22
22
23
23
#include <locale.h>
24
24
#include <signal.h>
25
+ #include <stdlib.h>
25
26
#include <sys/types.h>
26
27
#include <sys/stat.h>
27
28
#include <unistd.h>
@@ -138,6 +139,7 @@ static void read_post_opts(void);
138
139
139
140
static PGPing test_postmaster_connection (bool );
140
141
static bool postmaster_is_alive (pid_t pid );
142
+ static time_t start_time ;
141
143
142
144
static char postopts_file [MAXPGPATH ];
143
145
static char pid_file [MAXPGPATH ];
@@ -404,13 +406,13 @@ static PGPing
404
406
test_postmaster_connection (bool do_checkpoint )
405
407
{
406
408
int portnum = 0 ;
407
- char socket_dir [MAXPGPATH ];
409
+ char host_str [MAXPGPATH ];
408
410
char connstr [MAXPGPATH + 256 ];
409
411
PGPing ret = PQPING_OK ;/* assume success for wait == zero */
410
412
char * * optlines ;
411
413
int i ;
412
414
413
- socket_dir [0 ]= '\0' ;
415
+ host_str [0 ]= '\0' ;
414
416
connstr [0 ]= '\0' ;
415
417
416
418
for (i = 0 ;i < wait_seconds ;i ++ )
@@ -425,21 +427,25 @@ test_postmaster_connection(bool do_checkpoint)
425
427
*0lock file created but status not written
426
428
*2pre-9.1 server, shared memory not created
427
429
*3pre-9.1 server, shared memory created
428
- *49.1+ server, shared memory not created
429
- *59.1+ server, shared memory created
430
+ *59.1+ server, listen host not created
431
+ *69.1+ server, shared memory not created
432
+ *79.1+ server, shared memory created
430
433
*
431
434
*For pre-9.1 Unix servers, we grab the port number from the
432
435
*shmem key (first value on line 3). Pre-9.1 Win32 has no
433
- *written shmem key, so we fail. 9.1+ writesboth the port
434
- *number and socket address in the file for us to use.
436
+ *written shmem key, so we fail. 9.1+ writesconnection
437
+ *information in the file for us to use.
435
438
*(PG_VERSION could also have told us the major version.)
436
439
*/
437
440
438
441
/* Try to read a completed postmaster.pid file */
439
442
if ((optlines = readfile (pid_file ))!= NULL &&
440
443
optlines [0 ]!= NULL &&
441
444
optlines [1 ]!= NULL &&
442
- optlines [2 ]!= NULL )
445
+ optlines [2 ]!= NULL &&
446
+ /* pre-9.1 server or listen_address line is present? */
447
+ (optlines [3 ]== NULL ||
448
+ optlines [5 ]!= NULL ))
443
449
{
444
450
/* A 3-line file? */
445
451
if (optlines [3 ]== NULL )
@@ -459,41 +465,63 @@ test_postmaster_connection(bool do_checkpoint)
459
465
return PQPING_NO_ATTEMPT ;
460
466
}
461
467
}
462
- else /* 9.1+ server */
468
+ else
463
469
{
464
- portnum = atoi (optlines [2 ]);
465
-
466
- /* Get socket directory, if specified. */
467
- if (optlines [3 ][0 ]!= '\n' )
470
+ /*
471
+ *Easy check to see if we are looking at the right
472
+ *data directory: Is the postmaster older than this
473
+ *execution of pg_ctl? Subtract 2 seconds to account
474
+ *for possible clock skew between pg_ctl and the
475
+ *postmaster.
476
+ */
477
+ if (atol (optlines [1 ])< start_time - 2 )
468
478
{
469
- /*
470
- *While unix_socket_directory can accept relative
471
- *directories, libpq's host must have a leading slash
472
- *to indicate a socket directory.
473
- */
474
- if (optlines [3 ][0 ]!= '/' )
475
- {
476
- write_stderr (_ ("%s: -w option cannot use a relative socket directory specification\n" ),
477
- progname );
478
- return PQPING_NO_ATTEMPT ;
479
- }
480
- strlcpy (socket_dir ,optlines [3 ],MAXPGPATH );
481
- /* remove newline */
482
- if (strchr (socket_dir ,'\n' )!= NULL )
483
- * strchr (socket_dir ,'\n' )= '\0' ;
479
+ write_stderr (_ ("%s: this data directory is running an older postmaster\n" ),
480
+ progname );
481
+ return PQPING_NO_ATTEMPT ;
484
482
}
485
- }
483
+
484
+ portnum = atoi (optlines [3 ]);
486
485
486
+ /*
487
+ *Determine the proper host string to use.
488
+ */
489
+ #ifdef HAVE_UNIX_SOCKETS
490
+ /*
491
+ *Use socket directory, if specified. We assume if we
492
+ *have unix sockets, the server does too because we
493
+ *just started the postmaster.
494
+ */
495
+ /*
496
+ *While unix_socket_directory can accept relative
497
+ *directories, libpq's host must have a leading slash
498
+ *to indicate a socket directory.
499
+ */
500
+ if (optlines [4 ][0 ]!= '\n' && optlines [4 ][0 ]!= '/' )
501
+ {
502
+ write_stderr (_ ("%s: -w option cannot use a relative socket directory specification\n" ),
503
+ progname );
504
+ return PQPING_NO_ATTEMPT ;
505
+ }
506
+ strlcpy (host_str ,optlines [4 ],sizeof (host_str ));
507
+ #else
508
+ strlcpy (host_str ,optlines [5 ],sizeof (host_str ));
509
+ #endif
510
+ /* remove newline */
511
+ if (strchr (host_str ,'\n' )!= NULL )
512
+ * strchr (host_str ,'\n' )= '\0' ;
513
+ }
514
+
487
515
/*
488
516
* We need to set connect_timeout otherwise on Windows the
489
517
* Service Control Manager (SCM) will probably timeout first.
490
518
*/
491
519
snprintf (connstr ,sizeof (connstr ),
492
520
"dbname=postgres port=%d connect_timeout=5" ,portnum );
493
521
494
- if (socket_dir [0 ]!= '\0' )
522
+ if (host_str [0 ]!= '\0' )
495
523
snprintf (connstr + strlen (connstr ),sizeof (connstr )- strlen (connstr ),
496
- " host='%s'" ,socket_dir );
524
+ " host='%s'" ,host_str );
497
525
}
498
526
}
499
527
@@ -1756,6 +1784,7 @@ main(int argc, char **argv)
1756
1784
1757
1785
progname = get_progname (argv [0 ]);
1758
1786
set_pglocale_pgservice (argv [0 ],PG_TEXTDOMAIN ("pg_ctl" ));
1787
+ start_time = time (NULL );
1759
1788
1760
1789
/*
1761
1790
* save argv[0] so do_start() can look for the postmaster if necessary. we