1010 *
1111 *
1212 * IDENTIFICATION
13- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.132 2000/01/07 09:28:03 ishii Exp $
13+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.133 2000/01/09 12:13:24 ishii Exp $
1414 *
1515 * NOTES
1616 *
9292#include "utils/trace.h"
9393#include "version.h"
9494
95- /*
96- * "postmaster.pid" is a file containing postmaster's pid, being
97- * created uder $PGDATA upon postmaster's starting up. When postmaster
98- * shuts down, it will be unlinked. The purpose of the file includes:
99- *
100- * (1) supplying neccessary information to stop/restart postmaster
101- * (2) preventing another postmaster process starting while it has
102- * already started
103- */
104- #define PIDFNAME "postmaster.pid"
105-
10695/*
10796 * "postmaster.opts" is a file containing options for postmaser.
10897 * pg_ctl will use it to restart postmaster.
@@ -250,11 +239,6 @@ static boolFatalError = false;
250239
251240static unsignedint random_seed = 0 ;
252241
253- /*
254- * Path to pid file. Exitpostmaster() remember it to unlink the file.
255- */
256- static char PidFile [MAXPGPATH ];
257-
258242extern char * optarg ;
259243extern int optind ,
260244opterr ;
@@ -282,9 +266,7 @@ static long PostmasterRandom(void);
282266static void RandomSalt (char * salt );
283267static void SignalChildren (SIGNAL_ARGS );
284268static int CountChildren (void );
285- static void UnlinkPidFile (void );
286- static void SetPidFname (char * datadir );
287- static int SetPidFile (pid_t pid ,char * progname ,int port ,char * datadir ,
269+ static int SetOptsFile (char * progname ,int port ,char * datadir ,
288270int assert ,int nbuf ,char * execfile ,
289271int debuglvl ,int netserver ,
290272#ifdef USE_SSL
@@ -657,8 +639,9 @@ PostmasterMain(int argc, char *argv[])
657639/*
658640 * create pid file. if the file has already existed, exits.
659641 */
660- if (SetPidFile (
661- getpid (),/* postmaster process id */
642+ SetPidFname (DataDir );
643+ if (SetPidFile (getpid ())== 0 ) {
644+ if (SetOptsFile (
662645progname ,/* postmaster executable file */
663646PostPortName ,/* port number */
664647DataDir ,/* PGDATA */
@@ -675,13 +658,22 @@ PostmasterMain(int argc, char *argv[])
675658silentflag ,/* -S: detach tty */
676659SendStop ,/* -s: send SIGSTOP */
677660original_extraoptions /* options for backend */
678- )
679- ) {
680- ExitPostmaster (1 );
681- return 0 ;/* not reached */
682- }
661+ )!= 0 ) {
662+ UnlinkPidFile ();
663+ ExitPostmaster (1 );
664+ return 0 ;/* not reached */
665+ }
666+ }
667+ else {
668+ ExitPostmaster (1 );
669+ return 0 ;/* not reached */
670+ }
671+
672+ /*
673+ * register clean up proc
674+ */
675+ on_proc_exit (UnlinkPidFile ,NULL );
683676}
684-
685677/*
686678 * Set up signal handlers for the postmaster process.
687679 */
@@ -715,17 +707,19 @@ pmdaemonize(char *extraoptions)
715707int i ;
716708pid_t pid ;
717709
710+ SetPidFname (DataDir );
711+
718712pid = fork ();
719713if (pid == -1 ) {
720714perror ("Failed to fork postmaster" );
721715ExitPostmaster (1 );
722716return ;/* not reached */
723717}else if (pid ) {/* parent */
724- /*
725- * create pid file. if the file has already existed, exits.
726- */
727- if (SetPidFile (
728- pid , /* postmaster process id */
718+ /*
719+ * create pid file. if the file has already existed, exits.
720+ */
721+ if (SetPidFile (pid ) == 0 ) {
722+ if ( SetOptsFile (
729723progname ,/* postmaster executable file */
730724PostPortName ,/* port number */
731725DataDir ,/* PGDATA */
@@ -742,17 +736,27 @@ pmdaemonize(char *extraoptions)
7427361 ,/* -S: detach tty */
743737SendStop ,/* -s: send SIGSTOP */
744738extraoptions /* options for backend */
745- )
746- ) {
747- /*
748- * Failed to create pid file. kill the child and
749- * exit now.
750- */
751- kill (pid ,SIGTERM );
752- ExitPostmaster (1 );
753- return ;/* not reached */
754- }
755- _exit (0 );
739+ )!= 0 ) {
740+ /*
741+ * Failed to create opts file. kill the child and
742+ * exit now.
743+ */
744+ UnlinkPidFile ();
745+ kill (pid ,SIGTERM );
746+ ExitPostmaster (1 );
747+ return ;/* not reached */
748+ }
749+ _exit (0 );
750+ }
751+ else {
752+ /*
753+ * Failed to create pid file. kill the child and
754+ * exit now.
755+ */
756+ kill (pid ,SIGTERM );
757+ ExitPostmaster (1 );
758+ return ;/* not reached */
759+ }
756760}
757761
758762/* GH: If there's no setsid(), we hopefully don't need silent mode.
@@ -779,7 +783,6 @@ pmdaemonize(char *extraoptions)
779783/*
780784 * register clean up proc
781785 */
782- SetPidFname (DataDir );
783786on_proc_exit (UnlinkPidFile ,NULL );
784787}
785788
@@ -2179,25 +2182,9 @@ SSDataBase(bool startup)
21792182}
21802183
21812184/*
2182- * Remove the pid file. This function is called from proc_exit.
2183- */
2184- static void UnlinkPidFile (void )
2185- {
2186- unlink (PidFile );
2187- }
2188-
2189- /*
2190- * Set path to the pid file
2191- */
2192- static void SetPidFname (char * datadir )
2193- {
2194- snprintf (PidFile ,sizeof (PidFile ),"%s/%s" ,datadir ,PIDFNAME );
2195- }
2196-
2197- /*
2198- * Create the pid file
2185+ * Create the opts file
21992186 */
2200- static int SetPidFile ( pid_t pid , char * progname ,int port ,char * datadir ,
2187+ static int SetOptsFile ( char * progname ,int port ,char * datadir ,
22012188int assert ,int nbuf ,char * execfile ,
22022189int debuglvl ,int netserver ,
22032190#ifdef USE_SSL
@@ -2208,89 +2195,16 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
22082195{
22092196int fd ;
22102197char optsfile [MAXPGPATH ];
2211- char pidstr [32 ];
2212- int len ;
2213- pid_t post_pid ;
22142198char opts [1024 ];
22152199char buf [1024 ];
22162200
2217- /*
2218- * Creating pid file
2219- */
2220- SetPidFname (datadir );
2221- fd = open (PidFile ,O_RDWR |O_CREAT |O_EXCL ,0600 );
2222- if (fd < 0 ) {
2223- /*
2224- * Couldn't create the pid file. Probably
2225- * it already exists. Read the file to see if the process
2226- * actually exists
2227- */
2228- fd = open (PidFile ,O_RDONLY ,0600 );
2229- if (fd < 0 ) {
2230- fprintf (stderr ,"Can't create/read pid file: %s\n" ,PidFile );
2231- fprintf (stderr ,"Please check the permission and try again.\n" );
2232- return (-1 );
2233- }
2234-
2235- if ((len = read (fd ,pidstr ,sizeof (pidstr )- 1 ))< 0 ) {
2236- fprintf (stderr ,"Can't create/read pid file: %s\n" ,PidFile );
2237- fprintf (stderr ,"Please check the permission and try again.\n" );
2238- close (fd );
2239- return (-1 );
2240- }
2241- close (fd );
2242-
2243- /*
2244- * Check to see if the process actually exists
2245- */
2246- pidstr [len ]= '\0' ;
2247- post_pid = (pid_t )atoi (pidstr );
2248-
2249- if (post_pid == 0 || (post_pid > 0 && kill (post_pid ,0 )< 0 )) {
2250- /*
2251- * No, the process did not exist. Unlink
2252- * the file and try to create it
2253- */
2254- if (unlink (PidFile )< 0 ) {
2255- fprintf (stderr ,"Can't remove pidfile: %s\n" ,PidFile );
2256- fprintf (stderr ,"The file seems accidently left, but I couldn't remove it.\n" );
2257- fprintf (stderr ,"Please remove the file by hand and try again.\n" );
2258- return (-1 );
2259- }
2260- fd = open (PidFile ,O_RDWR |O_CREAT |O_EXCL ,0600 );
2261- if (fd < 0 ) {
2262- fprintf (stderr ,"Can't create pidfile: %s\n" ,PidFile );
2263- fprintf (stderr ,"Please check the permission and try again.\n" );
2264- return (-1 );
2265- }
2266- }else {
2267- /*
2268- * Another postmaster is running
2269- */
2270- fprintf (stderr ,"Can't create pidfile: %s\n" ,PidFile );
2271- fprintf (stderr ,"Is another postmaster (pid: %s) running?\n" ,pidstr );
2272- return (-1 );
2273- }
2274- }
2275-
2276- sprintf (pidstr ,"%d" ,pid );
2277- if (write (fd ,pidstr ,strlen (pidstr ))!= strlen (pidstr )) {
2278- fprintf (stderr ,"Write to pid file failed\n" );
2279- fprintf (stderr ,"Please check the permission and try again.\n" );
2280- close (fd );
2281- unlink (PidFile );
2282- return (-1 );
2283- }
2284- close (fd );
2285-
22862201/*
22872202 * Creating opts file
22882203 */
22892204snprintf (optsfile ,sizeof (optsfile ),"%s/%s" ,datadir ,OPTSFNAME );
22902205fd = open (optsfile ,O_RDWR |O_TRUNC |O_CREAT ,0600 );
22912206if (fd < 0 ) {
22922207fprintf (stderr ,"Can't create optsfile:%s" ,optsfile );
2293- unlink (PidFile );
22942208return (-1 );
22952209}
22962210snprintf (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,
23402254
23412255if (write (fd ,opts ,strlen (opts ))!= strlen (opts )) {
23422256perror ("Writing to opts file failed" );
2343- unlink (PidFile );
23442257close (fd );
23452258return (-1 );
23462259}
23472260close (fd );
23482261
2349- /*
2350- * register clean up proc
2351- */
2352- on_proc_exit (UnlinkPidFile ,NULL );
2353-
23542262return (0 );
23552263}