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.80 2007/05/31 15:13:04 petere 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
81 static bool do_wait = false;
82 static bool wait_set = false;
83 static int wait_seconds = 60;
84 static bool silent_mode = false;
85 static ShutdownMode shutdown_mode = SMART_MODE;
86 static int sig = SIGTERM; /* default */
87 static CtlCommand ctl_command = NO_COMMAND;
88 static char *pg_data = NULL;
89 static char *pgdata_opt = NULL;
90 static char *post_opts = NULL;
91 static const char *progname;
92 static char *log_file = NULL;
93 static char *postgres_path = NULL;
94 static const char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
95 static char *register_username = NULL;
96 static char *register_password = NULL;
97 static char *argv0 = NULL;
98 static bool allow_core_files = false;
101 write_stderr(const char *fmt,...)
102 /* This extension allows gcc to check the format string for consistency with
103 the supplied arguments. */
104 __attribute__((format(printf, 1, 2)));
105 static void *pg_malloc(size_t size);
106 static char *xstrdup(const char *s);
107 static void do_advice(void);
108 static void do_help(void);
109 static void set_mode(char *modeopt);
110 static void set_sig(char *signame);
111 static void do_start(void);
112 static void do_stop(void);
113 static void do_restart(void);
114 static void do_reload(void);
115 static void do_status(void);
116 static void do_kill(pgpid_t pid);
117 static void print_msg(const char *msg);
119 #if defined(WIN32) || defined(__CYGWIN__)
120 static bool pgwin32_IsInstalled(SC_HANDLE);
121 static char *pgwin32_CommandLine(bool);
122 static void pgwin32_doRegister(void);
123 static void pgwin32_doUnregister(void);
124 static void pgwin32_SetServiceStatus(DWORD);
125 static void WINAPI pgwin32_ServiceHandler(DWORD);
126 static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
127 static void pgwin32_doRunAsService(void);
128 static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo);
130 static pgpid_t get_pgpid(void);
131 static char **readfile(const char *path);
132 static int start_postmaster(void);
133 static bool test_postmaster_connection(void);
134 static bool postmaster_is_alive(pid_t pid);
136 static char def_postopts_file[MAXPGPATH];
137 static char postopts_file[MAXPGPATH];
138 static char pid_file[MAXPGPATH];
139 static char conf_file[MAXPGPATH];
141 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
142 static void unlimit_core_size(void);
146 #if defined(WIN32) || defined(__CYGWIN__)
148 write_eventlog(int level, const char *line)
150 static HANDLE evtHandle = INVALID_HANDLE_VALUE;
152 if (evtHandle == INVALID_HANDLE_VALUE)
154 evtHandle = RegisterEventSource(NULL, "PostgreSQL");
155 if (evtHandle == NULL)
157 evtHandle = INVALID_HANDLE_VALUE;
162 ReportEvent(evtHandle,
165 0, /* All events are Id 0 */
175 * Write errors to stderr (or by equal means when stderr is
179 write_stderr(const char *fmt,...)
184 #if !defined(WIN32) && !defined(__CYGWIN__)
185 /* On Unix, we just fprintf to stderr */
186 vfprintf(stderr, fmt, ap);
190 * On Win32, we print to stderr if running on a console, or write to
191 * eventlog if running as a service
193 if (!isatty(fileno(stderr))) /* Running as a service */
195 char errbuf[2048]; /* Arbitrary size? */
197 vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
199 write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
202 /* Not running as service, write to stderr */
203 vfprintf(stderr, fmt, ap);
209 * routines to check memory allocations and fail noisily.
213 pg_malloc(size_t size)
217 result = malloc(size);
220 write_stderr(_("%s: out of memory\n"), progname);
228 xstrdup(const char *s)
235 write_stderr(_("%s: out of memory\n"), progname);
242 * Given an already-localized string, print it to stdout unless the
243 * user has specified that no messages should be printed.
246 print_msg(const char *msg)
261 pidf = fopen(pid_file, "r");
264 /* No pid file, not an error on startup */
269 write_stderr(_("%s: could not open PID file \"%s\": %s\n"),
270 progname, pid_file, strerror(errno));
274 if (fscanf(pidf, "%ld", &pid) != 1)
276 write_stderr(_("%s: invalid data in PID file \"%s\"\n"),
281 return (pgpid_t) pid;
286 * get the lines from a text file - return NULL if file can't be opened
289 readfile(const char *path)
299 if ((infile = fopen(path, "r")) == NULL)
302 /* pass over the file twice - the first time to size the result */
304 while ((c = fgetc(infile)) != EOF)
310 if (linelen > maxlength)
316 /* handle last line without a terminating newline (yuck) */
319 if (linelen > maxlength)
322 /* set up the result and the line buffer */
323 result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
324 buffer = (char *) pg_malloc(maxlength + 1);
326 /* now reprocess the file and store the lines */
329 while (fgets(buffer, maxlength + 1, infile) != NULL)
330 result[nlines++] = xstrdup(buffer);
334 result[nlines] = NULL;
342 * start/test/stop routines
346 start_postmaster(void)
353 * Since there might be quotes to handle here, it is easier simply to pass
354 * everything to a shell to process them.
356 if (log_file != NULL)
357 snprintf(cmd, MAXPGPATH, "%s\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1 &%s",
358 SYSTEMQUOTE, postgres_path, pgdata_opt, post_opts,
359 DEVNULL, log_file, SYSTEMQUOTE);
361 snprintf(cmd, MAXPGPATH, "%s\"%s\" %s%s < \"%s\" 2>&1 &%s",
362 SYSTEMQUOTE, postgres_path, pgdata_opt, post_opts,
363 DEVNULL, SYSTEMQUOTE);
369 * On win32 we don't use system(). So we don't need to use & (which would
370 * be START /B on win32). However, we still call the shell (CMD.EXE) with
371 * it to handle redirection etc.
373 PROCESS_INFORMATION pi;
375 if (log_file != NULL)
376 snprintf(cmd, MAXPGPATH, "CMD /C %s\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1%s",
377 SYSTEMQUOTE, postgres_path, pgdata_opt, post_opts,
378 DEVNULL, log_file, SYSTEMQUOTE);
380 snprintf(cmd, MAXPGPATH, "CMD /C %s\"%s\" %s%s < \"%s\" 2>&1%s",
381 SYSTEMQUOTE, postgres_path, pgdata_opt, post_opts,
382 DEVNULL, SYSTEMQUOTE);
384 if (!CreateRestrictedProcess(cmd, &pi))
385 return GetLastError();
386 CloseHandle(pi.hProcess);
387 CloseHandle(pi.hThread);
394 /* Find the pgport and try a connection */
396 test_postmaster_connection(void)
399 bool success = false;
407 for (p = post_opts; *p;)
409 /* advance past whitespace/quoting */
410 while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
413 if (strncmp(p, "-p", strlen("-p")) == 0)
416 /* advance past whitespace/quoting */
417 while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
419 strlcpy(portstr, p, Min(strcspn(p, "\"'" WHITESPACE) + 1,
421 /* keep looking, maybe there is another -p */
423 /* Advance to next whitespace */
424 while (*p && !isspace((unsigned char) *p))
433 optlines = readfile(conf_file);
434 if (optlines != NULL)
436 for (; *optlines != NULL; optlines++)
440 while (isspace((unsigned char) *p))
442 if (strncmp(p, "port", strlen("port")) != 0)
445 while (isspace((unsigned char) *p))
450 while (isspace((unsigned char) *p))
452 strlcpy(portstr, p, Min(strcspn(p, "#" WHITESPACE) + 1,
454 /* keep looking, maybe there is another */
460 if (!*portstr && getenv("PGPORT") != NULL)
461 strlcpy(portstr, getenv("PGPORT"), sizeof(portstr));
465 snprintf(portstr, sizeof(portstr), "%d", DEF_PGPORT);
467 for (i = 0; i < wait_seconds; i++)
469 if ((conn = PQsetdbLogin(NULL, portstr, NULL, NULL,
470 "postgres", NULL, NULL)) != NULL &&
471 (PQstatus(conn) == CONNECTION_OK ||
472 (strcmp(PQerrorMessage(conn),
473 PQnoPasswordSupplied) == 0)))
483 pg_usleep(1000000); /* 1 sec */
491 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
493 unlimit_core_size(void)
496 getrlimit(RLIMIT_CORE,&lim);
497 if (lim.rlim_max == 0)
499 write_stderr(_("%s: cannot set core size, disallowed by hard limit.\n"),
503 else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
505 lim.rlim_cur = lim.rlim_max;
506 setrlimit(RLIMIT_CORE,&lim);
518 char *optline = NULL;
521 if (ctl_command != RESTART_COMMAND)
523 old_pid = get_pgpid();
525 write_stderr(_("%s: another server might be running; "
526 "trying to start server anyway\n"),
530 if (post_opts == NULL)
535 optlines = readfile(ctl_command == RESTART_COMMAND ?
536 postopts_file : def_postopts_file);
537 if (optlines == NULL)
539 if (ctl_command == START_COMMAND)
543 write_stderr(_("%s: could not read file \"%s\"\n"), progname, postopts_file);
547 else if (optlines[0] == NULL || optlines[1] != NULL)
549 write_stderr(_("%s: option file \"%s\" must have exactly one line\n"),
550 progname, ctl_command == RESTART_COMMAND ?
551 postopts_file : def_postopts_file);
556 optline = optlines[0];
557 len = strcspn(optline, "\r\n");
560 if (ctl_command == RESTART_COMMAND)
564 arg1 = strchr(optline, *SYSTEMQUOTE);
565 if (arg1 == NULL || arg1 == optline)
569 *(arg1 - 1) = '\0'; /* this should be a space */
572 if (postgres_path != NULL)
573 postgres_path = optline;
580 /* No -D or -D already added during server start */
581 if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
584 if (postgres_path == NULL)
586 char *postmaster_path;
589 postmaster_path = pg_malloc(MAXPGPATH);
591 if ((ret = find_other_exec(argv0, "postgres", PM_VERSIONSTR,
592 postmaster_path)) < 0)
594 char full_path[MAXPGPATH];
596 if (find_my_exec(argv0, full_path) < 0)
597 strlcpy(full_path, progname, sizeof(full_path));
600 write_stderr(_("The program \"postgres\" is needed by %s "
601 "but was not found in the\n"
602 "same directory as \"%s\".\n"
603 "Check your installation.\n"),
604 progname, full_path);
606 write_stderr(_("The program \"postgres\" was found by \"%s\"\n"
607 "but was not the same version as %s.\n"
608 "Check your installation.\n"),
609 full_path, progname);
612 postgres_path = postmaster_path;
615 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
616 if (allow_core_files)
620 exitcode = start_postmaster();
623 write_stderr(_("%s: could not start server: exit code was %d\n"),
634 write_stderr(_("%s: could not start server\n"
635 "Examine the log output.\n"),
643 print_msg(_("waiting for server to start..."));
645 if (test_postmaster_connection() == false)
647 printf(_("could not start server\n"));
652 print_msg(_(" done\n"));
653 print_msg(_("server started\n"));
657 print_msg(_("server starting\n"));
669 if (pid == 0) /* no pid file */
671 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
672 write_stderr(_("Is server running?\n"));
675 else if (pid < 0) /* standalone backend, not postmaster */
678 write_stderr(_("%s: cannot stop server; "
679 "single-user server is running (PID: %ld)\n"),
684 if (kill((pid_t) pid, sig) != 0)
686 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
693 print_msg(_("server shutting down\n"));
698 print_msg(_("waiting for server to shut down..."));
700 for (cnt = 0; cnt < wait_seconds; cnt++)
702 if ((pid = get_pgpid()) != 0)
705 pg_usleep(1000000); /* 1 sec */
711 if (pid != 0) /* pid file still exists */
713 print_msg(_(" failed\n"));
715 write_stderr(_("%s: server does not shut down\n"), progname);
718 print_msg(_(" done\n"));
720 printf(_("server stopped\n"));
726 * restart/reload routines
737 if (pid == 0) /* no pid file */
739 write_stderr(_("%s: PID file \"%s\" does not exist\n"),
741 write_stderr(_("Is server running?\n"));
742 write_stderr(_("starting server anyway\n"));
746 else if (pid < 0) /* standalone backend, not postmaster */
749 if (postmaster_is_alive((pid_t) pid))
751 write_stderr(_("%s: cannot restart server; "
752 "single-user server is running (PID: %ld)\n"),
754 write_stderr(_("Please terminate the single-user server and try again.\n"));
759 if (postmaster_is_alive((pid_t) pid))
761 if (kill((pid_t) pid, sig) != 0)
763 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
768 print_msg(_("waiting for server to shut down..."));
770 /* always wait for restart */
772 for (cnt = 0; cnt < wait_seconds; cnt++)
774 if ((pid = get_pgpid()) != 0)
777 pg_usleep(1000000); /* 1 sec */
783 if (pid != 0) /* pid file still exists */
785 print_msg(_(" failed\n"));
787 write_stderr(_("%s: server does not shut down\n"), progname);
791 print_msg(_(" done\n"));
792 printf(_("server stopped\n"));
796 write_stderr(_("%s: old server process (PID: %ld) seems to be gone\n"),
798 write_stderr(_("starting server anyway\n"));
811 if (pid == 0) /* no pid file */
813 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
814 write_stderr(_("Is server running?\n"));
817 else if (pid < 0) /* standalone backend, not postmaster */
820 write_stderr(_("%s: cannot reload server; "
821 "single-user server is running (PID: %ld)\n"),
823 write_stderr(_("Please terminate the single-user server and try again.\n"));
827 if (kill((pid_t) pid, sig) != 0)
829 write_stderr(_("%s: could not send reload signal (PID: %ld): %s\n"),
830 progname, pid, strerror(errno));
834 print_msg(_("server signaled\n"));
842 postmaster_is_alive(pid_t pid)
845 * Test to see if the process is still there. Note that we do not
846 * consider an EPERM failure to mean that the process is still there;
847 * EPERM must mean that the given PID belongs to some other userid, and
848 * considering the permissions on $PGDATA, that means it's not the
849 * postmaster we are after.
851 * Don't believe that our own PID or parent shell's PID is the postmaster,
852 * either. (Windows hasn't got getppid(), though.)
857 if (pid == getppid())
860 if (kill(pid, 0) == 0)
871 if (pid != 0) /* 0 means no pid file */
873 if (pid < 0) /* standalone backend */
876 if (postmaster_is_alive((pid_t) pid))
878 printf(_("%s: single-user server is running (PID: %ld)\n"),
886 if (postmaster_is_alive((pid_t) pid))
890 printf(_("%s: server is running (PID: %ld)\n"),
893 optlines = readfile(postopts_file);
894 if (optlines != NULL)
895 for (; *optlines != NULL; optlines++)
896 fputs(*optlines, stdout);
901 printf(_("%s: no server running\n"), progname);
910 if (kill((pid_t) pid, sig) != 0)
912 write_stderr(_("%s: could not send signal %d (PID: %ld): %s\n"),
913 progname, sig, pid, strerror(errno));
918 #if defined(WIN32) || defined(__CYGWIN__)
921 pgwin32_IsInstalled(SC_HANDLE hSCM)
923 SC_HANDLE hService = OpenService(hSCM, register_servicename, SERVICE_QUERY_CONFIG);
924 bool bResult = (hService != NULL);
927 CloseServiceHandle(hService);
932 pgwin32_CommandLine(bool registration)
934 static char cmdLine[MAXPGPATH];
943 ret = find_my_exec(argv0, cmdLine);
946 write_stderr(_("%s: could not find own program executable\n"), progname);
952 ret = find_other_exec(argv0, "postgres", PM_VERSIONSTR, cmdLine);
955 write_stderr(_("%s: could not find postgres program executable\n"), progname);
961 /* need to convert to windows path */
962 cygwin_conv_to_full_win32_path(cmdLine, buf);
963 strcpy(cmdLine, buf);
968 if (pg_strcasecmp(cmdLine + strlen(cmdLine) - 4, ".exe"))
970 /* If commandline does not end in .exe, append it */
971 strcat(cmdLine, ".exe");
973 strcat(cmdLine, " runservice -N \"");
974 strcat(cmdLine, register_servicename);
975 strcat(cmdLine, "\"");
980 strcat(cmdLine, " -D \"");
981 strcat(cmdLine, pg_data);
982 strcat(cmdLine, "\"");
986 strcat(cmdLine, " -w");
990 strcat(cmdLine, " ");
992 strcat(cmdLine, " -o \"");
993 strcat(cmdLine, post_opts);
995 strcat(cmdLine, "\"");
1002 pgwin32_doRegister(void)
1005 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1009 write_stderr(_("%s: could not open service manager\n"), progname);
1012 if (pgwin32_IsInstalled(hSCM))
1014 CloseServiceHandle(hSCM);
1015 write_stderr(_("%s: service \"%s\" already registered\n"), progname, register_servicename);
1019 if ((hService = CreateService(hSCM, register_servicename, register_servicename,
1020 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
1021 SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
1022 pgwin32_CommandLine(true),
1023 NULL, NULL, "RPCSS\0", register_username, register_password)) == NULL)
1025 CloseServiceHandle(hSCM);
1026 write_stderr(_("%s: could not register service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1029 CloseServiceHandle(hService);
1030 CloseServiceHandle(hSCM);
1034 pgwin32_doUnregister(void)
1037 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1041 write_stderr(_("%s: could not open service manager\n"), progname);
1044 if (!pgwin32_IsInstalled(hSCM))
1046 CloseServiceHandle(hSCM);
1047 write_stderr(_("%s: service \"%s\" not registered\n"), progname, register_servicename);
1051 if ((hService = OpenService(hSCM, register_servicename, DELETE)) == NULL)
1053 CloseServiceHandle(hSCM);
1054 write_stderr(_("%s: could not open service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1057 if (!DeleteService(hService))
1059 CloseServiceHandle(hService);
1060 CloseServiceHandle(hSCM);
1061 write_stderr(_("%s: could not unregister service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1064 CloseServiceHandle(hService);
1065 CloseServiceHandle(hSCM);
1069 static SERVICE_STATUS status;
1070 static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
1071 static HANDLE shutdownHandles[2];
1072 static pid_t postmasterPID = -1;
1074 #define shutdownEvent shutdownHandles[0]
1075 #define postmasterProcess shutdownHandles[1]
1078 pgwin32_SetServiceStatus(DWORD currentState)
1080 status.dwCurrentState = currentState;
1081 SetServiceStatus(hStatus, (LPSERVICE_STATUS) & status);
1085 pgwin32_ServiceHandler(DWORD request)
1089 case SERVICE_CONTROL_STOP:
1090 case SERVICE_CONTROL_SHUTDOWN:
1093 * We only need a short wait hint here as it just needs to wait
1094 * for the next checkpoint. They occur every 5 seconds during
1097 status.dwWaitHint = 10000;
1098 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1099 SetEvent(shutdownEvent);
1102 case SERVICE_CONTROL_PAUSE:
1103 /* Win32 config reloading */
1104 status.dwWaitHint = 5000;
1105 kill(postmasterPID, SIGHUP);
1108 /* FIXME: These could be used to replace other signals etc */
1109 case SERVICE_CONTROL_CONTINUE:
1110 case SERVICE_CONTROL_INTERROGATE:
1117 pgwin32_ServiceMain(DWORD argc, LPTSTR * argv)
1119 PROCESS_INFORMATION pi;
1122 /* Initialize variables */
1123 status.dwWin32ExitCode = S_OK;
1124 status.dwCheckPoint = 0;
1125 status.dwWaitHint = 60000;
1126 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
1127 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
1128 status.dwServiceSpecificExitCode = 0;
1129 status.dwCurrentState = SERVICE_START_PENDING;
1131 memset(&pi, 0, sizeof(pi));
1133 /* Register the control request handler */
1134 if ((hStatus = RegisterServiceCtrlHandler(register_servicename, pgwin32_ServiceHandler)) == (SERVICE_STATUS_HANDLE) 0)
1137 if ((shutdownEvent = CreateEvent(NULL, true, false, NULL)) == NULL)
1140 /* Start the postmaster */
1141 pgwin32_SetServiceStatus(SERVICE_START_PENDING);
1142 if (!CreateRestrictedProcess(pgwin32_CommandLine(false), &pi))
1144 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1147 postmasterPID = pi.dwProcessId;
1148 postmasterProcess = pi.hProcess;
1149 CloseHandle(pi.hThread);
1150 pgwin32_SetServiceStatus(SERVICE_RUNNING);
1152 /* Wait for quit... */
1153 ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);
1154 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1157 case WAIT_OBJECT_0: /* shutdown event */
1158 kill(postmasterPID, SIGINT);
1161 * Increment the checkpoint and try again Abort after 12
1162 * checkpoints as the postmaster has probably hung
1164 while (WaitForSingleObject(postmasterProcess, 5000) == WAIT_TIMEOUT && status.dwCheckPoint < 12)
1165 status.dwCheckPoint++;
1168 case (WAIT_OBJECT_0 + 1): /* postmaster went down */
1172 /* shouldn't get here? */
1176 CloseHandle(shutdownEvent);
1177 CloseHandle(postmasterProcess);
1179 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1183 pgwin32_doRunAsService(void)
1185 SERVICE_TABLE_ENTRY st[] = {{register_servicename, pgwin32_ServiceMain},
1188 if (StartServiceCtrlDispatcher(st) == 0)
1190 write_stderr(_("%s: could not start service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());
1197 * Mingw headers are incomplete, and so are the libraries. So we have to load
1198 * a whole lot of API functions dynamically. Since we have to do this anyway,
1199 * also load the couple of functions that *do* exist in minwg headers but not
1200 * on NT4. That way, we don't break on NT4.
1202 typedef BOOL(WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
1203 typedef BOOL(WINAPI * __IsProcessInJob) (HANDLE, HANDLE, PBOOL);
1204 typedef HANDLE(WINAPI * __CreateJobObject) (LPSECURITY_ATTRIBUTES, LPCTSTR);
1205 typedef BOOL(WINAPI * __SetInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD);
1206 typedef BOOL(WINAPI * __AssignProcessToJobObject) (HANDLE, HANDLE);
1207 typedef BOOL(WINAPI * __QueryInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD);
1209 /* Windows API define missing from MingW headers */
1210 #define DISABLE_MAX_PRIVILEGE 0x1
1213 * Create a restricted token, a job object sandbox, and execute the specified
1216 * Returns 0 on success, non-zero on failure, same as CreateProcess().
1218 * On NT4, or any other system not containing the required functions, will
1219 * launch the process under the current token without doing any modifications.
1221 * NOTE! Job object will only work when running as a service, because it's
1222 * automatically destroyed when pg_ctl exits.
1225 CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION * processInfo)
1231 HANDLE restrictedToken;
1232 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
1233 SID_AND_ATTRIBUTES dropSids[2];
1235 /* Functions loaded dynamically */
1236 __CreateRestrictedToken _CreateRestrictedToken = NULL;
1237 __IsProcessInJob _IsProcessInJob = NULL;
1238 __CreateJobObject _CreateJobObject = NULL;
1239 __SetInformationJobObject _SetInformationJobObject = NULL;
1240 __AssignProcessToJobObject _AssignProcessToJobObject = NULL;
1241 __QueryInformationJobObject _QueryInformationJobObject = NULL;
1242 HANDLE Kernel32Handle;
1243 HANDLE Advapi32Handle;
1245 ZeroMemory(&si, sizeof(si));
1248 Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
1249 if (Advapi32Handle != NULL)
1251 _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
1254 if (_CreateRestrictedToken == NULL)
1257 * NT4 doesn't have CreateRestrictedToken, so just call ordinary
1260 write_stderr("WARNING: cannot create restricted tokens on this platform\n");
1261 if (Advapi32Handle != NULL)
1262 FreeLibrary(Advapi32Handle);
1263 return CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, processInfo);
1266 /* Open the current token to use as a base for the restricted one */
1267 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
1269 write_stderr("Failed to open process token: %lu\n", GetLastError());
1273 /* Allocate list of SIDs to remove */
1274 ZeroMemory(&dropSids, sizeof(dropSids));
1275 if (!AllocateAndInitializeSid(&NtAuthority, 2,
1276 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
1277 0, &dropSids[0].Sid) ||
1278 !AllocateAndInitializeSid(&NtAuthority, 2,
1279 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
1280 0, &dropSids[1].Sid))
1282 write_stderr("Failed to allocate SIDs: %lu\n", GetLastError());
1286 b = _CreateRestrictedToken(origToken,
1287 DISABLE_MAX_PRIVILEGE,
1288 sizeof(dropSids) / sizeof(dropSids[0]),
1294 FreeSid(dropSids[1].Sid);
1295 FreeSid(dropSids[0].Sid);
1296 CloseHandle(origToken);
1297 FreeLibrary(Advapi32Handle);
1301 write_stderr("Failed to create restricted token: %lu\n", GetLastError());
1305 r = CreateProcessAsUser(restrictedToken, NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, processInfo);
1307 Kernel32Handle = LoadLibrary("KERNEL32.DLL");
1308 if (Kernel32Handle != NULL)
1310 _IsProcessInJob = (__IsProcessInJob) GetProcAddress(Kernel32Handle, "IsProcessInJob");
1311 _CreateJobObject = (__CreateJobObject) GetProcAddress(Kernel32Handle, "CreateJobObjectA");
1312 _SetInformationJobObject = (__SetInformationJobObject) GetProcAddress(Kernel32Handle, "SetInformationJobObject");
1313 _AssignProcessToJobObject = (__AssignProcessToJobObject) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject");
1314 _QueryInformationJobObject = (__QueryInformationJobObject) GetProcAddress(Kernel32Handle, "QueryInformationJobObject");
1317 /* Verify that we found all functions */
1318 if (_IsProcessInJob == NULL || _CreateJobObject == NULL || _SetInformationJobObject == NULL || _AssignProcessToJobObject == NULL || _QueryInformationJobObject == NULL)
1321 * IsProcessInJob() is not available on < WinXP, so there is no need
1322 * to log the error every time in that case
1326 osv.dwOSVersionInfoSize = sizeof(osv);
1327 if (!GetVersionEx(&osv) || /* could not get version */
1328 (osv.dwMajorVersion == 5 && osv.dwMinorVersion > 0) || /* 5.1=xp, 5.2=2003, etc */
1329 osv.dwMajorVersion > 5) /* anything newer should have the API */
1332 * Log error if we can't get version, or if we're on WinXP/2003 or
1335 write_stderr("WARNING: could not locate all job object functions in system API\n");
1341 if (_IsProcessInJob(processInfo->hProcess, NULL, &inJob))
1346 * Job objects are working, and the new process isn't in one,
1347 * so we can create one safely. If any problems show up when
1348 * setting it, we're going to ignore them.
1353 sprintf(jobname, "PostgreSQL_%lu", processInfo->dwProcessId);
1355 job = _CreateJobObject(NULL, jobname);
1358 JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
1359 JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
1360 JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
1362 ZeroMemory(&basicLimit, sizeof(basicLimit));
1363 ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
1364 ZeroMemory(&securityLimit, sizeof(securityLimit));
1366 basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
1367 basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
1368 _SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));
1370 uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
1371 JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_HANDLES | JOB_OBJECT_UILIMIT_READCLIPBOARD |
1372 JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
1373 _SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));
1375 securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
1376 securityLimit.JobToken = restrictedToken;
1377 _SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));
1379 _AssignProcessToJobObject(job, processInfo->hProcess);
1385 CloseHandle(restrictedToken);
1387 ResumeThread(processInfo->hThread);
1389 FreeLibrary(Kernel32Handle);
1392 * We intentionally don't close the job object handle, because we want the
1393 * object to live on until pg_ctl shuts down.
1402 write_stderr(_("Try \"%s --help\" for more information.\n"), progname);
1410 printf(_("%s is a utility to start, stop, restart, reload configuration files,\n"
1411 "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n\n"), progname);
1412 printf(_("Usage:\n"));
1413 printf(_(" %s start [-w] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n"), progname);
1414 printf(_(" %s stop [-W] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"), progname);
1415 printf(_(" %s restart [-w] [-D DATADIR] [-s] [-m SHUTDOWN-MODE] [-o \"OPTIONS\"]\n"), progname);
1416 printf(_(" %s reload [-D DATADIR] [-s]\n"), progname);
1417 printf(_(" %s status [-D DATADIR]\n"), progname);
1418 printf(_(" %s kill SIGNALNAME PID\n"), progname);
1419 #if defined(WIN32) || defined(__CYGWIN__)
1420 printf(_(" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n"
1421 " [-w] [-o \"OPTIONS\"]\n"), progname);
1422 printf(_(" %s unregister [-N SERVICENAME]\n"), progname);
1425 printf(_("\nCommon options:\n"));
1426 printf(_(" -D, --pgdata DATADIR location of the database storage area\n"));
1427 printf(_(" -s, --silent only print errors, no informational messages\n"));
1428 printf(_(" -w wait until operation completes\n"));
1429 printf(_(" -W do not wait until operation completes\n"));
1430 printf(_(" --help show this help, then exit\n"));
1431 printf(_(" --version output version information, then exit\n"));
1432 printf(_("(The default is to wait for shutdown, but not for start or restart.)\n\n"));
1433 printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
1435 printf(_("\nOptions for start or restart:\n"));
1436 printf(_(" -l, --log FILENAME write (or append) server log to FILENAME\n"));
1437 printf(_(" -o OPTIONS command line options to pass to postgres\n"
1438 " (PostgreSQL server executable)\n"));
1439 printf(_(" -p PATH-TO-POSTGRES normally not necessary\n"));
1440 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
1441 printf(_(" -c, --core-files allow postgres to produce core files\n"));
1443 printf(_(" -c, --core-files not applicable on this platform\n"));
1445 printf(_("\nOptions for stop or restart:\n"));
1446 printf(_(" -m SHUTDOWN-MODE can be \"smart\", \"fast\", or \"immediate\"\n"));
1448 printf(_("\nShutdown modes are:\n"));
1449 printf(_(" smart quit after all clients have disconnected\n"));
1450 printf(_(" fast quit directly, with proper shutdown\n"));
1451 printf(_(" immediate quit without complete shutdown; will lead to recovery on restart\n"));
1453 printf(_("\nAllowed signal names for kill:\n"));
1454 printf(" HUP INT QUIT ABRT TERM USR1 USR2\n");
1456 #if defined(WIN32) || defined(__CYGWIN__)
1457 printf(_("\nOptions for register and unregister:\n"));
1458 printf(_(" -N SERVICENAME service name with which to register PostgreSQL server\n"));
1459 printf(_(" -P PASSWORD password of account to register PostgreSQL server\n"));
1460 printf(_(" -U USERNAME user name of account to register PostgreSQL server\n"));
1463 printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
1469 set_mode(char *modeopt)
1471 if (strcmp(modeopt, "s") == 0 || strcmp(modeopt, "smart") == 0)
1473 shutdown_mode = SMART_MODE;
1476 else if (strcmp(modeopt, "f") == 0 || strcmp(modeopt, "fast") == 0)
1478 shutdown_mode = FAST_MODE;
1481 else if (strcmp(modeopt, "i") == 0 || strcmp(modeopt, "immediate") == 0)
1483 shutdown_mode = IMMEDIATE_MODE;
1488 write_stderr(_("%s: unrecognized shutdown mode \"%s\"\n"), progname, modeopt);
1497 set_sig(char *signame)
1499 if (!strcmp(signame, "HUP"))
1501 else if (!strcmp(signame, "INT"))
1503 else if (!strcmp(signame, "QUIT"))
1505 else if (!strcmp(signame, "ABRT"))
1509 * probably should NOT provide SIGKILL
1511 * else if (!strcmp(signame,"KILL")) sig = SIGKILL;
1513 else if (!strcmp(signame, "TERM"))
1515 else if (!strcmp(signame, "USR1"))
1517 else if (!strcmp(signame, "USR2"))
1521 write_stderr(_("%s: unrecognized signal name \"%s\"\n"), progname, signame);
1531 main(int argc, char **argv)
1533 static struct option long_options[] = {
1534 {"help", no_argument, NULL, '?'},
1535 {"version", no_argument, NULL, 'V'},
1536 {"log", required_argument, NULL, 'l'},
1537 {"mode", required_argument, NULL, 'm'},
1538 {"pgdata", required_argument, NULL, 'D'},
1539 {"silent", no_argument, NULL, 's'},
1540 {"core-files", no_argument, NULL, 'c'},
1546 pgpid_t killproc = 0;
1548 #if defined(WIN32) || defined(__CYGWIN__)
1549 setvbuf(stderr, NULL, _IONBF, 0);
1552 progname = get_progname(argv[0]);
1553 set_pglocale_pgservice(argv[0], "pg_ctl");
1556 * save argv[0] so do_start() can look for the postmaster if necessary. we
1557 * don't look for postmaster here because in many cases we won't need it.
1563 /* support --help and --version even if invoked as root */
1566 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 ||
1567 strcmp(argv[1], "-?") == 0)
1572 else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0)
1574 puts("pg_ctl (PostgreSQL) " PG_VERSION);
1580 * Disallow running as root, to forestall any possible security holes.
1585 write_stderr(_("%s: cannot be run as root\n"
1586 "Please log in (using, e.g., \"su\") as the "
1587 "(unprivileged) user that will\n"
1588 "own the server process.\n"),
1595 * 'Action' can be before or after args so loop over both. Some
1596 * getopt_long() implementations will reorder argv[] to place all flags
1597 * first (GNU?), but we don't rely on it. Our /port version doesn't do
1602 /* process command-line options */
1603 while (optind < argc)
1605 while ((c = getopt_long(argc, argv, "cD:l:m:N:o:p:P:sU:wW", long_options, &option_index)) != -1)
1612 char *env_var = pg_malloc(strlen(optarg) + 8);
1614 pgdata_D = xstrdup(optarg);
1615 canonicalize_path(pgdata_D);
1616 snprintf(env_var, strlen(optarg) + 8, "PGDATA=%s",
1621 * We could pass PGDATA just in an environment
1622 * variable but we do -D too for clearer postmaster
1625 pgdata_opt = pg_malloc(strlen(pgdata_D) + 7);
1626 snprintf(pgdata_opt, strlen(pgdata_D) + 7,
1632 log_file = xstrdup(optarg);
1638 register_servicename = xstrdup(optarg);
1641 post_opts = xstrdup(optarg);
1644 postgres_path = xstrdup(optarg);
1647 register_password = xstrdup(optarg);
1653 if (strchr(optarg, '\\'))
1654 register_username = xstrdup(optarg);
1656 /* Prepend .\ for local accounts */
1658 register_username = malloc(strlen(optarg) + 3);
1659 if (!register_username)
1661 write_stderr(_("%s: out of memory\n"), progname);
1664 strcpy(register_username, ".\\");
1665 strcat(register_username, optarg);
1677 allow_core_files = true;
1680 /* getopt_long already issued a suitable error message */
1686 /* Process an action */
1689 if (ctl_command != NO_COMMAND)
1691 write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]);
1696 if (strcmp(argv[optind], "start") == 0)
1697 ctl_command = START_COMMAND;
1698 else if (strcmp(argv[optind], "stop") == 0)
1699 ctl_command = STOP_COMMAND;
1700 else if (strcmp(argv[optind], "restart") == 0)
1701 ctl_command = RESTART_COMMAND;
1702 else if (strcmp(argv[optind], "reload") == 0)
1703 ctl_command = RELOAD_COMMAND;
1704 else if (strcmp(argv[optind], "status") == 0)
1705 ctl_command = STATUS_COMMAND;
1706 else if (strcmp(argv[optind], "kill") == 0)
1708 if (argc - optind < 3)
1710 write_stderr(_("%s: missing arguments for kill mode\n"), progname);
1714 ctl_command = KILL_COMMAND;
1715 set_sig(argv[++optind]);
1716 killproc = atol(argv[++optind]);
1718 #if defined(WIN32) || defined(__CYGWIN__)
1719 else if (strcmp(argv[optind], "register") == 0)
1720 ctl_command = REGISTER_COMMAND;
1721 else if (strcmp(argv[optind], "unregister") == 0)
1722 ctl_command = UNREGISTER_COMMAND;
1723 else if (strcmp(argv[optind], "runservice") == 0)
1724 ctl_command = RUN_AS_SERVICE_COMMAND;
1728 write_stderr(_("%s: unrecognized operation mode \"%s\"\n"), progname, argv[optind]);
1736 if (ctl_command == NO_COMMAND)
1738 write_stderr(_("%s: no operation specified\n"), progname);
1743 /* Note we put any -D switch into the env var above */
1744 pg_data = getenv("PGDATA");
1747 pg_data = xstrdup(pg_data);
1748 canonicalize_path(pg_data);
1751 if (pg_data == NULL &&
1752 ctl_command != KILL_COMMAND && ctl_command != UNREGISTER_COMMAND)
1754 write_stderr(_("%s: no database directory specified "
1755 "and environment variable PGDATA unset\n"),
1763 switch (ctl_command)
1765 case RESTART_COMMAND:
1777 if (ctl_command == RELOAD_COMMAND)
1785 snprintf(def_postopts_file, MAXPGPATH, "%s/postmaster.opts.default", pg_data);
1786 snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);
1787 snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
1788 snprintf(conf_file, MAXPGPATH, "%s/postgresql.conf", pg_data);
1791 switch (ctl_command)
1793 case STATUS_COMMAND:
1802 case RESTART_COMMAND:
1805 case RELOAD_COMMAND:
1811 #if defined(WIN32) || defined(__CYGWIN__)
1812 case REGISTER_COMMAND:
1813 pgwin32_doRegister();
1815 case UNREGISTER_COMMAND:
1816 pgwin32_doUnregister();
1818 case RUN_AS_SERVICE_COMMAND:
1819 pgwin32_doRunAsService();