37
37
*
38
38
*
39
39
* 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 $
41
41
*
42
42
* NOTES
43
43
*
73
73
#include <fcntl.h>
74
74
#include <time.h>
75
75
#include <sys/param.h>
76
- /* moved here to prevent double define */
76
+ #include <netinet/in.h>
77
+ #include <arpa/inet.h>
77
78
#include <netdb.h>
78
79
#include <limits.h>
79
80
103
104
#include "utils/exc.h"
104
105
#include "utils/guc.h"
105
106
#include "utils/memutils.h"
107
+ #include "utils/ps_status.h"
106
108
#include "bootstrap/bootstrap.h"
107
109
108
110
#include "pgstat.h"
@@ -194,6 +196,10 @@ int PreAuthDelay = 0;
194
196
int AuthenticationTimeout = 60 ;
195
197
int CheckPointTimeout = 300 ;
196
198
199
+ bool HostnameLookup ; /* for ps display */
200
+ bool ShowPortNumber ;
201
+ bool Log_connections = false;
202
+
197
203
/* Startup/shutdown state */
198
204
static pid_t StartupPID = 0 ,
199
205
ShutdownPID = 0 ,
@@ -821,7 +827,7 @@ ServerLoop(void)
821
827
struct timeval timeout_tv ;
822
828
823
829
if (CheckPointPID == 0 && checkpointed &&
824
- Shutdown == NoShutdown && !FatalError )
830
+ Shutdown == NoShutdown && !FatalError && random_seed != 0 )
825
831
{
826
832
time_t now = time (NULL );
827
833
@@ -981,7 +987,9 @@ initMasks(fd_set *rmask, fd_set *wmask)
981
987
* not return at all.
982
988
*
983
989
* (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.)
985
993
*/
986
994
static int
987
995
ProcessStartupPacket (Port * port , bool SSLdone )
@@ -991,15 +999,25 @@ ProcessStartupPacket(Port *port, bool SSLdone)
991
999
int32 len ;
992
1000
void * buf ;
993
1001
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
+
995
1008
len = ntohl (len );
996
1009
len -= 4 ;
997
1010
998
1011
if (len < sizeof (len ) || len > sizeof (len ) + sizeof (StartupPacket ))
999
1012
elog (FATAL , "invalid length of startup packet" );
1000
1013
1001
1014
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
+ }
1003
1021
1004
1022
packet = buf ;
1005
1023
@@ -1913,6 +1931,7 @@ split_opts(char **argv, int *argcp, char *s)
1913
1931
static int
1914
1932
DoBackend (Port * port )
1915
1933
{
1934
+ char * remote_host ;
1916
1935
char * av [ARGV_SIZE * 2 ];
1917
1936
int ac = 0 ;
1918
1937
char debugbuf [ARGV_SIZE ];
@@ -1981,14 +2000,78 @@ DoBackend(Port *port)
1981
2000
1982
2001
/*
1983
2002
* Receive the startup packet (which might turn out to be a cancel
1984
- * request packet); then perform client authentication .
2003
+ * request packet).
1985
2004
*/
1986
2005
status = ProcessStartupPacket (port , false);
1987
2006
1988
- if (status == 127 )
1989
- return 0 ; /* cancel request processed */
2007
+ if (status != STATUS_OK )
2008
+ return 0 ; /* cancel request processed, or error */
1990
2009
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 */
1992
2075
1993
2076
/*
1994
2077
* Done with authentication. Disable timeout, and prevent SIGTERM/SIGQUIT
@@ -1998,6 +2081,10 @@ DoBackend(Port *port)
1998
2081
elog (FATAL , "DoBackend: Unable to disable timer for auth timeout" );
1999
2082
PG_SETMASK (& BlockSig );
2000
2083
2084
+ if (Log_connections )
2085
+ elog (DEBUG , "connection: host=%s user=%s database=%s" ,
2086
+ remote_host , port -> user , port -> database );
2087
+
2001
2088
/*
2002
2089
* Don't want backend to be able to see the postmaster random number
2003
2090
* generator state. We have to clobber the static random_seed *and*
@@ -2138,7 +2225,7 @@ schedule_checkpoint(SIGNAL_ARGS)
2138
2225
2139
2226
/* Ignore request if checkpointing is currently disabled */
2140
2227
if (CheckPointPID == 0 && checkpointed &&
2141
- Shutdown == NoShutdown && !FatalError )
2228
+ Shutdown == NoShutdown && !FatalError && random_seed != 0 )
2142
2229
{
2143
2230
CheckPointPID = CheckPointDataBase ();
2144
2231
/* note: if fork fails, CheckPointPID stays 0; nothing happens */
@@ -2302,6 +2389,7 @@ SSDataBase(int xlop)
2302
2389
2303
2390
if ((pid = fork ()) == 0 ) /* child */
2304
2391
{
2392
+ const char * statmsg ;
2305
2393
char * av [ARGV_SIZE * 2 ];
2306
2394
int ac = 0 ;
2307
2395
char nbbuf [ARGV_SIZE ];
@@ -2321,6 +2409,30 @@ SSDataBase(int xlop)
2321
2409
/* Close the postmaster's sockets */
2322
2410
ClosePostmasterPorts (true);
2323
2411
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
+
2324
2436
/* Set up command-line arguments for subprocess */
2325
2437
av [ac ++ ] = "postgres" ;
2326
2438
0 commit comments