mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-09 08:10:09 +08:00
- Fix the -w (wait) option to work in Windows service mode, per bug #3382.
- Prevent the -w option being passed to the postmaster. - Read the postmaster options file when starting as a Windows service. Dave Page
This commit is contained in:
parent
1c7fe33fdb
commit
a1587e41ae
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.80 2007/05/31 15:13:04 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.81 2007/07/02 21:58:31 mha Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -126,11 +126,22 @@ static void WINAPI pgwin32_ServiceHandler(DWORD);
|
||||
static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
|
||||
static void pgwin32_doRunAsService(void);
|
||||
static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo);
|
||||
|
||||
static SERVICE_STATUS status;
|
||||
static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
|
||||
static HANDLE shutdownHandles[2];
|
||||
static pid_t postmasterPID = -1;
|
||||
|
||||
#define shutdownEvent shutdownHandles[0]
|
||||
#define postmasterProcess shutdownHandles[1]
|
||||
#endif
|
||||
|
||||
static pgpid_t get_pgpid(void);
|
||||
static char **readfile(const char *path);
|
||||
static int start_postmaster(void);
|
||||
static bool test_postmaster_connection(void);
|
||||
static int start_postmaster(void);
|
||||
static void read_post_opts(void);
|
||||
|
||||
static bool test_postmaster_connection(bool);
|
||||
static bool postmaster_is_alive(pid_t pid);
|
||||
|
||||
static char def_postopts_file[MAXPGPATH];
|
||||
@ -391,15 +402,20 @@ start_postmaster(void)
|
||||
|
||||
|
||||
|
||||
/* Find the pgport and try a connection */
|
||||
/*
|
||||
* Find the pgport and try a connection
|
||||
* Note that the checkpoint parameter enables a Windows service control
|
||||
* manager checkpoint, it's got nothing to do with database checkpoints!!
|
||||
*/
|
||||
static bool
|
||||
test_postmaster_connection(void)
|
||||
test_postmaster_connection(bool do_checkpoint)
|
||||
{
|
||||
PGconn *conn;
|
||||
bool success = false;
|
||||
int i;
|
||||
char portstr[32];
|
||||
char *p;
|
||||
char connstr[128]; /* Should be way more than enough! */
|
||||
|
||||
*portstr = '\0';
|
||||
|
||||
@ -464,10 +480,12 @@ test_postmaster_connection(void)
|
||||
if (!*portstr)
|
||||
snprintf(portstr, sizeof(portstr), "%d", DEF_PGPORT);
|
||||
|
||||
/* We need to set a connect timeout otherwise on Windows the SCM will probably timeout first */
|
||||
snprintf(connstr, sizeof(connstr), "dbname=postgres port=%s connect_timeout=5", portstr);
|
||||
|
||||
for (i = 0; i < wait_seconds; i++)
|
||||
{
|
||||
if ((conn = PQsetdbLogin(NULL, portstr, NULL, NULL,
|
||||
"postgres", NULL, NULL)) != NULL &&
|
||||
if ((conn = PQconnectdb(connstr)) != NULL &&
|
||||
(PQstatus(conn) == CONNECTION_OK ||
|
||||
(strcmp(PQerrorMessage(conn),
|
||||
PQnoPasswordSupplied) == 0)))
|
||||
@ -479,7 +497,25 @@ test_postmaster_connection(void)
|
||||
else
|
||||
{
|
||||
PQfinish(conn);
|
||||
print_msg(".");
|
||||
|
||||
#if defined(WIN32)
|
||||
if (do_checkpoint)
|
||||
{
|
||||
/*
|
||||
* Increment the wait hint by 6 secs (connection timeout + sleep)
|
||||
* We must do this to indicate to the SCM that our startup time is
|
||||
* changing, otherwise it'll usually send a stop signal after 20
|
||||
* seconds, despite incrementing the checkpoint counter.
|
||||
*/
|
||||
status.dwWaitHint += 6000;
|
||||
status.dwCheckPoint++;
|
||||
SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
|
||||
}
|
||||
|
||||
else
|
||||
#endif
|
||||
print_msg(".");
|
||||
|
||||
pg_usleep(1000000); /* 1 sec */
|
||||
}
|
||||
}
|
||||
@ -508,24 +544,10 @@ unlimit_core_size(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void
|
||||
do_start(void)
|
||||
read_post_opts(void)
|
||||
{
|
||||
pgpid_t pid;
|
||||
pgpid_t old_pid = 0;
|
||||
char *optline = NULL;
|
||||
int exitcode;
|
||||
|
||||
if (ctl_command != RESTART_COMMAND)
|
||||
{
|
||||
old_pid = get_pgpid();
|
||||
if (old_pid != 0)
|
||||
write_stderr(_("%s: another server might be running; "
|
||||
"trying to start server anyway\n"),
|
||||
progname);
|
||||
}
|
||||
|
||||
if (post_opts == NULL)
|
||||
{
|
||||
@ -536,7 +558,7 @@ do_start(void)
|
||||
postopts_file : def_postopts_file);
|
||||
if (optlines == NULL)
|
||||
{
|
||||
if (ctl_command == START_COMMAND)
|
||||
if (ctl_command == START_COMMAND || ctl_command == RUN_AS_SERVICE_COMMAND)
|
||||
post_opts = "";
|
||||
else
|
||||
{
|
||||
@ -576,6 +598,25 @@ do_start(void)
|
||||
post_opts = optline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_start(void)
|
||||
{
|
||||
pgpid_t pid;
|
||||
pgpid_t old_pid = 0;
|
||||
int exitcode;
|
||||
|
||||
if (ctl_command != RESTART_COMMAND)
|
||||
{
|
||||
old_pid = get_pgpid();
|
||||
if (old_pid != 0)
|
||||
write_stderr(_("%s: another server might be running; "
|
||||
"trying to start server anyway\n"),
|
||||
progname);
|
||||
}
|
||||
|
||||
read_post_opts();
|
||||
|
||||
/* No -D or -D already added during server start */
|
||||
if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
|
||||
@ -642,7 +683,7 @@ do_start(void)
|
||||
{
|
||||
print_msg(_("waiting for server to start..."));
|
||||
|
||||
if (test_postmaster_connection() == false)
|
||||
if (test_postmaster_connection(false) == false)
|
||||
{
|
||||
printf(_("could not start server\n"));
|
||||
exit(1);
|
||||
@ -982,7 +1023,7 @@ pgwin32_CommandLine(bool registration)
|
||||
strcat(cmdLine, "\"");
|
||||
}
|
||||
|
||||
if (do_wait)
|
||||
if (registration && do_wait)
|
||||
strcat(cmdLine, " -w");
|
||||
|
||||
if (post_opts)
|
||||
@ -1065,15 +1106,6 @@ pgwin32_doUnregister(void)
|
||||
CloseServiceHandle(hSCM);
|
||||
}
|
||||
|
||||
|
||||
static SERVICE_STATUS status;
|
||||
static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
|
||||
static HANDLE shutdownHandles[2];
|
||||
static pid_t postmasterPID = -1;
|
||||
|
||||
#define shutdownEvent shutdownHandles[0]
|
||||
#define postmasterProcess shutdownHandles[1]
|
||||
|
||||
static void
|
||||
pgwin32_SetServiceStatus(DWORD currentState)
|
||||
{
|
||||
@ -1118,6 +1150,7 @@ pgwin32_ServiceMain(DWORD argc, LPTSTR * argv)
|
||||
{
|
||||
PROCESS_INFORMATION pi;
|
||||
DWORD ret;
|
||||
DWORD check_point_start;
|
||||
|
||||
/* Initialize variables */
|
||||
status.dwWin32ExitCode = S_OK;
|
||||
@ -1130,6 +1163,8 @@ pgwin32_ServiceMain(DWORD argc, LPTSTR * argv)
|
||||
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
|
||||
read_post_opts();
|
||||
|
||||
/* Register the control request handler */
|
||||
if ((hStatus = RegisterServiceCtrlHandler(register_servicename, pgwin32_ServiceHandler)) == (SERVICE_STATUS_HANDLE) 0)
|
||||
return;
|
||||
@ -1147,10 +1182,27 @@ pgwin32_ServiceMain(DWORD argc, LPTSTR * argv)
|
||||
postmasterPID = pi.dwProcessId;
|
||||
postmasterProcess = pi.hProcess;
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
if (do_wait)
|
||||
{
|
||||
write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Waiting for server startup...\n"));
|
||||
if (test_postmaster_connection(true) == false)
|
||||
{
|
||||
write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Timed out waiting for server startup\n"));
|
||||
pgwin32_SetServiceStatus(SERVICE_STOPPED);
|
||||
return;
|
||||
}
|
||||
write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Server started and accepting connections\n"));
|
||||
}
|
||||
|
||||
/* Save the checkpoint value as it might have been incremented in test_postmaster_connection */
|
||||
check_point_start = status.dwCheckPoint;
|
||||
|
||||
pgwin32_SetServiceStatus(SERVICE_RUNNING);
|
||||
|
||||
/* Wait for quit... */
|
||||
ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);
|
||||
|
||||
pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
|
||||
switch (ret)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user