Skip to content

Commit 10283ee

Browse files
committed
Move SetPidFile() and firends to utils/init/miscinit.c from
postmaster/postmaster.c so that tcop/postgres.c can use them. Now we have an interlock between postmaster and postgres.
1 parent 3f3421f commit 10283ee

File tree

1 file changed

+155
-1
lines changed

1 file changed

+155
-1
lines changed

src/backend/utils/init/miscinit.c

Lines changed: 155 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.37 1999/11/24 16:52:42 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.38 2000/01/09 12:15:57 ishii Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
1414
#include <sys/param.h>
1515
#include <sys/types.h>
16+
#include <signal.h>
1617
#include <sys/stat.h>
1718
#include <sys/file.h>
1819
#include <unistd.h>
@@ -462,3 +463,156 @@ SetUserId()
462463
ShadowRelationName);
463464
UserId = (Oid) ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
464465
}
466+
467+
/*-------------------------------------------------------------------------
468+
*
469+
* posmaster pid file stuffs. $DATADIR/postmaster.pid is created when:
470+
*
471+
* (1) postmaster starts. In this case pid > 0.
472+
* (2) postgres starts in standalone mode. In this case
473+
* pid < 0
474+
*
475+
* to gain an interlock.
476+
*
477+
* SetPidFname(datadir)
478+
* Remember the the pid file name. This is neccesary
479+
* UnlinkPidFile() is called from proc_exit().
480+
*
481+
* GetPidFname(datadir)
482+
* Get the pid file name. SetPidFname() should be called
483+
* before GetPidFname() gets called.
484+
*
485+
* UnlinkPidFile()
486+
* This is called from proc_exit() and unlink the pid file.
487+
*
488+
* SetPidFile(pid_t pid)
489+
* Create the pid file. On failure, it checks if the process
490+
* actually exists or not. SetPidFname() should be called
491+
* in prior to calling SetPidFile().
492+
*
493+
*-------------------------------------------------------------------------
494+
*/
495+
496+
/*
497+
* Path to pid file. proc_exit() remember it to unlink the file.
498+
*/
499+
static char PidFile[MAXPGPATH];
500+
501+
/*
502+
* Remove the pid file. This function is called from proc_exit.
503+
*/
504+
void UnlinkPidFile(void)
505+
{
506+
unlink(PidFile);
507+
}
508+
509+
/*
510+
* Set path to the pid file
511+
*/
512+
void SetPidFname(char * datadir)
513+
{
514+
snprintf(PidFile, sizeof(PidFile), "%s/%s", datadir, PIDFNAME);
515+
}
516+
517+
/*
518+
* Get path to the pid file
519+
*/
520+
char *GetPidFname(void)
521+
{
522+
return(PidFile);
523+
}
524+
525+
/*
526+
* Create the pid file
527+
*/
528+
int SetPidFile(pid_t pid)
529+
{
530+
int fd;
531+
char *pidfile;
532+
char pidstr[32];
533+
int len;
534+
pid_t post_pid;
535+
int is_postgres = 0;
536+
537+
/*
538+
* Creating pid file
539+
*/
540+
pidfile = GetPidFname();
541+
fd = open(pidfile, O_RDWR | O_CREAT | O_EXCL, 0600);
542+
if (fd < 0) {
543+
/*
544+
* Couldn't create the pid file. Probably
545+
* it already exists. Read the file to see if the process
546+
* actually exists
547+
*/
548+
fd = open(pidfile, O_RDONLY, 0600);
549+
if (fd < 0) {
550+
fprintf(stderr, "Can't open pid file: %s\n", pidfile);
551+
fprintf(stderr, "Please check the permission and try again.\n");
552+
return(-1);
553+
}
554+
if ((len = read(fd, pidstr, sizeof(pidstr)-1)) < 0) {
555+
fprintf(stderr, "Can't read pid file: %s\n", pidfile);
556+
fprintf(stderr, "Please check the permission and try again.\n");
557+
close(fd);
558+
return(-1);
559+
}
560+
close(fd);
561+
562+
/*
563+
* Check to see if the process actually exists
564+
*/
565+
pidstr[len] = '\0';
566+
post_pid = (pid_t)atoi(pidstr);
567+
568+
/* if pid < 0, the pid is for postgres, not postmatser */
569+
if (post_pid < 0) {
570+
is_postgres++;
571+
post_pid = -post_pid;
572+
}
573+
574+
if (post_pid == 0 || (post_pid > 0 && kill(post_pid, 0) < 0)) {
575+
/*
576+
* No, the process did not exist. Unlink
577+
* the file and try to create it
578+
*/
579+
if (unlink(pidfile) < 0) {
580+
fprintf(stderr, "Can't remove pid file: %s\n", pidfile);
581+
fprintf(stderr, "The file seems accidently left, but I couldn't remove it.\n");
582+
fprintf(stderr, "Please remove the file by hand and try again.\n");
583+
return(-1);
584+
}
585+
fd = open(pidfile, O_RDWR | O_CREAT | O_EXCL, 0600);
586+
if (fd < 0) {
587+
fprintf(stderr, "Can't create pid file: %s\n", pidfile);
588+
fprintf(stderr, "Please check the permission and try again.\n");
589+
return(-1);
590+
}
591+
} else {
592+
/*
593+
* Another postmaster is running
594+
*/
595+
fprintf(stderr, "Can't create pid file: %s\n", pidfile);
596+
if (is_postgres) {
597+
fprintf(stderr, "Is another postgres (pid: %d) running?\n", post_pid);
598+
}
599+
else
600+
{
601+
fprintf(stderr, "Is another postmaster (pid: %s) running?\n", pidstr);
602+
}
603+
return(-1);
604+
}
605+
}
606+
607+
sprintf(pidstr, "%d", pid);
608+
if (write(fd, pidstr, strlen(pidstr)) != strlen(pidstr)) {
609+
fprintf(stderr,"Write to pid file failed\n");
610+
fprintf(stderr, "Please check the permission and try again.\n");
611+
close(fd);
612+
unlink(pidfile);
613+
return(-1);
614+
}
615+
close(fd);
616+
617+
return(0);
618+
}

0 commit comments

Comments
 (0)