I've written a small patch for following TODO item:
  «Add GUC variable to run a command on database
  panic or smart/fast/immediate shutdown.»

It adds two GUC variables as:
  enable_atexit_script_file
  atexit_script_file

postmaster will run related script file with passing shutdown type
(like "smart", "fast" or "immediate") as parameter to script file
on database shutdown. (Sorry, I'm not so good on PostgreSQL internals,
thus couldn't handle "panic" situation at the moment.)

I know, it's not the perfect one but I'd be so apprecited to hear
suggestions for fixing lost/wrong parts of it.


Regards.

-- 
"We are the middle children of history, raised by television to believe
that someday we'll be millionaires and movie stars and rock stars, but
we won't. And we're just learning this fact," Tyler said. "So don't
fuck with us."
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/postmaster/postmaster.c,v
retrieving revision 1.476
diff -u -r1.476 postmaster.c
--- src/backend/postmaster/postmaster.c 22 Nov 2005 18:17:18 -0000      1.476
+++ src/backend/postmaster/postmaster.c 10 Dec 2005 18:28:04 -0000
@@ -254,6 +254,7 @@
 static void ConnFree(Port *port);
 static void reset_shared(int port);
 static void SIGHUP_handler(SIGNAL_ARGS);
+static void RunAtexitScriptFile(const char *);
 static void pmdie(SIGNAL_ARGS);
 static void reaper(SIGNAL_ARGS);
 static void sigusr1_handler(SIGNAL_ARGS);
@@ -1856,6 +1858,21 @@
        errno = save_errno;
 }
 
+/*
+ * RunAtexitScriptFile -- run configured atexit script.
+ */
+static void
+RunAtexitScriptFile(const char *shuttype)
+{
+       if (enable_atexit_script_file && atexit_script_file)
+       {
+               int             l = strlen(atexit_script_file) + 
strlen(shuttype) + 2;
+               char    buf[l];
+
+               sprintf(buf, "%s %s", atexit_script_file, shuttype);
+               system(buf);
+       }
+}
 
 /*
  * pmdie -- signal handler for processing various postmaster signals.
@@ -1885,6 +1902,7 @@
                        Shutdown = SmartShutdown;
                        ereport(LOG,
                                        (errmsg("received smart shutdown 
request")));
+                       RunAtexitScriptFile("smart");
 
                        /*
                         * We won't wait out an autovacuum iteration ...
@@ -1931,6 +1949,7 @@
                        Shutdown = FastShutdown;
                        ereport(LOG,
                                        (errmsg("received fast shutdown 
request")));
+                       RunAtexitScriptFile("fast");
 
                        if (DLGetHead(BackendList) || AutoVacPID != 0)
                        {
@@ -1978,6 +1997,8 @@
                         */
                        ereport(LOG,
                                        (errmsg("received immediate shutdown 
request")));
+                       RunAtexitScriptFile("immediate");
+                       
                        if (StartupPID != 0)
                                kill(StartupPID, SIGQUIT);
                        if (BgWriterPID != 0)
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.301
diff -u -r1.301 guc.c
--- src/backend/utils/misc/guc.c        22 Nov 2005 18:17:26 -0000      1.301
+++ src/backend/utils/misc/guc.c        10 Dec 2005 18:28:24 -0000
@@ -145,6 +145,7 @@
 /*
  * GUC option variables that are exported from this module
  */
+bool           enable_atexit_script_file = false;
 #ifdef USE_ASSERT_CHECKING
 bool           assert_enabled = true;
 #endif
@@ -181,6 +182,7 @@
 char      *HbaFileName;
 char      *IdentFileName;
 char      *external_pid_file;
+char      *atexit_script_file;
 
 int                    tcp_keepalives_idle;
 int                    tcp_keepalives_interval;
@@ -391,6 +393,14 @@
 static struct config_bool ConfigureNamesBool[] =
 {
        {
+               {"enable_atexit_script_file", PGC_POSTMASTER, FILE_LOCATIONS,
+                       gettext_noop("Enables usage of atexit script file on 
postmaster shutdown."),
+                       NULL
+               },
+               &enable_atexit_script_file,
+               false, NULL, NULL
+       },
+       {
                {"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD,
                        gettext_noop("Enables the planner's use of 
sequential-scan plans."),
                        NULL
@@ -2119,6 +2129,16 @@
                NULL, assign_canonical_path, NULL
        },
 
+       {
+               {"atexit_script_file", PGC_POSTMASTER, FILE_LOCATIONS,
+                       gettext_noop("Executes specified atexit script file on 
database shutdown."),
+                       NULL,
+                       GUC_SUPERUSER_ONLY
+               },
+               &atexit_script_file,
+               NULL, assign_canonical_path, NULL
+       },
+
        /* End-of-list marker */
        {
                {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
@@ -2856,6 +2876,47 @@
 
        free(configdir);
 
+       /*
+        * Access permission check for atexit_script_file.
+        */
+       if (enable_atexit_script_file)
+       {
+               int xmask;
+               
+               if (!atexit_script_file)
+               {
+                       write_stderr("You must specify an atexit script file 
when you "
+                                                "enabled its usage.\n");
+                       return false;
+               }
+               else if (stat(atexit_script_file, &stat_buf) != 0)
+               {
+                       write_stderr("%s cannot access atexit script file to 
run on server "
+                                                "shutdown.\n\"%s\": %s\n",
+                                                progname, atexit_script_file, 
strerror(errno));
+                       return false;
+               }
+
+               /*
+                * FIXME: Below execution masks require editing
+                * (like S_IXROOT) for some platforms (like Netware).
+                */
+               if (stat_buf.st_uid == getuid())
+                       xmask = S_IXUSR;
+               else if (stat_buf.st_uid == getgid())
+                       xmask = S_IXGRP;
+               else
+                       xmask = S_IXOTH;
+
+               if ((stat_buf.st_mode&xmask) == 0 || S_ISDIR(stat_buf.st_mode))
+               {
+                       write_stderr("%s doesn't have execution permissions on 
script "
+                                                "file to run on server 
shutdown.\n\"%s\": %s\n",
+                                                progname, atexit_script_file, 
strerror(errno));
+                       return false;
+               }
+       }
+
        return true;
 }
 
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file: 
/projects/cvsroot/pgsql/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.171
diff -u -r1.171 postgresql.conf.sample
--- src/backend/utils/misc/postgresql.conf.sample       17 Nov 2005 22:14:54 
-0000      1.171
+++ src/backend/utils/misc/postgresql.conf.sample       10 Dec 2005 18:28:25 
-0000
@@ -39,6 +39,9 @@
 # If external_pid_file is not explicitly set, no extra pid file is written.
 #external_pid_file = '(none)'          # write an extra pid file
 
+# atexit script file to run on database shutdown.
+#enable_atexit_script_file = off
+#atexit_script_file = '(none)'
 
 #---------------------------------------------------------------------------
 # CONNECTIONS AND AUTHENTICATION
Index: src/include/utils/guc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/guc.h,v
retrieving revision 1.63
diff -u -r1.63 guc.h
--- src/include/utils/guc.h     15 Oct 2005 02:49:46 -0000      1.63
+++ src/include/utils/guc.h     10 Dec 2005 19:14:00 -0000
@@ -103,6 +103,7 @@
 #define GUC_QUALIFIER_SEPARATOR '.'
 
 /* GUC vars that are actually declared in guc.c, rather than elsewhere */
+extern bool enable_atexit_script_file;
 extern bool log_duration;
 extern bool Debug_print_plan;
 extern bool Debug_print_parse;
@@ -133,6 +134,7 @@
 extern char *HbaFileName;
 extern char *IdentFileName;
 extern char *external_pid_file;
+extern char *atexit_script_file;
 
 extern int     tcp_keepalives_idle;
 extern int     tcp_keepalives_interval;
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

               http://archives.postgresql.org

Reply via email to