diff options
Diffstat (limited to 'src/backend/postmaster/pgstat.c')
-rw-r--r-- | src/backend/postmaster/pgstat.c | 204 |
1 files changed, 162 insertions, 42 deletions
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 38323f45ba2..90689d2f4e6 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * Copyright (c) 2001-2003, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.49 2003/12/20 17:31:21 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.50 2003/12/25 03:52:51 momjian Exp $ * ---------- */ #include "postgres.h" @@ -106,7 +106,13 @@ static char pgStat_fname[MAXPGPATH]; * Local function forward declarations * ---------- */ -static void pgstat_main(void); +#ifdef EXEC_BACKEND +static void pgstat_exec(STATS_PROCESS_TYPE procType); +static void pgstat_parseArgs(PGSTAT_FORK_ARGS); +#endif +NON_EXEC_STATIC void pgstat_main(PGSTAT_FORK_ARGS); +NON_EXEC_STATIC void pgstat_mainChild(PGSTAT_FORK_ARGS); +static void pgstat_mainInit(void); static void pgstat_recvbuffer(void); static void pgstat_die(SIGNAL_ARGS); @@ -328,6 +334,89 @@ startup_failed: } +#ifdef EXEC_BACKEND + +/* ---------- + * pgstat_exec() - + * + * Used to format up the arglist for, and exec, statistics + * (buffer and collector) processes + * + */ +static void +pgstat_exec(STATS_PROCESS_TYPE procType) +{ + char *av[11]; + int ac = 0, bufc = 0, i; + char pgstatBuf[8][MAXPGPATH]; + + av[ac++] = "postgres"; + switch (procType) + { + case STAT_PROC_BUFFER: + av[ac++] = "-statBuf"; + break; + + case STAT_PROC_COLLECTOR: + av[ac++] = "-statCol"; + break; + + default: + Assert(false); + } + + /* Sockets + pipes */ + bufc = 0; + snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatSock); + snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatPmPipe[0]); + snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatPmPipe[1]); + snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatPipe[0]); + snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatPipe[1]); + + /* + the pstat file names, and postgres pathname */ + /* FIXME: [fork/exec] whitespaces in directories? */ + snprintf(pgstatBuf[bufc++],MAXPGPATH,"%s",pgStat_tmpfname); + snprintf(pgstatBuf[bufc++],MAXPGPATH,"%s",pgStat_fname); + snprintf(pgstatBuf[bufc++],MAXPGPATH,"%s",pg_pathname); + + /* Add to the arg list */ + Assert(bufc <= lengthof(pgstatBuf)); + for (i = 0; i < bufc; i++) + av[ac++] = pgstatBuf[i]; + + av[ac++] = NULL; + Assert(ac <= lengthof(av)); + + if (execv(pg_pathname,av) == -1) + /* FIXME: [fork/exec] suggestions for what to do here? Can't call elog... */ + Assert(false); +} + + +/* ---------- + * pgstat_parseArgs() - + * + * Used to unformat the arglist for exec'ed statistics + * (buffer and collector) processes + * + */ +static void +pgstat_parseArgs(PGSTAT_FORK_ARGS) +{ + Assert(argc == 8); + argc = 0; + pgStatSock = atoi(argv[argc++]); + pgStatPmPipe[0] = atoi(argv[argc++]); + pgStatPmPipe[1] = atoi(argv[argc++]); + pgStatPipe[0] = atoi(argv[argc++]); + pgStatPipe[1] = atoi(argv[argc++]); + strncpy(pgStat_tmpfname,argv[argc++],MAXPGPATH); + strncpy(pgStat_fname, argv[argc++],MAXPGPATH); + strncpy(pg_pathname, argv[argc++],MAXPGPATH); +} + +#endif + /* ---------- * pgstat_start() - * @@ -416,22 +505,17 @@ pgstat_start(void) beos_backend_startup(); #endif - IsUnderPostmaster = true; /* we are a postmaster subprocess now */ - - MyProcPid = getpid(); /* reset MyProcPid */ - - /* Lose the postmaster's on-exit routines */ - on_exit_reset(); - /* Close the postmaster's sockets, except for pgstat link */ ClosePostmasterPorts(false); /* Drop our connection to postmaster's shared memory, as well */ PGSharedMemoryDetach(); +#ifdef EXEC_BACKEND + pgstat_exec(STAT_PROC_BUFFER); +#else pgstat_main(); - - exit(0); +#endif } @@ -1228,35 +1312,15 @@ pgstat_send(void *msg, int len) *------------------------------------------------------------ */ - -/* ---------- - * pgstat_main() - - * - * Start up the statistics collector itself. This is the body of the - * postmaster child process. - * ---------- - */ static void -pgstat_main(void) +pgstat_mainInit(void) { - PgStat_Msg msg; - fd_set rfds; - int readPipe; - int pmPipe = pgStatPmPipe[0]; - int maxfd; - int nready; - int len = 0; - struct timeval timeout; - struct timeval next_statwrite; - bool need_statwrite; - HASHCTL hash_ctl; + IsUnderPostmaster = true; /* we are a postmaster subprocess now */ - /* - * Close the writing end of the postmaster pipe, so we'll see it - * closing when the postmaster terminates and can terminate as well. - */ - closesocket(pgStatPmPipe[1]); - pgStatPmPipe[1] = -1; + MyProcPid = getpid(); /* reset MyProcPid */ + + /* Lose the postmaster's on-exit routines */ + on_exit_reset(); /* * Ignore all signals usually bound to some action in the postmaster, @@ -1275,6 +1339,31 @@ pgstat_main(void) pqsignal(SIGTTOU, SIG_DFL); pqsignal(SIGCONT, SIG_DFL); pqsignal(SIGWINCH, SIG_DFL); +} + + +/* ---------- + * pgstat_main() - + * + * Start up the statistics collector itself. This is the body of the + * postmaster child process. + * ---------- + */ +NON_EXEC_STATIC void +pgstat_main(PGSTAT_FORK_ARGS) +{ + pgstat_mainInit(); /* Note: for *both* EXEC_BACKEND and regular cases */ + +#ifdef EXEC_BACKEND + pgstat_parseArgs(argc,argv); +#endif + + /* + * Close the writing end of the postmaster pipe, so we'll see it + * closing when the postmaster terminates and can terminate as well. + */ + closesocket(pgStatPmPipe[1]); + pgStatPmPipe[1] = -1; /* * Start a buffering process to read from the socket, so we have a @@ -1305,9 +1394,12 @@ pgstat_main(void) case 0: /* child becomes collector process */ - closesocket(pgStatPipe[1]); - closesocket(pgStatSock); - break; +#ifdef EXEC_BACKEND + pgstat_exec(STAT_PROC_COLLECTOR); +#else + pgstat_mainChild(); +#endif + exit(0); default: /* parent becomes buffer process */ @@ -1315,6 +1407,36 @@ pgstat_main(void) pgstat_recvbuffer(); exit(0); } +} + + +NON_EXEC_STATIC void +pgstat_mainChild(PGSTAT_FORK_ARGS) +{ + PgStat_Msg msg; + fd_set rfds; + int readPipe; + int pmPipe; + int maxfd; + int nready; + int len = 0; + struct timeval timeout; + struct timeval next_statwrite; + bool need_statwrite; + HASHCTL hash_ctl; + +#ifdef EXEC_BACKEND + MemoryContextInit(); /* before any elog'ing can occur */ + + pgstat_mainInit(); + pgstat_parseArgs(argc,argv); +#else + MyProcPid = getpid(); /* reset MyProcPid */ +#endif + + closesocket(pgStatPipe[1]); + closesocket(pgStatSock); + pmPipe = pgStatPmPipe[0]; /* * In the child we can have default SIGCHLD handling (in case we want @@ -1322,8 +1444,6 @@ pgstat_main(void) */ pqsignal(SIGCHLD, SIG_DFL); - MyProcPid = getpid(); /* reset MyProcPid */ - /* * Identify myself via ps */ |