*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.245 2001/10/03 21:58:28 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.246 2001/10/19 00:44:08 tgl Exp $
*
* NOTES
*
#include <fcntl.h>
#include <time.h>
#include <sys/param.h>
-/* moved here to prevent double define */
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <netdb.h>
#include <limits.h>
#include "utils/exc.h"
#include "utils/guc.h"
#include "utils/memutils.h"
+#include "utils/ps_status.h"
#include "bootstrap/bootstrap.h"
#include "pgstat.h"
int AuthenticationTimeout = 60;
int CheckPointTimeout = 300;
+bool HostnameLookup; /* for ps display */
+bool ShowPortNumber;
+bool Log_connections = false;
+
/* Startup/shutdown state */
static pid_t StartupPID = 0,
ShutdownPID = 0,
struct timeval timeout_tv;
if (CheckPointPID == 0 && checkpointed &&
- Shutdown == NoShutdown && !FatalError)
+ Shutdown == NoShutdown && !FatalError && random_seed != 0)
{
time_t now = time(NULL);
* not return at all.
*
* (Note that elog(FATAL) stuff is sent to the client, so only use it
- * if that's what you want.)
+ * if that's what you want. Return STATUS_ERROR if you don't want to
+ * send anything to the client, which would typically be appropriate
+ * if we detect a communications failure.)
*/
static int
ProcessStartupPacket(Port *port, bool SSLdone)
int32 len;
void *buf;
- pq_getbytes((char *)&len, 4);
+ if (pq_getbytes((char *) &len, 4) == EOF)
+ {
+ elog(DEBUG, "incomplete startup packet");
+ return STATUS_ERROR;
+ }
+
len = ntohl(len);
len -= 4;
elog(FATAL, "invalid length of startup packet");
buf = palloc(len);
- pq_getbytes(buf, len);
+
+ if (pq_getbytes(buf, len) == EOF)
+ {
+ elog(DEBUG, "incomplete startup packet");
+ return STATUS_ERROR;
+ }
packet = buf;
static int
DoBackend(Port *port)
{
+ char *remote_host;
char *av[ARGV_SIZE * 2];
int ac = 0;
char debugbuf[ARGV_SIZE];
/*
* Receive the startup packet (which might turn out to be a cancel
- * request packet); then perform client authentication.
+ * request packet).
*/
status = ProcessStartupPacket(port, false);
- if (status == 127)
- return 0; /* cancel request processed */
+ if (status != STATUS_OK)
+ return 0; /* cancel request processed, or error */
- ClientAuthentication(MyProcPort); /* might not return, if failure */
+ /*
+ * Now that we have the user and database name, we can set the process
+ * title for ps. It's good to do this as early as possible in startup.
+ *
+ * But first, we need the remote host name.
+ */
+ if (port->raddr.sa.sa_family == AF_INET)
+ {
+ unsigned short remote_port;
+ char *host_addr;
+
+ remote_port = ntohs(port->raddr.in.sin_port);
+ host_addr = inet_ntoa(port->raddr.in.sin_addr);
+
+ remote_host = NULL;
+
+ if (HostnameLookup)
+ {
+ struct hostent *host_ent;
+
+ host_ent = gethostbyaddr((char *) &port->raddr.in.sin_addr,
+ sizeof(port->raddr.in.sin_addr),
+ AF_INET);
+
+ if (host_ent)
+ {
+ remote_host = palloc(strlen(host_addr) + strlen(host_ent->h_name) + 3);
+ sprintf(remote_host, "%s[%s]", host_ent->h_name, host_addr);
+ }
+ }
+
+ if (remote_host == NULL)
+ remote_host = pstrdup(host_addr);
+
+ if (ShowPortNumber)
+ {
+ char *str = palloc(strlen(remote_host) + 7);
+
+ sprintf(str, "%s:%hu", remote_host, remote_port);
+ pfree(remote_host);
+ remote_host = str;
+ }
+ }
+ else
+ {
+ /* not AF_INET */
+ remote_host = "[local]";
+ }
+
+ /*
+ * Set process parameters for ps
+ *
+ * WARNING: On some platforms the environment will be moved around to
+ * make room for the ps display string. So any references to
+ * optarg or getenv() from above will be invalid after this call.
+ * Better use strdup or something similar.
+ */
+ init_ps_display(real_argc, real_argv, port->user, port->database,
+ remote_host);
+ set_ps_display("authentication");
+
+ /*
+ * Now perform authentication exchange.
+ */
+ ClientAuthentication(port); /* might not return, if failure */
/*
* Done with authentication. Disable timeout, and prevent SIGTERM/SIGQUIT
elog(FATAL, "DoBackend: Unable to disable timer for auth timeout");
PG_SETMASK(&BlockSig);
+ if (Log_connections)
+ elog(DEBUG, "connection: host=%s user=%s database=%s",
+ remote_host, port->user, port->database);
+
/*
* Don't want backend to be able to see the postmaster random number
* generator state. We have to clobber the static random_seed *and*
/* Ignore request if checkpointing is currently disabled */
if (CheckPointPID == 0 && checkpointed &&
- Shutdown == NoShutdown && !FatalError)
+ Shutdown == NoShutdown && !FatalError && random_seed != 0)
{
CheckPointPID = CheckPointDataBase();
/* note: if fork fails, CheckPointPID stays 0; nothing happens */
if ((pid = fork()) == 0) /* child */
{
+ const char *statmsg;
char *av[ARGV_SIZE * 2];
int ac = 0;
char nbbuf[ARGV_SIZE];
/* Close the postmaster's sockets */
ClosePostmasterPorts(true);
+ /*
+ * Identify myself via ps
+ *
+ * WARNING: On some platforms the environment will be moved around to
+ * make room for the ps display string.
+ */
+ switch (xlop)
+ {
+ case BS_XLOG_STARTUP:
+ statmsg = "startup subprocess";
+ break;
+ case BS_XLOG_CHECKPOINT:
+ statmsg = "checkpoint subprocess";
+ break;
+ case BS_XLOG_SHUTDOWN:
+ statmsg = "shutdown subprocess";
+ break;
+ default:
+ statmsg = "??? subprocess";
+ break;
+ }
+ init_ps_display(real_argc, real_argv, statmsg, "", "");
+ set_ps_display("");
+
/* Set up command-line arguments for subprocess */
av[ac++] = "postgres";
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.234 2001/09/27 16:29:12 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.235 2001/10/19 00:44:08 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
char *debug_query_string; /* used by pgmonitor */
-/*
- * for ps display
- */
-bool HostnameLookup;
-bool ShowPortNumber;
-
-bool Log_connections = false;
-
/* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
CommandDest whereToSendOutput = Debug;
int firstchar;
StringInfo parser_input;
- char *remote_host;
- unsigned short remote_port;
-
char *potential_DataDir = NULL;
/*
MemoryContextInit();
}
+ set_ps_display("startup");
+
SetProcessingMode(InitProcessing);
/*
real_argv[0]);
/*
- * Find remote host name or address.
- */
- remote_host = NULL;
-
- if (IsUnderPostmaster)
- {
- if (MyProcPort->raddr.sa.sa_family == AF_INET)
- {
- struct hostent *host_ent;
- char *host_addr;
-
- remote_port = ntohs(MyProcPort->raddr.in.sin_port);
- host_addr = inet_ntoa(MyProcPort->raddr.in.sin_addr);
-
- if (HostnameLookup)
- {
- host_ent = gethostbyaddr((char *) &MyProcPort->raddr.in.sin_addr, sizeof(MyProcPort->raddr.in.sin_addr), AF_INET);
-
- if (host_ent)
- {
- remote_host = palloc(strlen(host_addr) + strlen(host_ent->h_name) + 3);
- sprintf(remote_host, "%s[%s]", host_ent->h_name, host_addr);
- }
- }
-
- if (remote_host == NULL)
- remote_host = pstrdup(host_addr);
-
- if (ShowPortNumber)
- {
- char *str = palloc(strlen(remote_host) + 7);
-
- sprintf(str, "%s:%hu", remote_host, remote_port);
- pfree(remote_host);
- remote_host = str;
- }
- }
- else
-/* not AF_INET */
- remote_host = "[local]";
-
-
- /*
- * Set process parameters for ps
- *
- * WARNING: On some platforms the environment will be moved around to
- * make room for the ps display string. So any references to
- * optarg or getenv() from above will be invalid after this call.
- * Better use strdup or something similar.
- */
- init_ps_display(real_argc, real_argv, username, DBName, remote_host);
- set_ps_display("startup");
- }
-
- if (Log_connections)
- elog(DEBUG, "connection: host=%s user=%s database=%s",
- remote_host, username, DBName);
-
- /*
* General initialization.
*
* NOTE: if you are tempted to add code in this vicinity, consider
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
- puts("$Revision: 1.234 $ $Date: 2001/09/27 16:29:12 $\n");
+ puts("$Revision: 1.235 $ $Date: 2001/10/19 00:44:08 $\n");
}
/*