Commit eb133197 authored by Tom Lane's avatar Tom Lane

Move init_ps_display from postgres.c to postmaster.c, putting it

just after receipt of the startup packet.  Now, postmaster children
that are waiting for client authentication response will show as
'postgres: user database host authentication'.  Also, do an
init_ps_display for startup/shutdown/checkpoint subprocesses,
so that they are readily identifiable as well.  Fix an obscure race
condition that could lead to Assert failure in the postmaster ---
attempting to start a checkpoint process before any connections have
been received led to calling PostmasterRandom before setting random_seed.
parent 90472927
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* *
...@@ -73,7 +73,8 @@ ...@@ -73,7 +73,8 @@
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
#include <sys/param.h> #include <sys/param.h>
/* moved here to prevent double define */ #include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h> #include <netdb.h>
#include <limits.h> #include <limits.h>
...@@ -103,6 +104,7 @@ ...@@ -103,6 +104,7 @@
#include "utils/exc.h" #include "utils/exc.h"
#include "utils/guc.h" #include "utils/guc.h"
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/ps_status.h"
#include "bootstrap/bootstrap.h" #include "bootstrap/bootstrap.h"
#include "pgstat.h" #include "pgstat.h"
...@@ -194,6 +196,10 @@ int PreAuthDelay = 0; ...@@ -194,6 +196,10 @@ int PreAuthDelay = 0;
int AuthenticationTimeout = 60; int AuthenticationTimeout = 60;
int CheckPointTimeout = 300; int CheckPointTimeout = 300;
bool HostnameLookup; /* for ps display */
bool ShowPortNumber;
bool Log_connections = false;
/* Startup/shutdown state */ /* Startup/shutdown state */
static pid_t StartupPID = 0, static pid_t StartupPID = 0,
ShutdownPID = 0, ShutdownPID = 0,
...@@ -821,7 +827,7 @@ ServerLoop(void) ...@@ -821,7 +827,7 @@ ServerLoop(void)
struct timeval timeout_tv; struct timeval timeout_tv;
if (CheckPointPID == 0 && checkpointed && if (CheckPointPID == 0 && checkpointed &&
Shutdown == NoShutdown && !FatalError) Shutdown == NoShutdown && !FatalError && random_seed != 0)
{ {
time_t now = time(NULL); time_t now = time(NULL);
...@@ -981,7 +987,9 @@ initMasks(fd_set *rmask, fd_set *wmask) ...@@ -981,7 +987,9 @@ initMasks(fd_set *rmask, fd_set *wmask)
* not return at all. * not return at all.
* *
* (Note that elog(FATAL) stuff is sent to the client, so only use it * (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 static int
ProcessStartupPacket(Port *port, bool SSLdone) ProcessStartupPacket(Port *port, bool SSLdone)
...@@ -991,7 +999,12 @@ ProcessStartupPacket(Port *port, bool SSLdone) ...@@ -991,7 +999,12 @@ ProcessStartupPacket(Port *port, bool SSLdone)
int32 len; int32 len;
void *buf; 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 = ntohl(len);
len -= 4; len -= 4;
...@@ -999,7 +1012,12 @@ ProcessStartupPacket(Port *port, bool SSLdone) ...@@ -999,7 +1012,12 @@ ProcessStartupPacket(Port *port, bool SSLdone)
elog(FATAL, "invalid length of startup packet"); elog(FATAL, "invalid length of startup packet");
buf = palloc(len); buf = palloc(len);
pq_getbytes(buf, len);
if (pq_getbytes(buf, len) == EOF)
{
elog(DEBUG, "incomplete startup packet");
return STATUS_ERROR;
}
packet = buf; packet = buf;
...@@ -1913,6 +1931,7 @@ split_opts(char **argv, int *argcp, char *s) ...@@ -1913,6 +1931,7 @@ split_opts(char **argv, int *argcp, char *s)
static int static int
DoBackend(Port *port) DoBackend(Port *port)
{ {
char *remote_host;
char *av[ARGV_SIZE * 2]; char *av[ARGV_SIZE * 2];
int ac = 0; int ac = 0;
char debugbuf[ARGV_SIZE]; char debugbuf[ARGV_SIZE];
...@@ -1981,14 +2000,78 @@ DoBackend(Port *port) ...@@ -1981,14 +2000,78 @@ DoBackend(Port *port)
/* /*
* Receive the startup packet (which might turn out to be a cancel * Receive the startup packet (which might turn out to be a cancel
* request packet); then perform client authentication. * request packet).
*/ */
status = ProcessStartupPacket(port, false); status = ProcessStartupPacket(port, false);
if (status == 127) if (status != STATUS_OK)
return 0; /* cancel request processed */ 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 * Done with authentication. Disable timeout, and prevent SIGTERM/SIGQUIT
...@@ -1998,6 +2081,10 @@ DoBackend(Port *port) ...@@ -1998,6 +2081,10 @@ DoBackend(Port *port)
elog(FATAL, "DoBackend: Unable to disable timer for auth timeout"); elog(FATAL, "DoBackend: Unable to disable timer for auth timeout");
PG_SETMASK(&BlockSig); 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 * Don't want backend to be able to see the postmaster random number
* generator state. We have to clobber the static random_seed *and* * generator state. We have to clobber the static random_seed *and*
...@@ -2138,7 +2225,7 @@ schedule_checkpoint(SIGNAL_ARGS) ...@@ -2138,7 +2225,7 @@ schedule_checkpoint(SIGNAL_ARGS)
/* Ignore request if checkpointing is currently disabled */ /* Ignore request if checkpointing is currently disabled */
if (CheckPointPID == 0 && checkpointed && if (CheckPointPID == 0 && checkpointed &&
Shutdown == NoShutdown && !FatalError) Shutdown == NoShutdown && !FatalError && random_seed != 0)
{ {
CheckPointPID = CheckPointDataBase(); CheckPointPID = CheckPointDataBase();
/* note: if fork fails, CheckPointPID stays 0; nothing happens */ /* note: if fork fails, CheckPointPID stays 0; nothing happens */
...@@ -2302,6 +2389,7 @@ SSDataBase(int xlop) ...@@ -2302,6 +2389,7 @@ SSDataBase(int xlop)
if ((pid = fork()) == 0) /* child */ if ((pid = fork()) == 0) /* child */
{ {
const char *statmsg;
char *av[ARGV_SIZE * 2]; char *av[ARGV_SIZE * 2];
int ac = 0; int ac = 0;
char nbbuf[ARGV_SIZE]; char nbbuf[ARGV_SIZE];
...@@ -2321,6 +2409,30 @@ SSDataBase(int xlop) ...@@ -2321,6 +2409,30 @@ SSDataBase(int xlop)
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(true); 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 */ /* Set up command-line arguments for subprocess */
av[ac++] = "postgres"; av[ac++] = "postgres";
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -30,9 +30,6 @@ ...@@ -30,9 +30,6 @@
#if HAVE_SYS_SELECT_H #if HAVE_SYS_SELECT_H
#include <sys/select.h> #include <sys/select.h>
#endif #endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#ifdef HAVE_GETOPT_H #ifdef HAVE_GETOPT_H
#include <getopt.h> #include <getopt.h>
#endif #endif
...@@ -77,14 +74,6 @@ extern char *optarg; ...@@ -77,14 +74,6 @@ extern char *optarg;
char *debug_query_string; /* used by pgmonitor */ 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 */ /* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
CommandDest whereToSendOutput = Debug; CommandDest whereToSendOutput = Debug;
...@@ -1131,9 +1120,6 @@ PostgresMain(int argc, char *argv[], ...@@ -1131,9 +1120,6 @@ PostgresMain(int argc, char *argv[],
int firstchar; int firstchar;
StringInfo parser_input; StringInfo parser_input;
char *remote_host;
unsigned short remote_port;
char *potential_DataDir = NULL; char *potential_DataDir = NULL;
/* /*
...@@ -1165,6 +1151,8 @@ PostgresMain(int argc, char *argv[], ...@@ -1165,6 +1151,8 @@ PostgresMain(int argc, char *argv[],
MemoryContextInit(); MemoryContextInit();
} }
set_ps_display("startup");
SetProcessingMode(InitProcessing); SetProcessingMode(InitProcessing);
/* /*
...@@ -1625,65 +1613,6 @@ PostgresMain(int argc, char *argv[], ...@@ -1625,65 +1613,6 @@ PostgresMain(int argc, char *argv[],
elog(FATAL, "%s: could not locate executable, bailing out...", elog(FATAL, "%s: could not locate executable, bailing out...",
real_argv[0]); 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. * General initialization.
* *
...@@ -1716,7 +1645,7 @@ PostgresMain(int argc, char *argv[], ...@@ -1716,7 +1645,7 @@ PostgresMain(int argc, char *argv[],
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); 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");
} }
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment