Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit eb13319

Browse files
committed
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.
1 parent 9047292 commit eb13319

File tree

2 files changed

+127
-86
lines changed

2 files changed

+127
-86
lines changed

src/backend/postmaster/postmaster.c

Lines changed: 123 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
*
3838
*
3939
* IDENTIFICATION
40-
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.245 2001/10/03 21:58:28 tgl Exp $
40+
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.246 2001/10/19 00:44:08 tgl Exp $
4141
*
4242
* NOTES
4343
*
@@ -73,7 +73,8 @@
7373
#include <fcntl.h>
7474
#include <time.h>
7575
#include <sys/param.h>
76-
/* moved here to prevent double define */
76+
#include <netinet/in.h>
77+
#include <arpa/inet.h>
7778
#include <netdb.h>
7879
#include <limits.h>
7980

@@ -103,6 +104,7 @@
103104
#include "utils/exc.h"
104105
#include "utils/guc.h"
105106
#include "utils/memutils.h"
107+
#include "utils/ps_status.h"
106108
#include "bootstrap/bootstrap.h"
107109

108110
#include "pgstat.h"
@@ -194,6 +196,10 @@ int PreAuthDelay = 0;
194196
int AuthenticationTimeout = 60;
195197
int CheckPointTimeout = 300;
196198

199+
bool HostnameLookup; /* for ps display */
200+
bool ShowPortNumber;
201+
bool Log_connections = false;
202+
197203
/* Startup/shutdown state */
198204
static pid_t StartupPID = 0,
199205
ShutdownPID = 0,
@@ -821,7 +827,7 @@ ServerLoop(void)
821827
struct timeval timeout_tv;
822828

823829
if (CheckPointPID == 0 && checkpointed &&
824-
Shutdown == NoShutdown && !FatalError)
830+
Shutdown == NoShutdown && !FatalError && random_seed != 0)
825831
{
826832
time_t now = time(NULL);
827833

@@ -981,7 +987,9 @@ initMasks(fd_set *rmask, fd_set *wmask)
981987
* not return at all.
982988
*
983989
* (Note that elog(FATAL) stuff is sent to the client, so only use it
984-
* if that's what you want.)
990+
* if that's what you want. Return STATUS_ERROR if you don't want to
991+
* send anything to the client, which would typically be appropriate
992+
* if we detect a communications failure.)
985993
*/
986994
static int
987995
ProcessStartupPacket(Port *port, bool SSLdone)
@@ -991,15 +999,25 @@ ProcessStartupPacket(Port *port, bool SSLdone)
991999
int32 len;
9921000
void *buf;
9931001

994-
pq_getbytes((char *)&len, 4);
1002+
if (pq_getbytes((char *) &len, 4) == EOF)
1003+
{
1004+
elog(DEBUG, "incomplete startup packet");
1005+
return STATUS_ERROR;
1006+
}
1007+
9951008
len = ntohl(len);
9961009
len -= 4;
9971010

9981011
if (len < sizeof(len) || len > sizeof(len) + sizeof(StartupPacket))
9991012
elog(FATAL, "invalid length of startup packet");
10001013

10011014
buf = palloc(len);
1002-
pq_getbytes(buf, len);
1015+
1016+
if (pq_getbytes(buf, len) == EOF)
1017+
{
1018+
elog(DEBUG, "incomplete startup packet");
1019+
return STATUS_ERROR;
1020+
}
10031021

10041022
packet = buf;
10051023

@@ -1913,6 +1931,7 @@ split_opts(char **argv, int *argcp, char *s)
19131931
static int
19141932
DoBackend(Port *port)
19151933
{
1934+
char *remote_host;
19161935
char *av[ARGV_SIZE * 2];
19171936
int ac = 0;
19181937
char debugbuf[ARGV_SIZE];
@@ -1981,14 +2000,78 @@ DoBackend(Port *port)
19812000

19822001
/*
19832002
* Receive the startup packet (which might turn out to be a cancel
1984-
* request packet); then perform client authentication.
2003+
* request packet).
19852004
*/
19862005
status = ProcessStartupPacket(port, false);
19872006

1988-
if (status == 127)
1989-
return 0; /* cancel request processed */
2007+
if (status != STATUS_OK)
2008+
return 0; /* cancel request processed, or error */
19902009

1991-
ClientAuthentication(MyProcPort); /* might not return, if failure */
2010+
/*
2011+
* Now that we have the user and database name, we can set the process
2012+
* title for ps. It's good to do this as early as possible in startup.
2013+
*
2014+
* But first, we need the remote host name.
2015+
*/
2016+
if (port->raddr.sa.sa_family == AF_INET)
2017+
{
2018+
unsigned short remote_port;
2019+
char *host_addr;
2020+
2021+
remote_port = ntohs(port->raddr.in.sin_port);
2022+
host_addr = inet_ntoa(port->raddr.in.sin_addr);
2023+
2024+
remote_host = NULL;
2025+
2026+
if (HostnameLookup)
2027+
{
2028+
struct hostent *host_ent;
2029+
2030+
host_ent = gethostbyaddr((char *) &port->raddr.in.sin_addr,
2031+
sizeof(port->raddr.in.sin_addr),
2032+
AF_INET);
2033+
2034+
if (host_ent)
2035+
{
2036+
remote_host = palloc(strlen(host_addr) + strlen(host_ent->h_name) + 3);
2037+
sprintf(remote_host, "%s[%s]", host_ent->h_name, host_addr);
2038+
}
2039+
}
2040+
2041+
if (remote_host == NULL)
2042+
remote_host = pstrdup(host_addr);
2043+
2044+
if (ShowPortNumber)
2045+
{
2046+
char *str = palloc(strlen(remote_host) + 7);
2047+
2048+
sprintf(str, "%s:%hu", remote_host, remote_port);
2049+
pfree(remote_host);
2050+
remote_host = str;
2051+
}
2052+
}
2053+
else
2054+
{
2055+
/* not AF_INET */
2056+
remote_host = "[local]";
2057+
}
2058+
2059+
/*
2060+
* Set process parameters for ps
2061+
*
2062+
* WARNING: On some platforms the environment will be moved around to
2063+
* make room for the ps display string. So any references to
2064+
* optarg or getenv() from above will be invalid after this call.
2065+
* Better use strdup or something similar.
2066+
*/
2067+
init_ps_display(real_argc, real_argv, port->user, port->database,
2068+
remote_host);
2069+
set_ps_display("authentication");
2070+
2071+
/*
2072+
* Now perform authentication exchange.
2073+
*/
2074+
ClientAuthentication(port); /* might not return, if failure */
19922075

19932076
/*
19942077
* Done with authentication. Disable timeout, and prevent SIGTERM/SIGQUIT
@@ -1998,6 +2081,10 @@ DoBackend(Port *port)
19982081
elog(FATAL, "DoBackend: Unable to disable timer for auth timeout");
19992082
PG_SETMASK(&BlockSig);
20002083

2084+
if (Log_connections)
2085+
elog(DEBUG, "connection: host=%s user=%s database=%s",
2086+
remote_host, port->user, port->database);
2087+
20012088
/*
20022089
* Don't want backend to be able to see the postmaster random number
20032090
* generator state. We have to clobber the static random_seed *and*
@@ -2138,7 +2225,7 @@ schedule_checkpoint(SIGNAL_ARGS)
21382225

21392226
/* Ignore request if checkpointing is currently disabled */
21402227
if (CheckPointPID == 0 && checkpointed &&
2141-
Shutdown == NoShutdown && !FatalError)
2228+
Shutdown == NoShutdown && !FatalError && random_seed != 0)
21422229
{
21432230
CheckPointPID = CheckPointDataBase();
21442231
/* note: if fork fails, CheckPointPID stays 0; nothing happens */
@@ -2302,6 +2389,7 @@ SSDataBase(int xlop)
23022389

23032390
if ((pid = fork()) == 0) /* child */
23042391
{
2392+
const char *statmsg;
23052393
char *av[ARGV_SIZE * 2];
23062394
int ac = 0;
23072395
char nbbuf[ARGV_SIZE];
@@ -2321,6 +2409,30 @@ SSDataBase(int xlop)
23212409
/* Close the postmaster's sockets */
23222410
ClosePostmasterPorts(true);
23232411

2412+
/*
2413+
* Identify myself via ps
2414+
*
2415+
* WARNING: On some platforms the environment will be moved around to
2416+
* make room for the ps display string.
2417+
*/
2418+
switch (xlop)
2419+
{
2420+
case BS_XLOG_STARTUP:
2421+
statmsg = "startup subprocess";
2422+
break;
2423+
case BS_XLOG_CHECKPOINT:
2424+
statmsg = "checkpoint subprocess";
2425+
break;
2426+
case BS_XLOG_SHUTDOWN:
2427+
statmsg = "shutdown subprocess";
2428+
break;
2429+
default:
2430+
statmsg = "??? subprocess";
2431+
break;
2432+
}
2433+
init_ps_display(real_argc, real_argv, statmsg, "", "");
2434+
set_ps_display("");
2435+
23242436
/* Set up command-line arguments for subprocess */
23252437
av[ac++] = "postgres";
23262438

src/backend/tcop/postgres.c

Lines changed: 4 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.234 2001/09/27 16:29:12 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.235 2001/10/19 00:44:08 tgl Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -30,9 +30,6 @@
3030
#if HAVE_SYS_SELECT_H
3131
#include <sys/select.h>
3232
#endif
33-
#include <netinet/in.h>
34-
#include <arpa/inet.h>
35-
#include <netdb.h>
3633
#ifdef HAVE_GETOPT_H
3734
#include <getopt.h>
3835
#endif
@@ -77,14 +74,6 @@ extern char *optarg;
7774

7875
char *debug_query_string; /* used by pgmonitor */
7976

80-
/*
81-
* for ps display
82-
*/
83-
bool HostnameLookup;
84-
bool ShowPortNumber;
85-
86-
bool Log_connections = false;
87-
8877
/* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
8978
CommandDest whereToSendOutput = Debug;
9079

@@ -1131,9 +1120,6 @@ PostgresMain(int argc, char *argv[],
11311120
int firstchar;
11321121
StringInfo parser_input;
11331122

1134-
char *remote_host;
1135-
unsigned short remote_port;
1136-
11371123
char *potential_DataDir = NULL;
11381124

11391125
/*
@@ -1165,6 +1151,8 @@ PostgresMain(int argc, char *argv[],
11651151
MemoryContextInit();
11661152
}
11671153

1154+
set_ps_display("startup");
1155+
11681156
SetProcessingMode(InitProcessing);
11691157

11701158
/*
@@ -1625,65 +1613,6 @@ PostgresMain(int argc, char *argv[],
16251613
elog(FATAL, "%s: could not locate executable, bailing out...",
16261614
real_argv[0]);
16271615

1628-
/*
1629-
* Find remote host name or address.
1630-
*/
1631-
remote_host = NULL;
1632-
1633-
if (IsUnderPostmaster)
1634-
{
1635-
if (MyProcPort->raddr.sa.sa_family == AF_INET)
1636-
{
1637-
struct hostent *host_ent;
1638-
char *host_addr;
1639-
1640-
remote_port = ntohs(MyProcPort->raddr.in.sin_port);
1641-
host_addr = inet_ntoa(MyProcPort->raddr.in.sin_addr);
1642-
1643-
if (HostnameLookup)
1644-
{
1645-
host_ent = gethostbyaddr((char *) &MyProcPort->raddr.in.sin_addr, sizeof(MyProcPort->raddr.in.sin_addr), AF_INET);
1646-
1647-
if (host_ent)
1648-
{
1649-
remote_host = palloc(strlen(host_addr) + strlen(host_ent->h_name) + 3);
1650-
sprintf(remote_host, "%s[%s]", host_ent->h_name, host_addr);
1651-
}
1652-
}
1653-
1654-
if (remote_host == NULL)
1655-
remote_host = pstrdup(host_addr);
1656-
1657-
if (ShowPortNumber)
1658-
{
1659-
char *str = palloc(strlen(remote_host) + 7);
1660-
1661-
sprintf(str, "%s:%hu", remote_host, remote_port);
1662-
pfree(remote_host);
1663-
remote_host = str;
1664-
}
1665-
}
1666-
else
1667-
/* not AF_INET */
1668-
remote_host = "[local]";
1669-
1670-
1671-
/*
1672-
* Set process parameters for ps
1673-
*
1674-
* WARNING: On some platforms the environment will be moved around to
1675-
* make room for the ps display string. So any references to
1676-
* optarg or getenv() from above will be invalid after this call.
1677-
* Better use strdup or something similar.
1678-
*/
1679-
init_ps_display(real_argc, real_argv, username, DBName, remote_host);
1680-
set_ps_display("startup");
1681-
}
1682-
1683-
if (Log_connections)
1684-
elog(DEBUG, "connection: host=%s user=%s database=%s",
1685-
remote_host, username, DBName);
1686-
16871616
/*
16881617
* General initialization.
16891618
*
@@ -1716,7 +1645,7 @@ PostgresMain(int argc, char *argv[],
17161645
if (!IsUnderPostmaster)
17171646
{
17181647
puts("\nPOSTGRES backend interactive interface ");
1719-
puts("$Revision: 1.234 $ $Date: 2001/09/27 16:29:12 $\n");
1648+
puts("$Revision: 1.235 $ $Date: 2001/10/19 00:44:08 $\n");
17201649
}
17211650

17221651
/*

0 commit comments

Comments
 (0)