mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-01 07:01:19 +02:00
Move SetPidFile() and firends to utils/init/miscinit.c so that
tcop/postgres.c can use them. Now we have an interlock between postmaster and postgres.
This commit is contained in:
parent
359652898b
commit
3f3421f905
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -92,17 +92,6 @@
|
|||||||
#include "utils/trace.h"
|
#include "utils/trace.h"
|
||||||
#include "version.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.
|
* "postmaster.opts" is a file containing options for postmaser.
|
||||||
* pg_ctl will use it to restart postmaster.
|
* pg_ctl will use it to restart postmaster.
|
||||||
@ -250,11 +239,6 @@ static bool FatalError = false;
|
|||||||
|
|
||||||
static unsigned int random_seed = 0;
|
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 char *optarg;
|
||||||
extern int optind,
|
extern int optind,
|
||||||
opterr;
|
opterr;
|
||||||
@ -282,9 +266,7 @@ static long PostmasterRandom(void);
|
|||||||
static void RandomSalt(char *salt);
|
static void RandomSalt(char *salt);
|
||||||
static void SignalChildren(SIGNAL_ARGS);
|
static void SignalChildren(SIGNAL_ARGS);
|
||||||
static int CountChildren(void);
|
static int CountChildren(void);
|
||||||
static void UnlinkPidFile(void);
|
static int SetOptsFile(char *progname, int port, char *datadir,
|
||||||
static void SetPidFname(char *datadir);
|
|
||||||
static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
|
|
||||||
int assert, int nbuf, char *execfile,
|
int assert, int nbuf, char *execfile,
|
||||||
int debuglvl, int netserver,
|
int debuglvl, int netserver,
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
@ -657,8 +639,9 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
/*
|
/*
|
||||||
* create pid file. if the file has already existed, exits.
|
* create pid file. if the file has already existed, exits.
|
||||||
*/
|
*/
|
||||||
if (SetPidFile(
|
SetPidFname(DataDir);
|
||||||
getpid(), /* postmaster process id */
|
if (SetPidFile(getpid()) == 0) {
|
||||||
|
if (SetOptsFile(
|
||||||
progname, /* postmaster executable file */
|
progname, /* postmaster executable file */
|
||||||
PostPortName, /* port number */
|
PostPortName, /* port number */
|
||||||
DataDir, /* PGDATA */
|
DataDir, /* PGDATA */
|
||||||
@ -675,13 +658,22 @@ PostmasterMain(int argc, char *argv[])
|
|||||||
silentflag, /* -S: detach tty */
|
silentflag, /* -S: detach tty */
|
||||||
SendStop, /* -s: send SIGSTOP */
|
SendStop, /* -s: send SIGSTOP */
|
||||||
original_extraoptions /* options for backend */
|
original_extraoptions /* options for backend */
|
||||||
)
|
) != 0) {
|
||||||
) {
|
UnlinkPidFile();
|
||||||
ExitPostmaster(1);
|
ExitPostmaster(1);
|
||||||
return 0; /* not reached */
|
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.
|
* Set up signal handlers for the postmaster process.
|
||||||
*/
|
*/
|
||||||
@ -715,6 +707,8 @@ pmdaemonize(char *extraoptions)
|
|||||||
int i;
|
int i;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
|
SetPidFname(DataDir);
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
perror("Failed to fork postmaster");
|
perror("Failed to fork postmaster");
|
||||||
@ -724,8 +718,8 @@ pmdaemonize(char *extraoptions)
|
|||||||
/*
|
/*
|
||||||
* create pid file. if the file has already existed, exits.
|
* create pid file. if the file has already existed, exits.
|
||||||
*/
|
*/
|
||||||
if (SetPidFile(
|
if (SetPidFile(pid) == 0) {
|
||||||
pid, /* postmaster process id */
|
if (SetOptsFile(
|
||||||
progname, /* postmaster executable file */
|
progname, /* postmaster executable file */
|
||||||
PostPortName, /* port number */
|
PostPortName, /* port number */
|
||||||
DataDir, /* PGDATA */
|
DataDir, /* PGDATA */
|
||||||
@ -742,8 +736,19 @@ pmdaemonize(char *extraoptions)
|
|||||||
1, /* -S: detach tty */
|
1, /* -S: detach tty */
|
||||||
SendStop, /* -s: send SIGSTOP */
|
SendStop, /* -s: send SIGSTOP */
|
||||||
extraoptions /* options for backend */
|
extraoptions /* options for backend */
|
||||||
)
|
) != 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
|
* Failed to create pid file. kill the child and
|
||||||
* exit now.
|
* exit now.
|
||||||
@ -752,7 +757,6 @@ pmdaemonize(char *extraoptions)
|
|||||||
ExitPostmaster(1);
|
ExitPostmaster(1);
|
||||||
return; /* not reached */
|
return; /* not reached */
|
||||||
}
|
}
|
||||||
_exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GH: If there's no setsid(), we hopefully don't need silent mode.
|
/* GH: If there's no setsid(), we hopefully don't need silent mode.
|
||||||
@ -779,7 +783,6 @@ pmdaemonize(char *extraoptions)
|
|||||||
/*
|
/*
|
||||||
* register clean up proc
|
* register clean up proc
|
||||||
*/
|
*/
|
||||||
SetPidFname(DataDir);
|
|
||||||
on_proc_exit(UnlinkPidFile, NULL);
|
on_proc_exit(UnlinkPidFile, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2179,25 +2182,9 @@ SSDataBase(bool startup)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove the pid file. This function is called from proc_exit.
|
* Create the opts file
|
||||||
*/
|
*/
|
||||||
static void UnlinkPidFile(void)
|
static int SetOptsFile(char *progname, int port, char *datadir,
|
||||||
{
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
|
|
||||||
int assert, int nbuf, char *execfile,
|
int assert, int nbuf, char *execfile,
|
||||||
int debuglvl, int netserver,
|
int debuglvl, int netserver,
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
@ -2208,81 +2195,9 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
char optsfile[MAXPGPATH];
|
char optsfile[MAXPGPATH];
|
||||||
char pidstr[32];
|
|
||||||
int len;
|
|
||||||
pid_t post_pid;
|
|
||||||
char opts[1024];
|
char opts[1024];
|
||||||
char buf[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
|
* 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);
|
fd = open(optsfile, O_RDWR | O_TRUNC | O_CREAT, 0600);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fprintf(stderr, "Can't create optsfile:%s", optsfile);
|
fprintf(stderr, "Can't create optsfile:%s", optsfile);
|
||||||
unlink(PidFile);
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
snprintf(opts, sizeof(opts), "%s\n-p %d\n-D %s\n",progname, port, datadir);
|
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)) {
|
if (write(fd, opts, strlen(opts)) != strlen(opts)) {
|
||||||
perror("Writing to opts file failed");
|
perror("Writing to opts file failed");
|
||||||
unlink(PidFile);
|
|
||||||
close(fd);
|
close(fd);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
/*
|
|
||||||
* register clean up proc
|
|
||||||
*/
|
|
||||||
on_proc_exit(UnlinkPidFile, NULL);
|
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user