Move SetPidFile() and firends to utils/init/miscinit.c so that
authorTatsuo Ishii
Sun, 9 Jan 2000 12:13:24 +0000 (12:13 +0000)
committerTatsuo Ishii
Sun, 9 Jan 2000 12:13:24 +0000 (12:13 +0000)
tcop/postgres.c can use them. Now we have an interlock between
postmaster and postgres.

src/backend/postmaster/postmaster.c

index 67db5dec11577b439e3334b4fa47c1cb18d7aacc..884563f4a02ceadfca685982687141d3472c1898 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.132 2000/01/07 09:28:03 ishii Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.133 2000/01/09 12:13:24 ishii Exp $
  *
  * NOTES
  *
 #include "utils/trace.h"
 #include "version.h"
 
-/* 
- * "postmaster.pid" is a file containing postmaster's pid, being
- * created uder $PGDATA upon postmaster's starting up. When postmaster
- * shuts down, it will be unlinked. The purpose of the file includes:
- *
- * (1) supplying neccessary information to stop/restart postmaster
- * (2) preventing another postmaster process starting while it has
- *     already started
-*/
-#define PIDFNAME   "postmaster.pid"
-
 /*
  * "postmaster.opts" is a file containing options for postmaser.
  * pg_ctl will use it to restart postmaster.
@@ -250,11 +239,6 @@ static bool        FatalError = false;
 
 static unsigned int random_seed = 0;
 
-/*
- * Path to pid file. Exitpostmaster() remember it to unlink the file.
- */
-static char PidFile[MAXPGPATH];
-
 extern char *optarg;
 extern int optind,
            opterr;
@@ -282,9 +266,7 @@ static long     PostmasterRandom(void);
 static void    RandomSalt(char *salt);
 static void    SignalChildren(SIGNAL_ARGS);
 static int     CountChildren(void);
-static void    UnlinkPidFile(void);
-static void    SetPidFname(char *datadir);
-static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
+static int SetOptsFile(char *progname, int port, char *datadir,
              int assert, int nbuf, char *execfile,
              int debuglvl, int netserver,
 #ifdef USE_SSL
@@ -657,8 +639,9 @@ PostmasterMain(int argc, char *argv[])
        /*
         * create pid file. if the file has already existed, exits.
         */
-       if (SetPidFile(
-              getpid(),    /* postmaster process id */
+     SetPidFname(DataDir);
+     if (SetPidFile(getpid()) == 0) {
+       if (SetOptsFile(
               progname,    /* postmaster executable file */
               PostPortName,    /* port number */
               DataDir,     /* PGDATA */
@@ -675,13 +658,22 @@ PostmasterMain(int argc, char *argv[])
               silentflag,  /* -S: detach tty */
               SendStop,    /* -s: send SIGSTOP */
               original_extraoptions    /* options for backend */
-              )
-         ) {
-           ExitPostmaster(1);
-           return 0;   /* not reached */
-       }
+              ) != 0) {
+           UnlinkPidFile();
+           ExitPostmaster(1);
+           return 0;   /* not reached */
+       }
+     }
+     else {
+       ExitPostmaster(1);
+       return 0;   /* not reached */
+     }
+       
+     /*
+      * register clean up proc
+      */
+     on_proc_exit(UnlinkPidFile, NULL);
    }
-
    /*
     * Set up signal handlers for the postmaster process.
     */
@@ -715,17 +707,19 @@ pmdaemonize(char *extraoptions)
    int         i;
    pid_t   pid;
 
+   SetPidFname(DataDir);
+
    pid = fork();
    if (pid == -1) {
        perror("Failed to fork postmaster");
        ExitPostmaster(1);
        return; /* not reached */
    } else if (pid) {   /* parent */
-       /*
-        * create pid file. if the file has already existed, exits.
-        */
-       if (SetPidFile(
-              pid,     /* postmaster process id */
+     /*
+      * create pid file. if the file has already existed, exits.
+      */
+     if (SetPidFile(pid) == 0) {
+       if (SetOptsFile(
               progname,    /* postmaster executable file */
               PostPortName,    /* port number */
               DataDir,     /* PGDATA */
@@ -742,17 +736,27 @@ pmdaemonize(char *extraoptions)
               1,       /* -S: detach tty */
               SendStop,    /* -s: send SIGSTOP */
               extraoptions /* options for backend */
-              )
-       ) {
-           /*
-            * Failed to create pid file. kill the child and
-            * exit now.
-            */
-           kill(pid, SIGTERM);
-           ExitPostmaster(1);
-           return; /* not reached */
-       }
-       _exit(0);
+              ) != 0) {
+         /*
+          * Failed to create opts file. kill the child and
+          * exit now.
+          */
+         UnlinkPidFile();
+         kill(pid, SIGTERM);
+         ExitPostmaster(1);
+         return;   /* not reached */
+       }
+       _exit(0);
+     }
+     else {
+         /*
+          * Failed to create pid file. kill the child and
+          * exit now.
+          */
+         kill(pid, SIGTERM);
+         ExitPostmaster(1);
+         return;   /* not reached */
+     }
    }
 
 /* GH: If there's no setsid(), we hopefully don't need silent mode.
@@ -779,7 +783,6 @@ pmdaemonize(char *extraoptions)
    /*
     * register clean up proc
     */
-   SetPidFname(DataDir);
    on_proc_exit(UnlinkPidFile, NULL);
 }
 
@@ -2179,25 +2182,9 @@ SSDataBase(bool startup)
 }
 
 /*
- * Remove the pid file. This function is called from proc_exit.
- */
-static void UnlinkPidFile(void)
-{
-   unlink(PidFile);
-}
-
-/*
- * Set path to the pid file
- */
-static void SetPidFname(char * datadir)
-{
-   snprintf(PidFile, sizeof(PidFile), "%s/%s", datadir, PIDFNAME);
-}
-
-/*
- * Create the pid file
+ * Create the opts file
  */
-static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
+static int SetOptsFile(char *progname, int port, char *datadir,
              int assert, int nbuf, char *execfile,
              int debuglvl, int netserver,
 #ifdef USE_SSL
@@ -2208,81 +2195,9 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
 {
    int fd;
    char optsfile[MAXPGPATH];
-   char pidstr[32];
-   int len;
-   pid_t post_pid;
    char opts[1024];
    char buf[1024];
 
-   /*
-    * Creating pid file
-    */
-   SetPidFname(datadir);
-   fd = open(PidFile, O_RDWR | O_CREAT | O_EXCL, 0600);
-   if (fd < 0) {
-       /*
-        * Couldn't create the pid file. Probably
-        * it already exists. Read the file to see if the process
-        * actually exists
-        */
-       fd = open(PidFile, O_RDONLY, 0600);
-       if (fd < 0) {
-           fprintf(stderr, "Can't create/read pid file: %s\n", PidFile);
-           fprintf(stderr, "Please check the permission and try again.\n");
-           return(-1);
-       }
-
-       if ((len = read(fd, pidstr, sizeof(pidstr)-1)) < 0) {
-           fprintf(stderr, "Can't create/read pid file: %s\n", PidFile);
-           fprintf(stderr, "Please check the permission and try again.\n");
-           close(fd);
-           return(-1);
-       }
-       close(fd);
-
-       /*
-        * Check to see if the process actually exists
-        */
-       pidstr[len] = '\0';
-       post_pid = (pid_t)atoi(pidstr);
-
-       if (post_pid == 0 || (post_pid > 0 && kill(post_pid, 0) < 0)) {
-           /*
-            * No, the process did not exist. Unlink
-            * the file and try to create it
-            */
-           if (unlink(PidFile) < 0) {
-               fprintf(stderr, "Can't remove pidfile: %s\n", PidFile);
-               fprintf(stderr, "The file seems accidently left, but I couldn't remove it.\n");
-               fprintf(stderr, "Please remove the file by hand and try again.\n");
-               return(-1);
-           }
-           fd = open(PidFile, O_RDWR | O_CREAT | O_EXCL, 0600);
-           if (fd < 0) {
-               fprintf(stderr, "Can't create pidfile: %s\n", PidFile);
-               fprintf(stderr, "Please check the permission and try again.\n");
-               return(-1);
-           }
-       } else {
-           /*
-            * Another postmaster is running
-            */
-           fprintf(stderr, "Can't create pidfile: %s\n", PidFile);
-           fprintf(stderr, "Is another postmaster (pid: %s) running?\n", pidstr);
-           return(-1);
-       }
-   }
-
-   sprintf(pidstr, "%d", pid);
-   if (write(fd, pidstr, strlen(pidstr)) != strlen(pidstr)) {
-       fprintf(stderr,"Write to pid file failed\n");
-       fprintf(stderr, "Please check the permission and try again.\n");
-       close(fd);
-       unlink(PidFile);
-       return(-1);
-   }
-   close(fd);
-
    /*
     * Creating opts file
     */
@@ -2290,7 +2205,6 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
    fd = open(optsfile, O_RDWR | O_TRUNC | O_CREAT, 0600);
    if (fd < 0) {
        fprintf(stderr, "Can't create optsfile:%s", optsfile);
-       unlink(PidFile);
        return(-1);
    }
    snprintf(opts, sizeof(opts), "%s\n-p %d\n-D %s\n",progname, port, datadir);
@@ -2340,16 +2254,10 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
 
    if (write(fd, opts, strlen(opts)) != strlen(opts)) {
        perror("Writing to opts file failed");
-       unlink(PidFile);
        close(fd);
        return(-1);
    }
    close(fd);
 
-   /*
-    * register clean up proc
-    */
-   on_proc_exit(UnlinkPidFile, NULL);
-
    return(0);
 }