Refactor fork()-related code. We need to do various housekeeping tasks
before we can invoke fork() -- flush stdio buffers, save and restore the profiling timer on Linux with LINUX_PROFILE, and handle BeOS stuff. This patch moves that code into a single function, fork_process(), instead of duplicating it at the various callsites of fork(). This patch doesn't address the EXEC_BACKEND case; there is room for further cleanup there.
This commit is contained in:
parent
e829f82223
commit
164adc4d39
@ -265,7 +265,7 @@ beos_startup(int argc, char **argv)
|
||||
|
||||
|
||||
|
||||
/* The behavior of fork is borken on beos regarding shared memory. In fact
|
||||
/* The behavior of fork is broken on beos regarding shared memory. In fact
|
||||
all shared memory areas are clones in copy on write mode in the new process.
|
||||
|
||||
We need to do a remapping of these areas. Just afer the fork we performe the
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Makefile for src/backend/postmaster
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $PostgreSQL: pgsql/src/backend/postmaster/Makefile,v 1.19 2004/08/05 23:32:10 tgl Exp $
|
||||
# $PostgreSQL: pgsql/src/backend/postmaster/Makefile,v 1.20 2005/03/10 07:14:03 neilc Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -12,7 +12,7 @@ subdir = src/backend/postmaster
|
||||
top_builddir = ../../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
|
||||
OBJS = postmaster.o bgwriter.o pgstat.o pgarch.o syslogger.o
|
||||
OBJS = bgwriter.o fork_process.o pgarch.o pgstat.o postmaster.o syslogger.o
|
||||
|
||||
all: SUBSYS.o
|
||||
|
||||
|
80
src/backend/postmaster/fork_process.c
Normal file
80
src/backend/postmaster/fork_process.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* fork_process.c
|
||||
* A simple wrapper on top of fork(). This does not handle the
|
||||
* EXEC_BACKEND case; it might be extended to do so, but it would be
|
||||
* considerably more complex.
|
||||
*
|
||||
* Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/fork_process.c,v 1.1 2005/03/10 07:14:03 neilc Exp $
|
||||
*/
|
||||
#include "postgres.h"
|
||||
#include "postmaster/fork_process.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* Wrapper for fork(). Return values are the same as those for fork():
|
||||
* -1 if the fork failed, 0 in the child process, and the PID of the
|
||||
* child in the parent process.
|
||||
*/
|
||||
pid_t
|
||||
fork_process(void)
|
||||
{
|
||||
pid_t result;
|
||||
#ifdef LINUX_PROFILE
|
||||
struct itimerval prof_itimer;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flush stdio channels just before fork, to avoid double-output
|
||||
* problems. Ideally we'd use fflush(NULL) here, but there are still a
|
||||
* few non-ANSI stdio libraries out there (like SunOS 4.1.x) that
|
||||
* coredump if we do. Presently stdout and stderr are the only stdio
|
||||
* output channels used by the postmaster, so fflush'ing them should
|
||||
* be sufficient.
|
||||
*/
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
#ifdef LINUX_PROFILE
|
||||
/*
|
||||
* Linux's fork() resets the profiling timer in the child process. If
|
||||
* we want to profile child processes then we need to save and restore
|
||||
* the timer setting. This is a waste of time if not profiling,
|
||||
* however, so only do it if commanded by specific -DLINUX_PROFILE
|
||||
* switch.
|
||||
*/
|
||||
getitimer(ITIMER_PROF, &prof_itimer);
|
||||
#endif
|
||||
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions before backend startup */
|
||||
beos_before_backend_startup();
|
||||
#endif
|
||||
|
||||
result = fork();
|
||||
if (result == (pid_t) -1)
|
||||
{
|
||||
/* fork failed */
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos backend startup actions */
|
||||
beos_backend_startup_failed();
|
||||
#endif
|
||||
}
|
||||
else if (result == 0)
|
||||
{
|
||||
/* fork succeeded, in child */
|
||||
#ifdef LINUX_PROFILE
|
||||
setitimer(ITIMER_PROF, &prof_itimer, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos backend startup actions */
|
||||
beos_backend_startup();
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.14 2004/12/31 22:00:40 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.15 2005/03/10 07:14:03 neilc Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -34,6 +34,7 @@
|
||||
#include "access/xlog_internal.h"
|
||||
#include "libpq/pqsignal.h"
|
||||
#include "miscadmin.h"
|
||||
#include "postmaster/fork_process.h"
|
||||
#include "postmaster/pgarch.h"
|
||||
#include "postmaster/postmaster.h"
|
||||
#include "storage/fd.h"
|
||||
@ -141,25 +142,13 @@ pgarch_start(void)
|
||||
return 0;
|
||||
last_pgarch_start_time = curtime;
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions before backend startup */
|
||||
beos_before_backend_startup();
|
||||
#endif
|
||||
|
||||
#ifdef EXEC_BACKEND
|
||||
switch ((pgArchPid = pgarch_forkexec()))
|
||||
#else
|
||||
switch ((pgArchPid = fork()))
|
||||
switch ((pgArchPid = fork_process()))
|
||||
#endif
|
||||
{
|
||||
case -1:
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions */
|
||||
beos_backend_startup_failed();
|
||||
#endif
|
||||
ereport(LOG,
|
||||
(errmsg("could not fork archiver: %m")));
|
||||
return 0;
|
||||
@ -167,10 +156,6 @@ pgarch_start(void)
|
||||
#ifndef EXEC_BACKEND
|
||||
case 0:
|
||||
/* in postmaster child ... */
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions after backend startup */
|
||||
beos_backend_startup();
|
||||
#endif
|
||||
/* Close the postmaster's sockets */
|
||||
ClosePostmasterPorts(false);
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.445 2005/02/22 04:36:36 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.446 2005/03/10 07:14:03 neilc Exp $
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
@ -92,6 +92,8 @@
|
||||
#include <DNSServiceDiscovery/DNSServiceDiscovery.h>
|
||||
#endif
|
||||
|
||||
#include "access/xlog.h"
|
||||
#include "bootstrap/bootstrap.h"
|
||||
#include "catalog/pg_control.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "commands/async.h"
|
||||
@ -103,23 +105,22 @@
|
||||
#include "libpq/pqsignal.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/nodes.h"
|
||||
#include "postmaster/postmaster.h"
|
||||
#include "pgstat.h"
|
||||
#include "postmaster/fork_process.h"
|
||||
#include "postmaster/pgarch.h"
|
||||
#include "postmaster/postmaster.h"
|
||||
#include "postmaster/syslogger.h"
|
||||
#include "storage/bufmgr.h"
|
||||
#include "storage/fd.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/pg_shmem.h"
|
||||
#include "storage/pmsignal.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/bufmgr.h"
|
||||
#include "access/xlog.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/ps_status.h"
|
||||
#include "bootstrap/bootstrap.h"
|
||||
#include "pgstat.h"
|
||||
|
||||
#ifdef EXEC_BACKEND
|
||||
#include "storage/spin.h"
|
||||
@ -1008,16 +1009,7 @@ pmdaemonize(void)
|
||||
int i;
|
||||
pid_t pid;
|
||||
|
||||
#ifdef LINUX_PROFILE
|
||||
struct itimerval prof_itimer;
|
||||
#endif
|
||||
|
||||
#ifdef LINUX_PROFILE
|
||||
/* see comments in BackendStartup */
|
||||
getitimer(ITIMER_PROF, &prof_itimer);
|
||||
#endif
|
||||
|
||||
pid = fork();
|
||||
pid = fork_process();
|
||||
if (pid == (pid_t) -1)
|
||||
{
|
||||
write_stderr("%s: could not fork background process: %s\n",
|
||||
@ -1030,10 +1022,6 @@ pmdaemonize(void)
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
#ifdef LINUX_PROFILE
|
||||
setitimer(ITIMER_PROF, &prof_itimer, NULL);
|
||||
#endif
|
||||
|
||||
MyProcPid = PostmasterPid = getpid(); /* reset PID vars to child */
|
||||
|
||||
/* GH: If there's no setsid(), we hopefully don't need silent mode.
|
||||
@ -2382,10 +2370,6 @@ BackendStartup(Port *port)
|
||||
Backend *bn; /* for backend cleanup */
|
||||
pid_t pid;
|
||||
|
||||
#ifdef LINUX_PROFILE
|
||||
struct itimerval prof_itimer;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compute the cancel key that will be assigned to this backend. The
|
||||
* backend will have its own copy in the forked-off process' value of
|
||||
@ -2409,54 +2393,13 @@ BackendStartup(Port *port)
|
||||
/* Pass down canAcceptConnections state (kluge for EXEC_BACKEND case) */
|
||||
port->canAcceptConnections = canAcceptConnections();
|
||||
|
||||
/*
|
||||
* Flush stdio channels just before fork, to avoid double-output
|
||||
* problems. Ideally we'd use fflush(NULL) here, but there are still a
|
||||
* few non-ANSI stdio libraries out there (like SunOS 4.1.x) that
|
||||
* coredump if we do. Presently stdout and stderr are the only stdio
|
||||
* output channels used by the postmaster, so fflush'ing them should
|
||||
* be sufficient.
|
||||
*/
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
#ifdef EXEC_BACKEND
|
||||
|
||||
pid = backend_forkexec(port);
|
||||
|
||||
#else /* !EXEC_BACKEND */
|
||||
|
||||
#ifdef LINUX_PROFILE
|
||||
|
||||
/*
|
||||
* Linux's fork() resets the profiling timer in the child process. If
|
||||
* we want to profile child processes then we need to save and restore
|
||||
* the timer setting. This is a waste of time if not profiling,
|
||||
* however, so only do it if commanded by specific -DLINUX_PROFILE
|
||||
* switch.
|
||||
*/
|
||||
getitimer(ITIMER_PROF, &prof_itimer);
|
||||
#endif
|
||||
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions before backend startup */
|
||||
beos_before_backend_startup();
|
||||
#endif
|
||||
|
||||
pid = fork();
|
||||
|
||||
pid = fork_process();
|
||||
if (pid == 0) /* child */
|
||||
{
|
||||
#ifdef LINUX_PROFILE
|
||||
setitimer(ITIMER_PROF, &prof_itimer, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos backend startup actions */
|
||||
beos_backend_startup();
|
||||
#endif
|
||||
free(bn);
|
||||
|
||||
proc_exit(BackendRun(port));
|
||||
}
|
||||
#endif /* EXEC_BACKEND */
|
||||
@ -2466,10 +2409,6 @@ BackendStartup(Port *port)
|
||||
/* in parent, fork failed */
|
||||
int save_errno = errno;
|
||||
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos backend startup actions */
|
||||
beos_backend_startup_failed();
|
||||
#endif
|
||||
free(bn);
|
||||
errno = save_errno;
|
||||
ereport(LOG,
|
||||
@ -2945,7 +2884,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
|
||||
argv[2] = tmpfilename;
|
||||
|
||||
/* Fire off execv in child */
|
||||
if ((pid = fork()) == 0)
|
||||
if ((pid = fork_process()) == 0)
|
||||
{
|
||||
if (execv(postgres_exec_path, argv) < 0)
|
||||
{
|
||||
@ -3465,10 +3404,6 @@ StartChildProcess(int xlop)
|
||||
int ac = 0;
|
||||
char xlbuf[32];
|
||||
|
||||
#ifdef LINUX_PROFILE
|
||||
struct itimerval prof_itimer;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up command-line arguments for subprocess
|
||||
*/
|
||||
@ -3488,41 +3423,13 @@ StartChildProcess(int xlop)
|
||||
av[ac] = NULL;
|
||||
Assert(ac < lengthof(av));
|
||||
|
||||
/*
|
||||
* Flush stdio channels (see comments in BackendStartup)
|
||||
*/
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
#ifdef EXEC_BACKEND
|
||||
|
||||
pid = postmaster_forkexec(ac, av);
|
||||
|
||||
#else /* !EXEC_BACKEND */
|
||||
|
||||
#ifdef LINUX_PROFILE
|
||||
/* see comments in BackendStartup */
|
||||
getitimer(ITIMER_PROF, &prof_itimer);
|
||||
#endif
|
||||
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions before backend startup */
|
||||
beos_before_backend_startup();
|
||||
#endif
|
||||
|
||||
pid = fork();
|
||||
pid = fork_process();
|
||||
|
||||
if (pid == 0) /* child */
|
||||
{
|
||||
#ifdef LINUX_PROFILE
|
||||
setitimer(ITIMER_PROF, &prof_itimer, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions after backend startup */
|
||||
beos_backend_startup();
|
||||
#endif
|
||||
|
||||
IsUnderPostmaster = true; /* we are a postmaster subprocess
|
||||
* now */
|
||||
|
||||
@ -3546,11 +3453,6 @@ StartChildProcess(int xlop)
|
||||
{
|
||||
/* in parent, fork failed */
|
||||
int save_errno = errno;
|
||||
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions before backend startup */
|
||||
beos_backend_startup_failed();
|
||||
#endif
|
||||
errno = save_errno;
|
||||
switch (xlop)
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.12 2005/01/01 20:44:16 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/syslogger.c,v 1.13 2005/03/10 07:14:03 neilc Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -33,6 +33,7 @@
|
||||
|
||||
#include "libpq/pqsignal.h"
|
||||
#include "miscadmin.h"
|
||||
#include "postmaster/fork_process.h"
|
||||
#include "postmaster/postmaster.h"
|
||||
#include "postmaster/syslogger.h"
|
||||
#include "pgtime.h"
|
||||
@ -451,28 +452,13 @@ SysLogger_Start(void)
|
||||
|
||||
pfree(filename);
|
||||
|
||||
/*
|
||||
* Now we can fork off the syslogger subprocess.
|
||||
*/
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions before backend startup */
|
||||
beos_before_backend_startup();
|
||||
#endif
|
||||
|
||||
#ifdef EXEC_BACKEND
|
||||
switch ((sysloggerPid = syslogger_forkexec()))
|
||||
#else
|
||||
switch ((sysloggerPid = fork()))
|
||||
switch ((sysloggerPid = fork_process()))
|
||||
#endif
|
||||
{
|
||||
case -1:
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions */
|
||||
beos_backend_startup_failed();
|
||||
#endif
|
||||
ereport(LOG,
|
||||
(errmsg("could not fork system logger: %m")));
|
||||
return 0;
|
||||
@ -480,10 +466,6 @@ SysLogger_Start(void)
|
||||
#ifndef EXEC_BACKEND
|
||||
case 0:
|
||||
/* in postmaster child ... */
|
||||
#ifdef __BEOS__
|
||||
/* Specific beos actions after backend startup */
|
||||
beos_backend_startup();
|
||||
#endif
|
||||
/* Close the postmaster's sockets */
|
||||
ClosePostmasterPorts(true);
|
||||
|
||||
|
8
src/include/postmaster/fork_process.h
Normal file
8
src/include/postmaster/fork_process.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef FORK_PROCESS_H
|
||||
#define FORK_PROCESS_H
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
extern pid_t fork_process(void);
|
||||
|
||||
#endif /* ! FORK_PROCESS_H */
|
Loading…
x
Reference in New Issue
Block a user