mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
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.
This commit is contained in:
parent
9047292725
commit
eb133197b6
@ -37,7 +37,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
*
|
||||
@ -73,7 +73,8 @@
|
||||
#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>
|
||||
|
||||
@ -103,6 +104,7 @@
|
||||
#include "utils/exc.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/ps_status.h"
|
||||
#include "bootstrap/bootstrap.h"
|
||||
|
||||
#include "pgstat.h"
|
||||
@ -194,6 +196,10 @@ int PreAuthDelay = 0;
|
||||
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,
|
||||
@ -821,7 +827,7 @@ ServerLoop(void)
|
||||
struct timeval timeout_tv;
|
||||
|
||||
if (CheckPointPID == 0 && checkpointed &&
|
||||
Shutdown == NoShutdown && !FatalError)
|
||||
Shutdown == NoShutdown && !FatalError && random_seed != 0)
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
|
||||
@ -981,7 +987,9 @@ initMasks(fd_set *rmask, fd_set *wmask)
|
||||
* 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)
|
||||
@ -991,7 +999,12 @@ 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;
|
||||
|
||||
@ -999,7 +1012,12 @@ ProcessStartupPacket(Port *port, bool SSLdone)
|
||||
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;
|
||||
|
||||
@ -1913,6 +1931,7 @@ split_opts(char **argv, int *argcp, char *s)
|
||||
static int
|
||||
DoBackend(Port *port)
|
||||
{
|
||||
char *remote_host;
|
||||
char *av[ARGV_SIZE * 2];
|
||||
int ac = 0;
|
||||
char debugbuf[ARGV_SIZE];
|
||||
@ -1981,14 +2000,78 @@ DoBackend(Port *port)
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -1998,6 +2081,10 @@ DoBackend(Port *port)
|
||||
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*
|
||||
@ -2138,7 +2225,7 @@ schedule_checkpoint(SIGNAL_ARGS)
|
||||
|
||||
/* 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 */
|
||||
@ -2302,6 +2389,7 @@ SSDataBase(int xlop)
|
||||
|
||||
if ((pid = fork()) == 0) /* child */
|
||||
{
|
||||
const char *statmsg;
|
||||
char *av[ARGV_SIZE * 2];
|
||||
int ac = 0;
|
||||
char nbbuf[ARGV_SIZE];
|
||||
@ -2321,6 +2409,30 @@ SSDataBase(int xlop)
|
||||
/* 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";
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@ -30,9 +30,6 @@
|
||||
#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
|
||||
@ -77,14 +74,6 @@ extern char *optarg;
|
||||
|
||||
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;
|
||||
|
||||
@ -1131,9 +1120,6 @@ PostgresMain(int argc, char *argv[],
|
||||
int firstchar;
|
||||
StringInfo parser_input;
|
||||
|
||||
char *remote_host;
|
||||
unsigned short remote_port;
|
||||
|
||||
char *potential_DataDir = NULL;
|
||||
|
||||
/*
|
||||
@ -1165,6 +1151,8 @@ PostgresMain(int argc, char *argv[],
|
||||
MemoryContextInit();
|
||||
}
|
||||
|
||||
set_ps_display("startup");
|
||||
|
||||
SetProcessingMode(InitProcessing);
|
||||
|
||||
/*
|
||||
@ -1625,65 +1613,6 @@ PostgresMain(int argc, char *argv[],
|
||||
elog(FATAL, "%s: could not locate executable, bailing out...",
|
||||
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.
|
||||
*
|
||||
@ -1716,7 +1645,7 @@ PostgresMain(int argc, char *argv[],
|
||||
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");
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user