1 /*-------------------------------------------------------------------------
3 * pg_ctl --- start/stops/restarts the PostgreSQL server
5 * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
7 * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.91 2007/12/09 19:01:40 tgl Exp $
9 *-------------------------------------------------------------------------
14 * Need this to get defines for restricted tokens and jobs. And it
15 * has to be set before any header from the Win32 API is loaded.
17 #define _WIN32_WINNT 0x0500
20 #include "postgres_fe.h"
25 #include <sys/types.h>
29 #ifdef HAVE_SYS_RESOURCE_H
31 #include <sys/resource.h>
34 #include "libpq/pqsignal.h"
35 #include "getopt_long.h"
37 #if defined(__CYGWIN__)
38 #include <sys/cygwin.h>
40 /* Cygwin defines WIN32 in windows.h, but we don't want it. */
44 #ifndef HAVE_INT_OPTRESET
48 /* PID can be negative for standalone backend */
52 #define WHITESPACE "\f\n\r\t\v" /* as defined by isspace() */
54 /* postgres version ident string */
55 #define PM_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"
77 RUN_AS_SERVICE_COMMAND
80 #define DEFAULT_WAIT 60
82 static bool do_wait = false;
83 static bool wait_set = false;
84 static int wait_seconds = DEFAULT_WAIT;
85 static bool silent_mode = false;
86 static ShutdownMode shutdown_mode = SMART_MODE;
87 static int sig = SIGTERM; /* default */
88 static CtlCommand ctl_command = NO_COMMAND;
89 static char *pg_data = NULL;
90 static char *pgdata_opt = NULL;
91 static char *post_opts = NULL;
92 static const char *progname;
93 static char *log_file = NULL;
94 static char *postgres_path = NULL;
95 static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
96 static char *register_username = NULL;
97 static char *register_password = NULL;
98 static char *argv0 = NULL;
99 static bool allow_core_files = false;
102 write_stderr(const char *fmt,...)
103 /* This extension allows gcc to check the format string for consistency with
104 the supplied arguments. */
105 __attribute__((format(printf, 1, 2)));
106 static void *pg_malloc(size_t size);
107 static char *xstrdup(const char *s);
108 static void do_advice(void);
109 static void do_help(void);
110 static void set_mode(char *modeopt);
111 static void set_sig(char *signame);
112 static void do_start(void);
113 static void do_stop(void);
114 static void do_restart(void);
115 static void do_reload(void);
116 static void do_status(void);
117 static void do_kill(pgpid_t pid);
118 static void print_msg(const char *msg);
120 #if defined(WIN32) || defined(__CYGWIN__)
121 static bool pgwin32_IsInstalled(SC_HANDLE);
122 static char *pgwin32_CommandLine(bool);
123 static void pgwin32_doRegister(void);
124 static void pgwin32_doUnregister(void);
125 static void pgwin32_SetServiceStatus(DWORD);
126 static void WINAPI pgwin32_ServiceHandler(DWORD);
127 static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
128 static void pgwin32_doRunAsService(void);
129 static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo);
131 static SERVICE_STATUS status;
132 static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
133 static HANDLE shutdownHandles[2];
134 static pid_t postmasterPID = -1;
136 #define shutdownEvent shutdownHandles[0]
137 #define postmasterProcess shutdownHandles[1]
140 static pgpid_t get_pgpid(void);
141 static char **readfile(const char *path);
142 static int start_postmaster(void);
143 static void read_post_opts(void);
145 static bool test_postmaster_connection(bool);
146 static bool postmaster_is_alive(pid_t pid);
148 static char def_postopts_file[MAXPGPATH];
149 static char postopts_file[MAXPGPATH];
150 static char pid_file[MAXPGPATH];
151 static char conf_file[MAXPGPATH];
153 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
154 static void unlimit_core_size(void);
158 #if defined(WIN32) || defined(__CYGWIN__)
160 write_eventlog(int level, const char *line)
162 static HANDLE evtHandle = INVALID_HANDLE_VALUE;
164 if (evtHandle == INVALID_HANDLE_VALUE)
166 evtHandle = RegisterEventSource(NULL, "PostgreSQL");
167 if (evtHandle == NULL)
169 evtHandle = INVALID_HANDLE_VALUE;
174 ReportEvent(evtHandle,
177 0, /* All events are Id 0 */
187 * Write errors to stderr (or by equal means when stderr is
191 write_stderr(const char *fmt,...)
196 #if !defined(WIN32) && !defined(__CYGWIN__)
197 /* On Unix, we just fprintf to stderr */
198 vfprintf(stderr, fmt, ap);
202 * On Win32, we print to stderr if running on a console, or write to
203 * eventlog if running as a service
205 if (!isatty(fileno(stderr))) /* Running as a service */
207 char errbuf[2048]; /* Arbitrary size? */
209 vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
211 write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
214 /* Not running as service, write to stderr */
215 vfprintf(stderr, fmt, ap);
221 * routines to check memory allocations and fail noisily.
225 pg_malloc(size_t size)
229 result = malloc(size);
232 write_stderr(_("%s: out of memory\n"), progname);
240 xstrdup(const char *s)
247 write_stderr(_("%s: out of memory\n"), progname);
254 * Given an already-localized string, print it to stdout unless the
255 * user has specified that no messages should be printed.
258 print_msg(const char *msg)
273 pidf = fopen(pid_file, "r");
276 /* No pid file, not an error on startup */
281 write_stderr(_("%s: could not open PID file \"%s\": %s\n"),
282 progname, pid_file, strerror(errno));
286 if (fscanf(pidf, "%ld", &pid) != 1)
288 write_stderr(_("%s: invalid data in PID file \"%s\"\n"),
293 return (pgpid_t) pid;
298 * get the lines from a text file - return NULL if file can't be opened
301 readfile(const char *path)
311 if ((infile = fopen(path, "r")) == NULL)
314 /* pass over the file twice - the first time to size the result */
316 while ((c = fgetc(infile)) != EOF)
322 if (linelen > maxlength)
328 /* handle last line without a terminating newline (yuck) */
331 if (linelen > maxlength)
334 /* set up the result and the line buffer */
335 result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
336 buffer = (char *) pg_malloc(maxlength + 1);
338 /* now reprocess the file and store the lines */
341 while (fgets(buffer, maxlength + 1, infile) != NULL)
342 result[nlines++] = xstrdup(buffer);
346 result[nlines] = NULL;
354 * start/test/stop routines
358 start_postmaster(void)
365 * Since there might be quotes to handle here, it is easier simply to pass
366 * everything to a shell to process them.
368 if (log_file != NULL)
369 snprintf(cmd, MAXPGPATH, "%s\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1 &%s",
370 SYSTEMQUOTE, postgres_path, pgdata_opt, post_opts,
371 DEVNULL, log_file, SYSTEMQUOTE);
373 snprintf(cmd, MAXPGPATH, "%s\"%s\" %s%s < \"%s\" 2>&1 &%s",
374 SYSTEMQUOTE, postgres_path, pgdata_opt, post_opts,
375 DEVNULL, SYSTEMQUOTE);
381 * On win32 we don't use system(). So we don't need to use & (which would
382 * be START /B on win32). However, we still call the shell (CMD.EXE) with
383 * it to handle redirection etc.
385 PROCESS_INFORMATION pi;
387 if (log_file != NULL)
388 snprintf(cmd, MAXPGPATH, "CMD /C %s\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1%s",
389 SYSTEMQUOTE, postgres_path, pgdata_opt, post_opts,
390 DEVNULL, log_file, SYSTEMQUOTE);
392 snprintf(cmd, MAXPGPATH, "CMD /C %s\"%s\" %s%s < \"%s\" 2>&1%s",
393 SYSTEMQUOTE, postgres_path, pgdata_opt, post_opts,
394 DEVNULL, SYSTEMQUOTE);
396 if (!CreateRestrictedProcess(cmd, &pi))
397 return GetLastError();
398 CloseHandle(pi.hProcess);
399 CloseHandle(pi.hThread);
407 * Find the pgport and try a connection
408 * Note that the checkpoint parameter enables a Windows service control
409 * manager checkpoint, it's got nothing to do with database checkpoints!!
412 test_postmaster_connection(bool do_checkpoint)
415 bool success = false;
419 char connstr[128]; /* Should be way more than enough! */
424 for (p = post_opts; *p;)
426 /* advance past whitespace/quoting */
427 while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
430 if (strncmp(p, "-p", strlen("-p")) == 0)
433 /* advance past whitespace/quoting */
434 while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
436 strlcpy(portstr, p, Min(strcspn(p, "\"'" WHITESPACE) + 1,
438 /* keep looking, maybe there is another -p */
440 /* Advance to next whitespace */
441 while (*p && !isspace((unsigned char) *p))
450 optlines = readfile(conf_file);
451 if (optlines != NULL)
453 for (; *optlines != NULL; optlines++)
457 while (isspace((unsigned char) *p))
459 if (strncmp(p, "port", strlen("port")) != 0)
462 while (isspace((unsigned char) *p))
467 while (isspace((unsigned char) *p))
469 strlcpy(portstr, p, Min(strcspn(p, "#" WHITESPACE) + 1,
471 /* keep looking, maybe there is another */
477 if (!*portstr && getenv("PGPORT") != NULL)
478 strlcpy(portstr, getenv("PGPORT"), sizeof(portstr));
482 snprintf(portstr, sizeof(portstr), "%d", DEF_PGPORT);
485 * We need to set a connect timeout otherwise on Windows the SCM will
486 * probably timeout first
488 snprintf(connstr, sizeof(connstr),
489 "dbname=postgres port=%s connect_timeout=5", portstr);
491 for (i = 0; i < wait_seconds; i++)
493 if ((conn = PQconnectdb(connstr)) != NULL &&
494 (PQstatus(conn) == CONNECTION_OK ||
495 PQconnectionNeedsPassword(conn)))
509 * Increment the wait hint by 6 secs (connection timeout +
510 * sleep) We must do this to indicate to the SCM that our
511 * startup time is changing, otherwise it'll usually send a
512 * stop signal after 20 seconds, despite incrementing the
513 * checkpoint counter.
515 status.dwWaitHint += 6000;
516 status.dwCheckPoint++;
517 SetServiceStatus(hStatus, (LPSERVICE_STATUS) & status);
524 pg_usleep(1000000); /* 1 sec */
532 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
534 unlimit_core_size(void)
538 getrlimit(RLIMIT_CORE, &lim);
539 if (lim.rlim_max == 0)
541 write_stderr(_("%s: cannot set core file size limit; disallowed by hard limit\n"),
545 else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
547 lim.rlim_cur = lim.rlim_max;
548 setrlimit(RLIMIT_CORE, &lim);
556 char *optline = NULL;
558 if (post_opts == NULL)
563 optlines = readfile(ctl_command == RESTART_COMMAND ?
564 postopts_file : def_postopts_file);
565 if (optlines == NULL)
567 if (ctl_command == START_COMMAND || ctl_command == RUN_AS_SERVICE_COMMAND)
571 write_stderr(_("%s: could not read file \"%s\"\n"), progname, postopts_file);
575 else if (optlines[0] == NULL || optlines[1] != NULL)
577 write_stderr(_("%s: option file \"%s\" must have exactly one line\n"),
578 progname, ctl_command == RESTART_COMMAND ?
579 postopts_file : def_postopts_file);
584 optline = optlines[0];
585 len = strcspn(optline, "\r\n");
588 if (ctl_command == RESTART_COMMAND)
592 arg1 = strchr(optline, *SYSTEMQUOTE);
593 if (arg1 == NULL || arg1 == optline)
597 *(arg1 - 1) = '\0'; /* this should be a space */
600 if (postgres_path != NULL)
601 postgres_path = optline;
616 if (ctl_command != RESTART_COMMAND)
618 old_pid = get_pgpid();
620 write_stderr(_("%s: another server might be running; "
621 "trying to start server anyway\n"),
627 /* No -D or -D already added during server start */
628 if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
631 if (postgres_path == NULL)
633 char *postmaster_path;
636 postmaster_path = pg_malloc(MAXPGPATH);
638 if ((ret = find_other_exec(argv0, "postgres", PM_VERSIONSTR,
639 postmaster_path)) < 0)
641 char full_path[MAXPGPATH];
643 if (find_my_exec(argv0, full_path) < 0)
644 strlcpy(full_path, progname, sizeof(full_path));
647 write_stderr(_("The program \"postgres\" is needed by %s "
648 "but was not found in the\n"
649 "same directory as \"%s\".\n"
650 "Check your installation.\n"),
651 progname, full_path);
653 write_stderr(_("The program \"postgres\" was found by \"%s\"\n"
654 "but was not the same version as %s.\n"
655 "Check your installation.\n"),
656 full_path, progname);
659 postgres_path = postmaster_path;
662 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
663 if (allow_core_files)
667 exitcode = start_postmaster();
670 write_stderr(_("%s: could not start server: exit code was %d\n"),
681 write_stderr(_("%s: could not start server\n"
682 "Examine the log output.\n"),
690 print_msg(_("waiting for server to start..."));
692 if (test_postmaster_connection(false) == false)
694 printf(_("could not start server\n"));
699 print_msg(_(" done\n"));
700 print_msg(_("server started\n"));
704 print_msg(_("server starting\n"));
716 if (pid == 0) /* no pid file */
718 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
719 write_stderr(_("Is server running?\n"));
722 else if (pid < 0) /* standalone backend, not postmaster */
725 write_stderr(_("%s: cannot stop server; "
726 "single-user server is running (PID: %ld)\n"),
731 if (kill((pid_t) pid, sig) != 0)
733 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
740 print_msg(_("server shutting down\n"));
745 print_msg(_("waiting for server to shut down..."));
747 for (cnt = 0; cnt < wait_seconds; cnt++)
749 if ((pid = get_pgpid()) != 0)
752 pg_usleep(1000000); /* 1 sec */
758 if (pid != 0) /* pid file still exists */
760 print_msg(_(" failed\n"));
762 write_stderr(_("%s: server does not shut down\n"), progname);
765 print_msg(_(" done\n"));
767 printf(_("server stopped\n"));
773 * restart/reload routines
784 if (pid == 0) /* no pid file */
786 write_stderr(_("%s: PID file \"%s\" does not exist\n"),
788 write_stderr(_("Is server running?\n"));
789 write_stderr(_("starting server anyway\n"));
793 else if (pid < 0) /* standalone backend, not postmaster */
796 if (postmaster_is_alive((pid_t) pid))
798 write_stderr(_("%s: cannot restart server; "
799 "single-user server is running (PID: %ld)\n"),
801 write_stderr(_("Please terminate the single-user server and try again.\n"));
806 if (postmaster_is_alive((pid_t) pid))
808 if (kill((pid_t) pid, sig) != 0)
810 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
815 print_msg(_("waiting for server to shut down..."));
817 /* always wait for restart */
819 for (cnt = 0; cnt < wait_seconds; cnt++)
821 if ((pid = get_pgpid()) != 0)
824 pg_usleep(1000000); /* 1 sec */
830 if (pid != 0) /* pid file still exists */
832 print_msg(_(" failed\n"));
834 write_stderr(_("%s: server does not shut down\n"), progname);
838 print_msg(_(" done\n"));
839 printf(_("server stopped\n"));
843 write_stderr(_("%s: old server process (PID: %ld) seems to be gone\n"),
845 write_stderr(_("starting server anyway\n"));
858 if (pid == 0) /* no pid file */
860 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
861 write_stderr(_("Is server running?\n"));
864 else if (pid < 0) /* standalone backend, not postmaster */
867 write_stderr(_("%s: cannot reload server; "
868 "single-user server is running (PID: %ld)\n"),
870 write_stderr(_("Please terminate the single-user server and try again.\n"));
874 if (kill((pid_t) pid, sig) != 0)
876 write_stderr(_("%s: could not send reload signal (PID: %ld): %s\n"),
877 progname, pid, strerror(errno));
881 print_msg(_("server signaled\n"));
889 postmaster_is_alive(pid_t pid)
892 * Test to see if the process is still there. Note that we do not
893 * consider an EPERM failure to mean that the process is still there;
894 * EPERM must mean that the given PID belongs to some other userid, and
895 * considering the permissions on $PGDATA, that means it's not the
896 * postmaster we are after.
898 * Don't believe that our own PID or parent shell's PID is the postmaster,
899 * either. (Windows hasn't got getppid(), though.)
904 if (pid == getppid())
907 if (kill(pid, 0) == 0)
918 if (pid != 0) /* 0 means no pid file */
920 if (pid < 0) /* standalone backend */
923 if (postmaster_is_alive((pid_t) pid))
925 printf(_("%s: single-user server is running (PID: %ld)\n"),
933 if (postmaster_is_alive((pid_t) pid))
937 printf(_("%s: server is running (PID: %ld)\n"),
940 optlines = readfile(postopts_file);
941 if (optlines != NULL)
942 for (; *optlines != NULL; optlines++)
943 fputs(*optlines, stdout);
948 printf(_("%s: no server running\n"), progname);
957 if (kill((pid_t) pid, sig) != 0)
959 write_stderr(_("%s: could not send signal %d (PID: %ld): %s\n"),
960 progname, sig, pid, strerror(errno));
965 #if defined(WIN32) || defined(__CYGWIN__)
968 pgwin32_IsInstalled(SC_HANDLE hSCM)
970 SC_HANDLE hService = OpenService(hSCM, register_servicename, SERVICE_QUERY_CONFIG);
971 bool bResult = (hService != NULL);
974 CloseServiceHandle(hService);
979 pgwin32_CommandLine(bool registration)
981 static char cmdLine[MAXPGPATH];
990 ret = find_my_exec(argv0, cmdLine);
993 write_stderr(_("%s: could not find own program executable\n"), progname);
999 ret = find_other_exec(argv0, "postgres", PM_VERSIONSTR, cmdLine);
1002 write_stderr(_("%s: could not find postgres program executable\n"), progname);
1008 /* need to convert to windows path */
1009 cygwin_conv_to_full_win32_path(cmdLine, buf);
1010 strcpy(cmdLine, buf);
1015 if (pg_strcasecmp(cmdLine + strlen(cmdLine) - 4, ".exe"))
1017 /* If commandline does not end in .exe, append it */
1018 strcat(cmdLine, ".exe");
1020 strcat(cmdLine, " runservice -N \"");
1021 strcat(cmdLine, register_servicename);
1022 strcat(cmdLine, "\"");
1027 strcat(cmdLine, " -D \"");
1028 strcat(cmdLine, pg_data);
1029 strcat(cmdLine, "\"");
1032 if (registration && do_wait)
1033 strcat(cmdLine, " -w");
1035 if (registration && wait_seconds != DEFAULT_WAIT)
1037 sprintf(cmdLine + strlen(cmdLine), " -t %d", wait_seconds);
1041 strcat(cmdLine, " ");
1043 strcat(cmdLine, " -o \"");
1044 strcat(cmdLine, post_opts);
1046 strcat(cmdLine, "\"");
1053 pgwin32_doRegister(void)
1056 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1060 write_stderr(_("%s: could not open service manager\n"), progname);
1063 if (pgwin32_IsInstalled(hSCM))
1065 CloseServiceHandle(hSCM);
1066 write_stderr(_("%s: service \"%s\" already registered\n"), progname, register_servicename);
1070 if ((hService = CreateService(hSCM, register_servicename, register_servicename,
1071 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
1072 SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
1073 pgwin32_CommandLine(true),
1074 NULL, NULL, "RPCSS\0", register_username, register_password)) == NULL)
1076 CloseServiceHandle(hSCM);
1077 write_stderr(_("%s: could not register service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1080 CloseServiceHandle(hService);
1081 CloseServiceHandle(hSCM);
1085 pgwin32_doUnregister(void)
1088 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1092 write_stderr(_("%s: could not open service manager\n"), progname);
1095 if (!pgwin32_IsInstalled(hSCM))
1097 CloseServiceHandle(hSCM);
1098 write_stderr(_("%s: service \"%s\" not registered\n"), progname, register_servicename);
1102 if ((hService = OpenService(hSCM, register_servicename, DELETE)) == NULL)
1104 CloseServiceHandle(hSCM);
1105 write_stderr(_("%s: could not open service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1108 if (!DeleteService(hService))
1110 CloseServiceHandle(hService);
1111 CloseServiceHandle(hSCM);
1112 write_stderr(_("%s: could not unregister service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1115 CloseServiceHandle(hService);
1116 CloseServiceHandle(hSCM);
1120 pgwin32_SetServiceStatus(DWORD currentState)
1122 status.dwCurrentState = currentState;
1123 SetServiceStatus(hStatus, (LPSERVICE_STATUS) & status);
1127 pgwin32_ServiceHandler(DWORD request)
1131 case SERVICE_CONTROL_STOP:
1132 case SERVICE_CONTROL_SHUTDOWN:
1135 * We only need a short wait hint here as it just needs to wait
1136 * for the next checkpoint. They occur every 5 seconds during
1139 status.dwWaitHint = 10000;
1140 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1141 SetEvent(shutdownEvent);
1144 case SERVICE_CONTROL_PAUSE:
1145 /* Win32 config reloading */
1146 status.dwWaitHint = 5000;
1147 kill(postmasterPID, SIGHUP);
1150 /* FIXME: These could be used to replace other signals etc */
1151 case SERVICE_CONTROL_CONTINUE:
1152 case SERVICE_CONTROL_INTERROGATE:
1159 pgwin32_ServiceMain(DWORD argc, LPTSTR * argv)
1161 PROCESS_INFORMATION pi;
1163 DWORD check_point_start;
1165 /* Initialize variables */
1166 status.dwWin32ExitCode = S_OK;
1167 status.dwCheckPoint = 0;
1168 status.dwWaitHint = 60000;
1169 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
1170 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
1171 status.dwServiceSpecificExitCode = 0;
1172 status.dwCurrentState = SERVICE_START_PENDING;
1174 memset(&pi, 0, sizeof(pi));
1178 /* Register the control request handler */
1179 if ((hStatus = RegisterServiceCtrlHandler(register_servicename, pgwin32_ServiceHandler)) == (SERVICE_STATUS_HANDLE) 0)
1182 if ((shutdownEvent = CreateEvent(NULL, true, false, NULL)) == NULL)
1185 /* Start the postmaster */
1186 pgwin32_SetServiceStatus(SERVICE_START_PENDING);
1187 if (!CreateRestrictedProcess(pgwin32_CommandLine(false), &pi))
1189 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1192 postmasterPID = pi.dwProcessId;
1193 postmasterProcess = pi.hProcess;
1194 CloseHandle(pi.hThread);
1198 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Waiting for server startup...\n"));
1199 if (test_postmaster_connection(true) == false)
1201 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Timed out waiting for server startup\n"));
1202 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1205 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Server started and accepting connections\n"));
1209 * Save the checkpoint value as it might have been incremented in
1210 * test_postmaster_connection
1212 check_point_start = status.dwCheckPoint;
1214 pgwin32_SetServiceStatus(SERVICE_RUNNING);
1216 /* Wait for quit... */
1217 ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);
1219 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1222 case WAIT_OBJECT_0: /* shutdown event */
1223 kill(postmasterPID, SIGINT);
1226 * Increment the checkpoint and try again Abort after 12
1227 * checkpoints as the postmaster has probably hung
1229 while (WaitForSingleObject(postmasterProcess, 5000) == WAIT_TIMEOUT && status.dwCheckPoint < 12)
1230 status.dwCheckPoint++;
1233 case (WAIT_OBJECT_0 + 1): /* postmaster went down */
1237 /* shouldn't get here? */
1241 CloseHandle(shutdownEvent);
1242 CloseHandle(postmasterProcess);
1244 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1248 pgwin32_doRunAsService(void)
1250 SERVICE_TABLE_ENTRY st[] = {{register_servicename, pgwin32_ServiceMain},
1253 if (StartServiceCtrlDispatcher(st) == 0)
1255 write_stderr(_("%s: could not start service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1262 * Mingw headers are incomplete, and so are the libraries. So we have to load
1263 * a whole lot of API functions dynamically. Since we have to do this anyway,
1264 * also load the couple of functions that *do* exist in minwg headers but not
1265 * on NT4. That way, we don't break on NT4.
1267 typedef BOOL(WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
1268 typedef BOOL(WINAPI * __IsProcessInJob) (HANDLE, HANDLE, PBOOL);
1269 typedef HANDLE(WINAPI * __CreateJobObject) (LPSECURITY_ATTRIBUTES, LPCTSTR);
1270 typedef BOOL(WINAPI * __SetInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD);
1271 typedef BOOL(WINAPI * __AssignProcessToJobObject) (HANDLE, HANDLE);
1272 typedef BOOL(WINAPI * __QueryInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD);
1274 /* Windows API define missing from MingW headers */
1275 #define DISABLE_MAX_PRIVILEGE 0x1
1278 * Create a restricted token, a job object sandbox, and execute the specified
1281 * Returns 0 on success, non-zero on failure, same as CreateProcess().
1283 * On NT4, or any other system not containing the required functions, will
1284 * launch the process under the current token without doing any modifications.
1286 * NOTE! Job object will only work when running as a service, because it's
1287 * automatically destroyed when pg_ctl exits.
1290 CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo)
1296 HANDLE restrictedToken;
1297 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
1298 SID_AND_ATTRIBUTES dropSids[2];
1300 /* Functions loaded dynamically */
1301 __CreateRestrictedToken _CreateRestrictedToken = NULL;
1302 __IsProcessInJob _IsProcessInJob = NULL;
1303 __CreateJobObject _CreateJobObject = NULL;
1304 __SetInformationJobObject _SetInformationJobObject = NULL;
1305 __AssignProcessToJobObject _AssignProcessToJobObject = NULL;
1306 __QueryInformationJobObject _QueryInformationJobObject = NULL;
1307 HANDLE Kernel32Handle;
1308 HANDLE Advapi32Handle;
1310 ZeroMemory(&si, sizeof(si));
1313 Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
1314 if (Advapi32Handle != NULL)
1316 _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
1319 if (_CreateRestrictedToken == NULL)
1322 * NT4 doesn't have CreateRestrictedToken, so just call ordinary
1325 write_stderr("WARNING: cannot create restricted tokens on this platform\n");
1326 if (Advapi32Handle != NULL)
1327 FreeLibrary(Advapi32Handle);
1328 return CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, processInfo);
1331 /* Open the current token to use as a base for the restricted one */
1332 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
1334 write_stderr("Failed to open process token: %lu\n", GetLastError());
1338 /* Allocate list of SIDs to remove */
1339 ZeroMemory(&dropSids, sizeof(dropSids));
1340 if (!AllocateAndInitializeSid(&NtAuthority, 2,
1341 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
1342 0, &dropSids[0].Sid) ||
1343 !AllocateAndInitializeSid(&NtAuthority, 2,
1344 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
1345 0, &dropSids[1].Sid))
1347 write_stderr("Failed to allocate SIDs: %lu\n", GetLastError());
1351 b = _CreateRestrictedToken(origToken,
1352 DISABLE_MAX_PRIVILEGE,
1353 sizeof(dropSids) / sizeof(dropSids[0]),
1359 FreeSid(dropSids[1].Sid);
1360 FreeSid(dropSids[0].Sid);
1361 CloseHandle(origToken);
1362 FreeLibrary(Advapi32Handle);
1366 write_stderr("Failed to create restricted token: %lu\n", GetLastError());
1370 r = CreateProcessAsUser(restrictedToken, NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, processInfo);
1372 Kernel32Handle = LoadLibrary("KERNEL32.DLL");
1373 if (Kernel32Handle != NULL)
1375 _IsProcessInJob = (__IsProcessInJob) GetProcAddress(Kernel32Handle, "IsProcessInJob");
1376 _CreateJobObject = (__CreateJobObject) GetProcAddress(Kernel32Handle, "CreateJobObjectA");
1377 _SetInformationJobObject = (__SetInformationJobObject) GetProcAddress(Kernel32Handle, "SetInformationJobObject");
1378 _AssignProcessToJobObject = (__AssignProcessToJobObject) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject");
1379 _QueryInformationJobObject = (__QueryInformationJobObject) GetProcAddress(Kernel32Handle, "QueryInformationJobObject");
1382 /* Verify that we found all functions */
1383 if (_IsProcessInJob == NULL || _CreateJobObject == NULL || _SetInformationJobObject == NULL || _AssignProcessToJobObject == NULL || _QueryInformationJobObject == NULL)
1386 * IsProcessInJob() is not available on < WinXP, so there is no need
1387 * to log the error every time in that case
1391 osv.dwOSVersionInfoSize = sizeof(osv);
1392 if (!GetVersionEx(&osv) || /* could not get version */
1393 (osv.dwMajorVersion == 5 && osv.dwMinorVersion > 0) || /* 5.1=xp, 5.2=2003, etc */
1394 osv.dwMajorVersion > 5) /* anything newer should have the API */
1397 * Log error if we can't get version, or if we're on WinXP/2003 or
1400 write_stderr("WARNING: could not locate all job object functions in system API\n");
1406 if (_IsProcessInJob(processInfo->hProcess, NULL, &inJob))
1411 * Job objects are working, and the new process isn't in one,
1412 * so we can create one safely. If any problems show up when
1413 * setting it, we're going to ignore them.
1418 sprintf(jobname, "PostgreSQL_%lu", processInfo->dwProcessId);
1420 job = _CreateJobObject(NULL, jobname);
1423 JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
1424 JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
1425 JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
1427 ZeroMemory(&basicLimit, sizeof(basicLimit));
1428 ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
1429 ZeroMemory(&securityLimit, sizeof(securityLimit));
1431 basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
1432 basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
1433 _SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));
1435 uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
1436 JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_HANDLES | JOB_OBJECT_UILIMIT_READCLIPBOARD |
1437 JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
1438 _SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));
1440 securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
1441 securityLimit.JobToken = restrictedToken;
1442 _SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));
1444 _AssignProcessToJobObject(job, processInfo->hProcess);
1450 CloseHandle(restrictedToken);
1452 ResumeThread(processInfo->hThread);
1454 FreeLibrary(Kernel32Handle);
1457 * We intentionally don't close the job object handle, because we want the
1458 * object to live on until pg_ctl shuts down.
1467 write_stderr(_("Try \"%s --help\" for more information.\n"), progname);
1475 printf(_("%s is a utility to start, stop, restart, reload configuration files,\n"
1476 "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n\n"), progname);
1477 printf(_("Usage:\n"));
1478 printf(_(" %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n"), progname);
1479 printf(_(" %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"), progname);
1480 printf(_(" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"
1481 " [-o \"OPTIONS\"]\n"), progname);
1482 printf(_(" %s reload [-D DATADIR] [-s]\n"), progname);
1483 printf(_(" %s status [-D DATADIR]\n"), progname);
1484 printf(_(" %s kill SIGNALNAME PID\n"), progname);
1485 #if defined(WIN32) || defined(__CYGWIN__)
1486 printf(_(" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n"
1487 " [-w] [-t SECS] [-o \"OPTIONS\"]\n"), progname);
1488 printf(_(" %s unregister [-N SERVICENAME]\n"), progname);
1491 printf(_("\nCommon options:\n"));
1492 printf(_(" -D, --pgdata DATADIR location of the database storage area\n"));
1493 printf(_(" -s, --silent only print errors, no informational messages\n"));
1494 printf(_(" -t SECS seconds to wait when using -w option\n"));
1495 printf(_(" -w wait until operation completes\n"));
1496 printf(_(" -W do not wait until operation completes\n"));
1497 printf(_(" --help show this help, then exit\n"));
1498 printf(_(" --version output version information, then exit\n"));
1499 printf(_("(The default is to wait for shutdown, but not for start or restart.)\n\n"));
1500 printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
1502 printf(_("\nOptions for start or restart:\n"));
1503 printf(_(" -l, --log FILENAME write (or append) server log to FILENAME\n"));
1504 printf(_(" -o OPTIONS command line options to pass to postgres\n"
1505 " (PostgreSQL server executable)\n"));
1506 printf(_(" -p PATH-TO-POSTGRES normally not necessary\n"));
1507 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
1508 printf(_(" -c, --core-files allow postgres to produce core files\n"));
1510 printf(_(" -c, --core-files not applicable on this platform\n"));
1512 printf(_("\nOptions for stop or restart:\n"));
1513 printf(_(" -m SHUTDOWN-MODE can be \"smart\", \"fast\", or \"immediate\"\n"));
1515 printf(_("\nShutdown modes are:\n"));
1516 printf(_(" smart quit after all clients have disconnected\n"));
1517 printf(_(" fast quit directly, with proper shutdown\n"));
1518 printf(_(" immediate quit without complete shutdown; will lead to recovery on restart\n"));
1520 printf(_("\nAllowed signal names for kill:\n"));
1521 printf(" HUP INT QUIT ABRT TERM USR1 USR2\n");
1523 #if defined(WIN32) || defined(__CYGWIN__)
1524 printf(_("\nOptions for register and unregister:\n"));
1525 printf(_(" -N SERVICENAME service name with which to register PostgreSQL server\n"));
1526 printf(_(" -P PASSWORD password of account to register PostgreSQL server\n"));
1527 printf(_(" -U USERNAME user name of account to register PostgreSQL server\n"));
1530 printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
1536 set_mode(char *modeopt)
1538 if (strcmp(modeopt, "s") == 0 || strcmp(modeopt, "smart") == 0)
1540 shutdown_mode = SMART_MODE;
1543 else if (strcmp(modeopt, "f") == 0 || strcmp(modeopt, "fast") == 0)
1545 shutdown_mode = FAST_MODE;
1548 else if (strcmp(modeopt, "i") == 0 || strcmp(modeopt, "immediate") == 0)
1550 shutdown_mode = IMMEDIATE_MODE;
1555 write_stderr(_("%s: unrecognized shutdown mode \"%s\"\n"), progname, modeopt);
1564 set_sig(char *signame)
1566 if (!strcmp(signame, "HUP"))
1568 else if (!strcmp(signame, "INT"))
1570 else if (!strcmp(signame, "QUIT"))
1572 else if (!strcmp(signame, "ABRT"))
1576 * probably should NOT provide SIGKILL
1578 * else if (!strcmp(signame,"KILL")) sig = SIGKILL;
1580 else if (!strcmp(signame, "TERM"))
1582 else if (!strcmp(signame, "USR1"))
1584 else if (!strcmp(signame, "USR2"))
1588 write_stderr(_("%s: unrecognized signal name \"%s\"\n"), progname, signame);
1598 main(int argc, char **argv)
1600 static struct option long_options[] = {
1601 {"help", no_argument, NULL, '?'},
1602 {"version", no_argument, NULL, 'V'},
1603 {"log", required_argument, NULL, 'l'},
1604 {"mode", required_argument, NULL, 'm'},
1605 {"pgdata", required_argument, NULL, 'D'},
1606 {"silent", no_argument, NULL, 's'},
1607 {"timeout", required_argument, NULL, 't'},
1608 {"core-files", no_argument, NULL, 'c'},
1614 pgpid_t killproc = 0;
1616 #if defined(WIN32) || defined(__CYGWIN__)
1617 setvbuf(stderr, NULL, _IONBF, 0);
1620 progname = get_progname(argv[0]);
1621 set_pglocale_pgservice(argv[0], "pg_ctl");
1624 * save argv[0] so do_start() can look for the postmaster if necessary. we
1625 * don't look for postmaster here because in many cases we won't need it.
1631 /* support --help and --version even if invoked as root */
1634 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 ||
1635 strcmp(argv[1], "-?") == 0)
1640 else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0)
1642 puts("pg_ctl (PostgreSQL) " PG_VERSION);
1648 * Disallow running as root, to forestall any possible security holes.
1653 write_stderr(_("%s: cannot be run as root\n"
1654 "Please log in (using, e.g., \"su\") as the "
1655 "(unprivileged) user that will\n"
1656 "own the server process.\n"),
1663 * 'Action' can be before or after args so loop over both. Some
1664 * getopt_long() implementations will reorder argv[] to place all flags
1665 * first (GNU?), but we don't rely on it. Our /port version doesn't do
1670 /* process command-line options */
1671 while (optind < argc)
1673 while ((c = getopt_long(argc, argv, "cD:l:m:N:o:p:P:st:U:wW", long_options, &option_index)) != -1)
1680 char *env_var = pg_malloc(strlen(optarg) + 8);
1682 pgdata_D = xstrdup(optarg);
1683 canonicalize_path(pgdata_D);
1684 snprintf(env_var, strlen(optarg) + 8, "PGDATA=%s",
1689 * We could pass PGDATA just in an environment
1690 * variable but we do -D too for clearer postmaster
1693 pgdata_opt = pg_malloc(strlen(pgdata_D) + 7);
1694 snprintf(pgdata_opt, strlen(pgdata_D) + 7,
1700 log_file = xstrdup(optarg);
1706 register_servicename = xstrdup(optarg);
1709 post_opts = xstrdup(optarg);
1712 postgres_path = xstrdup(optarg);
1715 register_password = xstrdup(optarg);
1721 wait_seconds = atoi(optarg);
1724 if (strchr(optarg, '\\'))
1725 register_username = xstrdup(optarg);
1727 /* Prepend .\ for local accounts */
1729 register_username = malloc(strlen(optarg) + 3);
1730 if (!register_username)
1732 write_stderr(_("%s: out of memory\n"), progname);
1735 strcpy(register_username, ".\\");
1736 strcat(register_username, optarg);
1748 allow_core_files = true;
1751 /* getopt_long already issued a suitable error message */
1757 /* Process an action */
1760 if (ctl_command != NO_COMMAND)
1762 write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]);
1767 if (strcmp(argv[optind], "start") == 0)
1768 ctl_command = START_COMMAND;
1769 else if (strcmp(argv[optind], "stop") == 0)
1770 ctl_command = STOP_COMMAND;
1771 else if (strcmp(argv[optind], "restart") == 0)
1772 ctl_command = RESTART_COMMAND;
1773 else if (strcmp(argv[optind], "reload") == 0)
1774 ctl_command = RELOAD_COMMAND;
1775 else if (strcmp(argv[optind], "status") == 0)
1776 ctl_command = STATUS_COMMAND;
1777 else if (strcmp(argv[optind], "kill") == 0)
1779 if (argc - optind < 3)
1781 write_stderr(_("%s: missing arguments for kill mode\n"), progname);
1785 ctl_command = KILL_COMMAND;
1786 set_sig(argv[++optind]);
1787 killproc = atol(argv[++optind]);
1789 #if defined(WIN32) || defined(__CYGWIN__)
1790 else if (strcmp(argv[optind], "register") == 0)
1791 ctl_command = REGISTER_COMMAND;
1792 else if (strcmp(argv[optind], "unregister") == 0)
1793 ctl_command = UNREGISTER_COMMAND;
1794 else if (strcmp(argv[optind], "runservice") == 0)
1795 ctl_command = RUN_AS_SERVICE_COMMAND;
1799 write_stderr(_("%s: unrecognized operation mode \"%s\"\n"), progname, argv[optind]);
1807 if (ctl_command == NO_COMMAND)
1809 write_stderr(_("%s: no operation specified\n"), progname);
1814 /* Note we put any -D switch into the env var above */
1815 pg_data = getenv("PGDATA");
1818 pg_data = xstrdup(pg_data);
1819 canonicalize_path(pg_data);
1822 if (pg_data == NULL &&
1823 ctl_command != KILL_COMMAND && ctl_command != UNREGISTER_COMMAND)
1825 write_stderr(_("%s: no database directory specified "
1826 "and environment variable PGDATA unset\n"),
1834 switch (ctl_command)
1836 case RESTART_COMMAND:
1848 if (ctl_command == RELOAD_COMMAND)
1856 snprintf(def_postopts_file, MAXPGPATH, "%s/postmaster.opts.default", pg_data);
1857 snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);
1858 snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
1859 snprintf(conf_file, MAXPGPATH, "%s/postgresql.conf", pg_data);
1862 switch (ctl_command)
1864 case STATUS_COMMAND:
1873 case RESTART_COMMAND:
1876 case RELOAD_COMMAND:
1882 #if defined(WIN32) || defined(__CYGWIN__)
1883 case REGISTER_COMMAND:
1884 pgwin32_doRegister();
1886 case UNREGISTER_COMMAND:
1887 pgwin32_doUnregister();
1889 case RUN_AS_SERVICE_COMMAND:
1890 pgwin32_doRunAsService();