Skip to content

Commit d9f61cf

Browse files
committed
Unlink the pid file if it's bogus (no associated process exists)
1 parent e958a30 commit d9f61cf

File tree

1 file changed

+113
-22
lines changed

1 file changed

+113
-22
lines changed

src/backend/postmaster/postmaster.c

Lines changed: 113 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.128 1999/12/03 06:26:34 ishii Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.129 1999/12/04 08:23:43 ishii Exp $
1414
*
1515
* NOTES
1616
*
@@ -257,7 +257,7 @@ extern int optind,
257257
/*
258258
* postmaster.c - function prototypes
259259
*/
260-
static void pmdaemonize(void);
260+
static void pmdaemonize(char *extraoptions);
261261
static Port *ConnCreate(int serverFd);
262262
static void ConnFree(Port *port);
263263
static void reset_shared(unsigned short port);
@@ -645,13 +645,13 @@ PostmasterMain(int argc, char *argv[])
645645
BackendList = DLNewList();
646646
PortList = DLNewList();
647647

648-
if (silentflag)
649-
pmdaemonize();
650-
651-
/*
652-
* create pid file. if the file has already existed, exits.
653-
*/
654-
if (SetPidFile(
648+
if (silentflag) {
649+
pmdaemonize(original_extraoptions);
650+
} else {
651+
/*
652+
* create pid file. if the file has already existed, exits.
653+
*/
654+
if (SetPidFile(
655655
getpid(), /* postmaster process id */
656656
progname, /* postmaster executable file */
657657
PostPortName, /* port number */
@@ -670,9 +670,10 @@ PostmasterMain(int argc, char *argv[])
670670
SendStop, /* -s: send SIGSTOP */
671671
original_extraoptions /* options for backend */
672672
)
673-
) {
674-
ExitPostmaster(1);
675-
return 0;
673+
) {
674+
ExitPostmaster(1);
675+
return 0; /* not reached */
676+
}
676677
}
677678

678679
/*
@@ -703,12 +704,50 @@ PostmasterMain(int argc, char *argv[])
703704
}
704705

705706
static void
706-
pmdaemonize(void)
707+
pmdaemonize(char *extraoptions)
707708
{
708709
int i;
710+
pid_t pid;
709711

710-
if (fork())
712+
pid = fork();
713+
if (pid == -1) {
714+
perror("Failed to fork postmaster");
715+
ExitPostmaster(1);
716+
return; /* not reached */
717+
} else if (pid) { /* parent */
718+
/*
719+
* create pid file. if the file has already existed, exits.
720+
*/
721+
if (SetPidFile(
722+
pid, /* postmaster process id */
723+
progname, /* postmaster executable file */
724+
PostPortName, /* port number */
725+
DataDir, /* PGDATA */
726+
assert_enabled, /* whether -A is specified or not */
727+
NBuffers, /* -B: number of shared buffers */
728+
Execfile, /* -b: postgres executable file */
729+
DebugLvl, /* -d: debug level */
730+
NetServer, /* -i: accept connection from INET */
731+
#ifdef USE_SSL
732+
SecureNetServer, /* -l: use SSL */
733+
#endif
734+
MaxBackends, /* -N: max number of backends */
735+
Reinit, /* -n: reinit shared mem after failure */
736+
1, /* -S: detach tty */
737+
SendStop, /* -s: send SIGSTOP */
738+
extraoptions /* options for backend */
739+
)
740+
) {
741+
/*
742+
* Failed to create pid file. kill the child and
743+
* exit now.
744+
*/
745+
kill(pid, SIGTERM);
746+
ExitPostmaster(1);
747+
return; /* not reached */
748+
}
711749
_exit(0);
750+
}
712751
/* GH: If there's no setsid(), we hopefully don't need silent mode.
713752
* Until there's a better solution.
714753
*/
@@ -2145,22 +2184,74 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
21452184
int fd;
21462185
char optsfile[MAXPGPATH];
21472186
char pidstr[32];
2187+
int len;
2188+
pid_t post_pid;
21482189
char opts[1024];
21492190
char buf[1024];
21502191

21512192
/*
21522193
* Creating pid file
21532194
*/
2154-
sprintf(PidFile,"%s/%s", datadir, PIDFNAME);
2195+
snprintf(PidFile, sizeof(PidFile), "%s/%s", datadir, PIDFNAME);
21552196
fd = open(PidFile, O_RDWR | O_CREAT | O_EXCL, 0600);
21562197
if (fd < 0) {
2157-
fprintf(stderr, "Can't create pidfile: %s\n", PidFile);
2158-
fprintf(stderr, "Is another postmaser running?\n");
2159-
return(-1);
2198+
/*
2199+
* Couldn't create the pid file. Probably
2200+
* it already exists. Read the file to see if the process
2201+
* actually exists
2202+
*/
2203+
fd = open(PidFile, O_RDONLY, 0600);
2204+
if (fd < 0) {
2205+
fprintf(stderr, "Can't create/read pid file: %s\n", PidFile);
2206+
fprintf(stderr, "Please check the permission and try again.\n");
2207+
return(-1);
2208+
}
2209+
2210+
if ((len = read(fd, pidstr, sizeof(pidstr)-1)) < 0) {
2211+
fprintf(stderr, "Can't create/read pid file: %s\n", PidFile);
2212+
fprintf(stderr, "Please check the permission and try again.\n");
2213+
close(fd);
2214+
return(-1);
2215+
}
2216+
close(fd);
2217+
2218+
/*
2219+
* Check to see if the process actually exists
2220+
*/
2221+
pidstr[len] = '\0';
2222+
post_pid = (pid_t)atoi(pidstr);
2223+
2224+
if (post_pid == 0 || (post_pid > 0 && kill(post_pid, 0) < 0)) {
2225+
/*
2226+
* No, the process did not exist. Unlink
2227+
* the file and try to create it
2228+
*/
2229+
if (unlink(PidFile) < 0) {
2230+
fprintf(stderr, "Can't remove pidfile: %s\n", PidFile);
2231+
fprintf(stderr, "The file seems accidently left, but I couldn't remove it.\n");
2232+
fprintf(stderr, "Please remove the file by hand and try again.\n");
2233+
return(-1);
2234+
}
2235+
fd = open(PidFile, O_RDWR | O_CREAT | O_EXCL, 0600);
2236+
if (fd < 0) {
2237+
fprintf(stderr, "Can't create pidfile: %s\n", PidFile);
2238+
fprintf(stderr, "Please check the permission and try again.\n");
2239+
return(-1);
2240+
}
2241+
} else {
2242+
/*
2243+
* Another postmaster is running
2244+
*/
2245+
fprintf(stderr, "Can't create pidfile: %s\n", PidFile);
2246+
fprintf(stderr, "Is another postmaser (pid: %s) running?\n", pidstr);
2247+
return(-1);
2248+
}
21602249
}
2250+
21612251
sprintf(pidstr, "%d", pid);
21622252
if (write(fd, pidstr, strlen(pidstr)) != strlen(pidstr)) {
21632253
fprintf(stderr,"Write to pid file failed\n");
2254+
fprintf(stderr, "Please check the permission and try again.\n");
21642255
close(fd);
21652256
unlink(PidFile);
21662257
return(-1);
@@ -2170,20 +2261,20 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
21702261
/*
21712262
* Creating opts file
21722263
*/
2173-
sprintf(optsfile,"%s/%s", datadir, OPTSFNAME);
2264+
snprintf(optsfile, sizeof(optsfile), "%s/%s", datadir, OPTSFNAME);
21742265
fd = open(optsfile, O_RDWR | O_TRUNC | O_CREAT, 0600);
21752266
if (fd < 0) {
21762267
fprintf(stderr, "Can't create optsfile:%s", optsfile);
21772268
unlink(PidFile);
21782269
return(-1);
21792270
}
2180-
sprintf(opts, "%s\n-p %d\n-D %s\n",progname, port, datadir);
2271+
snprintf(opts, sizeof(opts), "%s\n-p %d\n-D %s\n",progname, port, datadir);
21812272
if (assert) {
21822273
sprintf(buf, "-A %d\n", assert);
21832274
strcat(opts, buf);
21842275
}
21852276

2186-
sprintf(buf, "-B %d\n-b %s\n",nbuf, execfile);
2277+
snprintf(buf, sizeof(buf), "-B %d\n-b %s\n",nbuf, execfile);
21872278
strcat(opts, buf);
21882279

21892280
if (debuglvl) {
@@ -2201,7 +2292,7 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
22012292
}
22022293
#endif
22032294

2204-
sprintf(buf, "-N %d\n", maxbackends);
2295+
snprintf(buf, sizeof(buf), "-N %d\n", maxbackends);
22052296
strcat(opts, buf);
22062297

22072298
if (!reinit) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy