aboutsummaryrefslogtreecommitdiff
path: root/src/backend/postmaster/pgstat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/postmaster/pgstat.c')
-rw-r--r--src/backend/postmaster/pgstat.c204
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
*/