1 /*-------------------------------------------------------------------------
2 *
3 * pg_ctl --- start/stops/restarts the PostgreSQL server
4 *
5 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
6 *
7 * src/bin/pg_ctl/pg_ctl.c
8 *
9 *-------------------------------------------------------------------------
10 */
11
12 #include "postgres_fe.h"
13
14 #include <fcntl.h>
15 #include <signal.h>
16 #include <time.h>
17 #include <sys/stat.h>
18 #include <sys/wait.h>
19 #include <unistd.h>
20
21 #ifdef HAVE_SYS_RESOURCE_H
22 #include <sys/time.h>
23 #include <sys/resource.h>
24 #endif
25
26 #include "catalog/pg_control.h"
27 #include "common/controldata_utils.h"
28 #include "common/file_perm.h"
29 #include "common/logging.h"
30 #include "getopt_long.h"
31 #include "utils/pidfile.h"
32
33 #ifdef WIN32 /* on Unix, we don't need libpq */
34 #include "pqexpbuffer.h"
35 #endif
36
37 /* PID can be negative for standalone backend */
38 typedef long pgpid_t;
39
40
41 typedef enum
42 {
43 SMART_MODE,
44 FAST_MODE,
45 IMMEDIATE_MODE
46 } ShutdownMode;
47
48 typedef enum
49 {
50 POSTMASTER_READY,
51 POSTMASTER_STILL_STARTING,
52 POSTMASTER_FAILED
53 } WaitPMResult;
54
55 typedef enum
56 {
57 NO_COMMAND = 0,
58 INIT_COMMAND,
59 START_COMMAND,
60 STOP_COMMAND,
61 RESTART_COMMAND,
62 RELOAD_COMMAND,
63 STATUS_COMMAND,
64 PROMOTE_COMMAND,
65 LOGROTATE_COMMAND,
66 KILL_COMMAND,
67 REGISTER_COMMAND,
68 UNREGISTER_COMMAND,
69 RUN_AS_SERVICE_COMMAND
70 } CtlCommand;
71
72 #define DEFAULT_WAIT 60
73
74 #define USEC_PER_SEC 1000000
75
76 #define WAITS_PER_SEC 10 /* should divide USEC_PER_SEC evenly */
77
78 static bool do_wait = true;
79 static int wait_seconds = DEFAULT_WAIT;
80 static bool wait_seconds_arg = false;
81 static bool silent_mode = false;
82 static ShutdownMode shutdown_mode = FAST_MODE;
83 static int sig = SIGINT; /* default */
84 static CtlCommand ctl_command = NO_COMMAND;
85 static char *pg_data = NULL;
86 static char *pg_config = NULL;
87 static char *pgdata_opt = NULL;
88 static char *post_opts = NULL;
89 static const char *progname;
90 static char *log_file = NULL;
91 static char *exec_path = NULL;
92 static char *event_source = NULL;
93 static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
94 static char *register_username = NULL;
95 static char *register_password = NULL;
96 static char *argv0 = NULL;
97 static bool allow_core_files = false;
98 static time_t start_time;
99
100 static char postopts_file[MAXPGPATH];
101 static char version_file[MAXPGPATH];
102 static char pid_file[MAXPGPATH];
103 static char backup_file[MAXPGPATH];
104 static char promote_file[MAXPGPATH];
105 static char logrotate_file[MAXPGPATH];
106
107 static volatile pgpid_t postmasterPID = -1;
108
109 #ifdef WIN32
110 static DWORD pgctl_start_type = SERVICE_AUTO_START;
111 static SERVICE_STATUS status;
112 static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
113 static HANDLE shutdownHandles[2];
114
115 #define shutdownEvent shutdownHandles[0]
116 #define postmasterProcess shutdownHandles[1]
117 #endif
118
119
120 static void write_stderr(const char *fmt,...) pg_attribute_printf(1, 2);
121 static void do_advice(void);
122 static void do_help(void);
123 static void set_mode(char *modeopt);
124 static void set_sig(char *signame);
125 static void do_init(void);
126 static void do_start(void);
127 static void do_stop(void);
128 static void do_restart(void);
129 static void do_reload(void);
130 static void do_status(void);
131 static void do_promote(void);
132 static void do_logrotate(void);
133 static void do_kill(pgpid_t pid);
134 static void print_msg(const char *msg);
135 static void adjust_data_dir(void);
136
137 #ifdef WIN32
138 #if (_MSC_VER >= 1800)
139 #include <versionhelpers.h>
140 #else
141 static bool IsWindowsXPOrGreater(void);
142 static bool IsWindows7OrGreater(void);
143 #endif
144 static bool pgwin32_IsInstalled(SC_HANDLE);
145 static char *pgwin32_CommandLine(bool);
146 static void pgwin32_doRegister(void);
147 static void pgwin32_doUnregister(void);
148 static void pgwin32_SetServiceStatus(DWORD);
149 static void WINAPI pgwin32_ServiceHandler(DWORD);
150 static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
151 static void pgwin32_doRunAsService(void);
152 static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service);
153 static PTOKEN_PRIVILEGES GetPrivilegesToDelete(HANDLE hToken);
154 #endif
155
156 static pgpid_t get_pgpid(bool is_status_request);
157 static char **readfile(const char *path, int *numlines);
158 static void free_readfile(char **optlines);
159 static pgpid_t start_postmaster(void);
160 static void read_post_opts(void);
161
162 static WaitPMResult wait_for_postmaster(pgpid_t pm_pid, bool do_checkpoint);
163 static bool postmaster_is_alive(pid_t pid);
164
165 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
166 static void unlimit_core_size(void);
167 #endif
168
169 static DBState get_control_dbstate(void);
170
171
172 #ifdef WIN32
173 static void
write_eventlog(int level,const char * line)174 write_eventlog(int level, const char *line)
175 {
176 static HANDLE evtHandle = INVALID_HANDLE_VALUE;
177
178 if (silent_mode && level == EVENTLOG_INFORMATION_TYPE)
179 return;
180
181 if (evtHandle == INVALID_HANDLE_VALUE)
182 {
183 evtHandle = RegisterEventSource(NULL,
184 event_source ? event_source : DEFAULT_EVENT_SOURCE);
185 if (evtHandle == NULL)
186 {
187 evtHandle = INVALID_HANDLE_VALUE;
188 return;
189 }
190 }
191
192 ReportEvent(evtHandle,
193 level,
194 0,
195 0, /* All events are Id 0 */
196 NULL,
197 1,
198 0,
199 &line,
200 NULL);
201 }
202 #endif
203
204 /*
205 * Write errors to stderr (or by equal means when stderr is
206 * not available).
207 */
208 static void
write_stderr(const char * fmt,...)209 write_stderr(const char *fmt,...)
210 {
211 va_list ap;
212
213 va_start(ap, fmt);
214 #ifndef WIN32
215 /* On Unix, we just fprintf to stderr */
216 vfprintf(stderr, fmt, ap);
217 #else
218
219 /*
220 * On Win32, we print to stderr if running on a console, or write to
221 * eventlog if running as a service
222 */
223 if (pgwin32_is_service()) /* Running as a service */
224 {
225 char errbuf[2048]; /* Arbitrary size? */
226
227 vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
228
229 write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
230 }
231 else
232 /* Not running as service, write to stderr */
233 vfprintf(stderr, fmt, ap);
234 #endif
235 va_end(ap);
236 }
237
238 /*
239 * Given an already-localized string, print it to stdout unless the
240 * user has specified that no messages should be printed.
241 */
242 static void
print_msg(const char * msg)243 print_msg(const char *msg)
244 {
245 if (!silent_mode)
246 {
247 fputs(msg, stdout);
248 fflush(stdout);
249 }
250 }
251
252 static pgpid_t
get_pgpid(bool is_status_request)253 get_pgpid(bool is_status_request)
254 {
255 FILE *pidf;
256 long pid;
257 struct stat statbuf;
258
259 if (stat(pg_data, &statbuf) != 0)
260 {
261 if (errno == ENOENT)
262 write_stderr(_("%s: directory \"%s\" does not exist\n"), progname,
263 pg_data);
264 else
265 write_stderr(_("%s: could not access directory \"%s\": %s\n"), progname,
266 pg_data, strerror(errno));
267
268 /*
269 * The Linux Standard Base Core Specification 3.1 says this should
270 * return '4, program or service status is unknown'
271 * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
272 */
273 exit(is_status_request ? 4 : 1);
274 }
275
276 if (stat(version_file, &statbuf) != 0 && errno == ENOENT)
277 {
278 write_stderr(_("%s: directory \"%s\" is not a database cluster directory\n"),
279 progname, pg_data);
280 exit(is_status_request ? 4 : 1);
281 }
282
283 pidf = fopen(pid_file, "r");
284 if (pidf == NULL)
285 {
286 /* No pid file, not an error on startup */
287 if (errno == ENOENT)
288 return 0;
289 else
290 {
291 write_stderr(_("%s: could not open PID file \"%s\": %s\n"),
292 progname, pid_file, strerror(errno));
293 exit(1);
294 }
295 }
296 if (fscanf(pidf, "%ld", &pid) != 1)
297 {
298 /* Is the file empty? */
299 if (ftell(pidf) == 0 && feof(pidf))
300 write_stderr(_("%s: the PID file \"%s\" is empty\n"),
301 progname, pid_file);
302 else
303 write_stderr(_("%s: invalid data in PID file \"%s\"\n"),
304 progname, pid_file);
305 exit(1);
306 }
307 fclose(pidf);
308 return (pgpid_t) pid;
309 }
310
311
312 /*
313 * get the lines from a text file - return NULL if file can't be opened
314 *
315 * Trailing newlines are deleted from the lines (this is a change from pre-v10)
316 *
317 * *numlines is set to the number of line pointers returned; there is
318 * also an additional NULL pointer after the last real line.
319 */
320 static char **
readfile(const char * path,int * numlines)321 readfile(const char *path, int *numlines)
322 {
323 int fd;
324 int nlines;
325 char **result;
326 char *buffer;
327 char *linebegin;
328 int i;
329 int n;
330 int len;
331 struct stat statbuf;
332
333 *numlines = 0; /* in case of failure or empty file */
334
335 /*
336 * Slurp the file into memory.
337 *
338 * The file can change concurrently, so we read the whole file into memory
339 * with a single read() call. That's not guaranteed to get an atomic
340 * snapshot, but in practice, for a small file, it's close enough for the
341 * current use.
342 */
343 fd = open(path, O_RDONLY | PG_BINARY, 0);
344 if (fd < 0)
345 return NULL;
346 if (fstat(fd, &statbuf) < 0)
347 {
348 close(fd);
349 return NULL;
350 }
351 if (statbuf.st_size == 0)
352 {
353 /* empty file */
354 close(fd);
355 result = (char **) pg_malloc(sizeof(char *));
356 *result = NULL;
357 return result;
358 }
359 buffer = pg_malloc(statbuf.st_size + 1);
360
361 len = read(fd, buffer, statbuf.st_size + 1);
362 close(fd);
363 if (len != statbuf.st_size)
364 {
365 /* oops, the file size changed between fstat and read */
366 free(buffer);
367 return NULL;
368 }
369
370 /*
371 * Count newlines. We expect there to be a newline after each full line,
372 * including one at the end of file. If there isn't a newline at the end,
373 * any characters after the last newline will be ignored.
374 */
375 nlines = 0;
376 for (i = 0; i < len; i++)
377 {
378 if (buffer[i] == '\n')
379 nlines++;
380 }
381
382 /* set up the result buffer */
383 result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
384 *numlines = nlines;
385
386 /* now split the buffer into lines */
387 linebegin = buffer;
388 n = 0;
389 for (i = 0; i < len; i++)
390 {
391 if (buffer[i] == '\n')
392 {
393 int slen = &buffer[i] - linebegin;
394 char *linebuf = pg_malloc(slen + 1);
395
396 memcpy(linebuf, linebegin, slen);
397 /* we already dropped the \n, but get rid of any \r too */
398 if (slen > 0 && linebuf[slen - 1] == '\r')
399 slen--;
400 linebuf[slen] = '\0';
401 result[n++] = linebuf;
402 linebegin = &buffer[i + 1];
403 }
404 }
405 result[n] = NULL;
406
407 free(buffer);
408
409 return result;
410 }
411
412
413 /*
414 * Free memory allocated for optlines through readfile()
415 */
416 static void
free_readfile(char ** optlines)417 free_readfile(char **optlines)
418 {
419 char *curr_line = NULL;
420 int i = 0;
421
422 if (!optlines)
423 return;
424
425 while ((curr_line = optlines[i++]))
426 free(curr_line);
427
428 free(optlines);
429
430 return;
431 }
432
433 /*
434 * start/test/stop routines
435 */
436
437 /*
438 * Start the postmaster and return its PID.
439 *
440 * Currently, on Windows what we return is the PID of the shell process
441 * that launched the postmaster (and, we trust, is waiting for it to exit).
442 * So the PID is usable for "is the postmaster still running" checks,
443 * but cannot be compared directly to postmaster.pid.
444 *
445 * On Windows, we also save aside a handle to the shell process in
446 * "postmasterProcess", which the caller should close when done with it.
447 */
448 static pgpid_t
start_postmaster(void)449 start_postmaster(void)
450 {
451 char *cmd;
452
453 #ifndef WIN32
454 pgpid_t pm_pid;
455
456 /* Flush stdio channels just before fork, to avoid double-output problems */
457 fflush(stdout);
458 fflush(stderr);
459
460 pm_pid = fork();
461 if (pm_pid < 0)
462 {
463 /* fork failed */
464 write_stderr(_("%s: could not start server: %s\n"),
465 progname, strerror(errno));
466 exit(1);
467 }
468 if (pm_pid > 0)
469 {
470 /* fork succeeded, in parent */
471 return pm_pid;
472 }
473
474 /* fork succeeded, in child */
475
476 /*
477 * If possible, detach the postmaster process from the launching process
478 * group and make it a group leader, so that it doesn't get signaled along
479 * with the current group that launched it.
480 */
481 #ifdef HAVE_SETSID
482 if (setsid() < 0)
483 {
484 write_stderr(_("%s: could not start server due to setsid() failure: %s\n"),
485 progname, strerror(errno));
486 exit(1);
487 }
488 #endif
489
490 /*
491 * Since there might be quotes to handle here, it is easier simply to pass
492 * everything to a shell to process them. Use exec so that the postmaster
493 * has the same PID as the current child process.
494 */
495 if (log_file != NULL)
496 cmd = psprintf("exec \"%s\" %s%s < \"%s\" >> \"%s\" 2>&1",
497 exec_path, pgdata_opt, post_opts,
498 DEVNULL, log_file);
499 else
500 cmd = psprintf("exec \"%s\" %s%s < \"%s\" 2>&1",
501 exec_path, pgdata_opt, post_opts, DEVNULL);
502
503 (void) execl("/bin/sh", "/bin/sh", "-c", cmd, (char *) NULL);
504
505 /* exec failed */
506 write_stderr(_("%s: could not start server: %s\n"),
507 progname, strerror(errno));
508 exit(1);
509
510 return 0; /* keep dumb compilers quiet */
511
512 #else /* WIN32 */
513
514 /*
515 * As with the Unix case, it's easiest to use the shell (CMD.EXE) to
516 * handle redirection etc. Unfortunately CMD.EXE lacks any equivalent of
517 * "exec", so we don't get to find out the postmaster's PID immediately.
518 */
519 PROCESS_INFORMATION pi;
520
521 if (log_file != NULL)
522 {
523 /*
524 * First, open the log file if it exists. The idea is that if the
525 * file is still locked by a previous postmaster run, we'll wait until
526 * it comes free, instead of failing with ERROR_SHARING_VIOLATION.
527 * (It'd be better to open the file in a sharing-friendly mode, but we
528 * can't use CMD.EXE to do that, so work around it. Note that the
529 * previous postmaster will still have the file open for a short time
530 * after removing postmaster.pid.)
531 *
532 * If the log file doesn't exist, we *must not* create it here. If we
533 * were launched with higher privileges than the restricted process
534 * will have, the log file might end up with permissions settings that
535 * prevent the postmaster from writing on it.
536 */
537 int fd = open(log_file, O_RDWR, 0);
538
539 if (fd == -1)
540 {
541 /*
542 * ENOENT is expectable since we didn't use O_CREAT. Otherwise
543 * complain. We could just fall through and let CMD.EXE report
544 * the problem, but its error reporting is pretty miserable.
545 */
546 if (errno != ENOENT)
547 {
548 write_stderr(_("%s: could not open log file \"%s\": %s\n"),
549 progname, log_file, strerror(errno));
550 exit(1);
551 }
552 }
553 else
554 close(fd);
555
556 cmd = psprintf("CMD /C \"\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1\"",
557 exec_path, pgdata_opt, post_opts, DEVNULL, log_file);
558 }
559 else
560 cmd = psprintf("CMD /C \"\"%s\" %s%s < \"%s\" 2>&1\"",
561 exec_path, pgdata_opt, post_opts, DEVNULL);
562
563 if (!CreateRestrictedProcess(cmd, &pi, false))
564 {
565 write_stderr(_("%s: could not start server: error code %lu\n"),
566 progname, (unsigned long) GetLastError());
567 exit(1);
568 }
569 /* Don't close command process handle here; caller must do so */
570 postmasterProcess = pi.hProcess;
571 CloseHandle(pi.hThread);
572 return pi.dwProcessId; /* Shell's PID, not postmaster's! */
573 #endif /* WIN32 */
574 }
575
576
577
578 /*
579 * Wait for the postmaster to become ready.
580 *
581 * On Unix, pm_pid is the PID of the just-launched postmaster. On Windows,
582 * it may be the PID of an ancestor shell process, so we can't check the
583 * contents of postmaster.pid quite as carefully.
584 *
585 * On Windows, the static variable postmasterProcess is an implicit argument
586 * to this routine; it contains a handle to the postmaster process or an
587 * ancestor shell process thereof.
588 *
589 * Note that the checkpoint parameter enables a Windows service control
590 * manager checkpoint, it's got nothing to do with database checkpoints!!
591 */
592 static WaitPMResult
wait_for_postmaster(pgpid_t pm_pid,bool do_checkpoint)593 wait_for_postmaster(pgpid_t pm_pid, bool do_checkpoint)
594 {
595 int i;
596
597 for (i = 0; i < wait_seconds * WAITS_PER_SEC; i++)
598 {
599 char **optlines;
600 int numlines;
601
602 /*
603 * Try to read the postmaster.pid file. If it's not valid, or if the
604 * status line isn't there yet, just keep waiting.
605 */
606 if ((optlines = readfile(pid_file, &numlines)) != NULL &&
607 numlines >= LOCK_FILE_LINE_PM_STATUS)
608 {
609 /* File is complete enough for us, parse it */
610 pgpid_t pmpid;
611 time_t pmstart;
612
613 /*
614 * Make sanity checks. If it's for the wrong PID, or the recorded
615 * start time is before pg_ctl started, then either we are looking
616 * at the wrong data directory, or this is a pre-existing pidfile
617 * that hasn't (yet?) been overwritten by our child postmaster.
618 * Allow 2 seconds slop for possible cross-process clock skew.
619 */
620 pmpid = atol(optlines[LOCK_FILE_LINE_PID - 1]);
621 pmstart = atol(optlines[LOCK_FILE_LINE_START_TIME - 1]);
622 if (pmstart >= start_time - 2 &&
623 #ifndef WIN32
624 pmpid == pm_pid
625 #else
626 /* Windows can only reject standalone-backend PIDs */
627 pmpid > 0
628 #endif
629 )
630 {
631 /*
632 * OK, seems to be a valid pidfile from our child. Check the
633 * status line (this assumes a v10 or later server).
634 */
635 char *pmstatus = optlines[LOCK_FILE_LINE_PM_STATUS - 1];
636
637 if (strcmp(pmstatus, PM_STATUS_READY) == 0 ||
638 strcmp(pmstatus, PM_STATUS_STANDBY) == 0)
639 {
640 /* postmaster is done starting up */
641 free_readfile(optlines);
642 return POSTMASTER_READY;
643 }
644 }
645 }
646
647 /*
648 * Free the results of readfile.
649 *
650 * This is safe to call even if optlines is NULL.
651 */
652 free_readfile(optlines);
653
654 /*
655 * Check whether the child postmaster process is still alive. This
656 * lets us exit early if the postmaster fails during startup.
657 *
658 * On Windows, we may be checking the postmaster's parent shell, but
659 * that's fine for this purpose.
660 */
661 #ifndef WIN32
662 {
663 int exitstatus;
664
665 if (waitpid((pid_t) pm_pid, &exitstatus, WNOHANG) == (pid_t) pm_pid)
666 return POSTMASTER_FAILED;
667 }
668 #else
669 if (WaitForSingleObject(postmasterProcess, 0) == WAIT_OBJECT_0)
670 return POSTMASTER_FAILED;
671 #endif
672
673 /* Startup still in process; wait, printing a dot once per second */
674 if (i % WAITS_PER_SEC == 0)
675 {
676 #ifdef WIN32
677 if (do_checkpoint)
678 {
679 /*
680 * Increment the wait hint by 6 secs (connection timeout +
681 * sleep). We must do this to indicate to the SCM that our
682 * startup time is changing, otherwise it'll usually send a
683 * stop signal after 20 seconds, despite incrementing the
684 * checkpoint counter.
685 */
686 status.dwWaitHint += 6000;
687 status.dwCheckPoint++;
688 SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
689 }
690 else
691 #endif
692 print_msg(".");
693 }
694
695 pg_usleep(USEC_PER_SEC / WAITS_PER_SEC);
696 }
697
698 /* out of patience; report that postmaster is still starting up */
699 return POSTMASTER_STILL_STARTING;
700 }
701
702
703 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
704 static void
unlimit_core_size(void)705 unlimit_core_size(void)
706 {
707 struct rlimit lim;
708
709 getrlimit(RLIMIT_CORE, &lim);
710 if (lim.rlim_max == 0)
711 {
712 write_stderr(_("%s: cannot set core file size limit; disallowed by hard limit\n"),
713 progname);
714 return;
715 }
716 else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
717 {
718 lim.rlim_cur = lim.rlim_max;
719 setrlimit(RLIMIT_CORE, &lim);
720 }
721 }
722 #endif
723
724 static void
read_post_opts(void)725 read_post_opts(void)
726 {
727 if (post_opts == NULL)
728 {
729 post_opts = ""; /* default */
730 if (ctl_command == RESTART_COMMAND)
731 {
732 char **optlines;
733 int numlines;
734
735 optlines = readfile(postopts_file, &numlines);
736 if (optlines == NULL)
737 {
738 write_stderr(_("%s: could not read file \"%s\"\n"), progname, postopts_file);
739 exit(1);
740 }
741 else if (numlines != 1)
742 {
743 write_stderr(_("%s: option file \"%s\" must have exactly one line\n"),
744 progname, postopts_file);
745 exit(1);
746 }
747 else
748 {
749 char *optline;
750 char *arg1;
751
752 optline = optlines[0];
753
754 /*
755 * Are we at the first option, as defined by space and
756 * double-quote?
757 */
758 if ((arg1 = strstr(optline, " \"")) != NULL)
759 {
760 *arg1 = '\0'; /* terminate so we get only program name */
761 post_opts = pg_strdup(arg1 + 1); /* point past whitespace */
762 }
763 if (exec_path == NULL)
764 exec_path = pg_strdup(optline);
765 }
766
767 /* Free the results of readfile. */
768 free_readfile(optlines);
769 }
770 }
771 }
772
773 /*
774 * SIGINT signal handler used while waiting for postmaster to start up.
775 * Forwards the SIGINT to the postmaster process, asking it to shut down,
776 * before terminating pg_ctl itself. This way, if the user hits CTRL-C while
777 * waiting for the server to start up, the server launch is aborted.
778 */
779 static void
trap_sigint_during_startup(int sig)780 trap_sigint_during_startup(int sig)
781 {
782 if (postmasterPID != -1)
783 {
784 if (kill(postmasterPID, SIGINT) != 0)
785 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"),
786 progname, (pgpid_t) postmasterPID, strerror(errno));
787 }
788
789 /*
790 * Clear the signal handler, and send the signal again, to terminate the
791 * process as normal.
792 */
793 pqsignal(SIGINT, SIG_DFL);
794 raise(SIGINT);
795 }
796
797 static char *
find_other_exec_or_die(const char * argv0,const char * target,const char * versionstr)798 find_other_exec_or_die(const char *argv0, const char *target, const char *versionstr)
799 {
800 int ret;
801 char *found_path;
802
803 found_path = pg_malloc(MAXPGPATH);
804
805 if ((ret = find_other_exec(argv0, target, versionstr, found_path)) < 0)
806 {
807 char full_path[MAXPGPATH];
808
809 if (find_my_exec(argv0, full_path) < 0)
810 strlcpy(full_path, progname, sizeof(full_path));
811
812 if (ret == -1)
813 write_stderr(_("The program \"%s\" is needed by %s "
814 "but was not found in the\n"
815 "same directory as \"%s\".\n"
816 "Check your installation.\n"),
817 target, progname, full_path);
818 else
819 write_stderr(_("The program \"%s\" was found by \"%s\"\n"
820 "but was not the same version as %s.\n"
821 "Check your installation.\n"),
822 target, full_path, progname);
823 exit(1);
824 }
825
826 return found_path;
827 }
828
829 static void
do_init(void)830 do_init(void)
831 {
832 char *cmd;
833
834 if (exec_path == NULL)
835 exec_path = find_other_exec_or_die(argv0, "initdb", "initdb (PostgreSQL) " PG_VERSION "\n");
836
837 if (pgdata_opt == NULL)
838 pgdata_opt = "";
839
840 if (post_opts == NULL)
841 post_opts = "";
842
843 if (!silent_mode)
844 cmd = psprintf("\"%s\" %s%s",
845 exec_path, pgdata_opt, post_opts);
846 else
847 cmd = psprintf("\"%s\" %s%s > \"%s\"",
848 exec_path, pgdata_opt, post_opts, DEVNULL);
849
850 if (system(cmd) != 0)
851 {
852 write_stderr(_("%s: database system initialization failed\n"), progname);
853 exit(1);
854 }
855 }
856
857 static void
do_start(void)858 do_start(void)
859 {
860 pgpid_t old_pid = 0;
861 pgpid_t pm_pid;
862
863 if (ctl_command != RESTART_COMMAND)
864 {
865 old_pid = get_pgpid(false);
866 if (old_pid != 0)
867 write_stderr(_("%s: another server might be running; "
868 "trying to start server anyway\n"),
869 progname);
870 }
871
872 read_post_opts();
873
874 /* No -D or -D already added during server start */
875 if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
876 pgdata_opt = "";
877
878 if (exec_path == NULL)
879 exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
880
881 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
882 if (allow_core_files)
883 unlimit_core_size();
884 #endif
885
886 /*
887 * If possible, tell the postmaster our parent shell's PID (see the
888 * comments in CreateLockFile() for motivation). Windows hasn't got
889 * getppid() unfortunately.
890 */
891 #ifndef WIN32
892 {
893 static char env_var[32];
894
895 snprintf(env_var, sizeof(env_var), "PG_GRANDPARENT_PID=%d",
896 (int) getppid());
897 putenv(env_var);
898 }
899 #endif
900
901 pm_pid = start_postmaster();
902
903 if (do_wait)
904 {
905 /*
906 * If the user interrupts the startup (e.g. with CTRL-C), we'd like to
907 * abort the server launch. Install a signal handler that will
908 * forward SIGINT to the postmaster process, while we wait.
909 *
910 * (We don't bother to reset the signal handler after the launch, as
911 * we're about to exit, anyway.)
912 */
913 postmasterPID = pm_pid;
914 pqsignal(SIGINT, trap_sigint_during_startup);
915
916 print_msg(_("waiting for server to start..."));
917
918 switch (wait_for_postmaster(pm_pid, false))
919 {
920 case POSTMASTER_READY:
921 print_msg(_(" done\n"));
922 print_msg(_("server started\n"));
923 break;
924 case POSTMASTER_STILL_STARTING:
925 print_msg(_(" stopped waiting\n"));
926 write_stderr(_("%s: server did not start in time\n"),
927 progname);
928 exit(1);
929 break;
930 case POSTMASTER_FAILED:
931 print_msg(_(" stopped waiting\n"));
932 write_stderr(_("%s: could not start server\n"
933 "Examine the log output.\n"),
934 progname);
935 exit(1);
936 break;
937 }
938 }
939 else
940 print_msg(_("server starting\n"));
941
942 #ifdef WIN32
943 /* Now we don't need the handle to the shell process anymore */
944 CloseHandle(postmasterProcess);
945 postmasterProcess = INVALID_HANDLE_VALUE;
946 #endif
947 }
948
949
950 static void
do_stop(void)951 do_stop(void)
952 {
953 int cnt;
954 pgpid_t pid;
955 struct stat statbuf;
956
957 pid = get_pgpid(false);
958
959 if (pid == 0) /* no pid file */
960 {
961 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
962 write_stderr(_("Is server running?\n"));
963 exit(1);
964 }
965 else if (pid < 0) /* standalone backend, not postmaster */
966 {
967 pid = -pid;
968 write_stderr(_("%s: cannot stop server; "
969 "single-user server is running (PID: %ld)\n"),
970 progname, pid);
971 exit(1);
972 }
973
974 if (kill((pid_t) pid, sig) != 0)
975 {
976 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
977 strerror(errno));
978 exit(1);
979 }
980
981 if (!do_wait)
982 {
983 print_msg(_("server shutting down\n"));
984 return;
985 }
986 else
987 {
988 /*
989 * If backup_label exists, an online backup is running. Warn the user
990 * that smart shutdown will wait for it to finish. However, if the
991 * server is in archive recovery, we're recovering from an online
992 * backup instead of performing one.
993 */
994 if (shutdown_mode == SMART_MODE &&
995 stat(backup_file, &statbuf) == 0 &&
996 get_control_dbstate() != DB_IN_ARCHIVE_RECOVERY)
997 {
998 print_msg(_("WARNING: online backup mode is active\n"
999 "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
1000 }
1001
1002 print_msg(_("waiting for server to shut down..."));
1003
1004 for (cnt = 0; cnt < wait_seconds * WAITS_PER_SEC; cnt++)
1005 {
1006 if ((pid = get_pgpid(false)) != 0)
1007 {
1008 if (cnt % WAITS_PER_SEC == 0)
1009 print_msg(".");
1010 pg_usleep(USEC_PER_SEC / WAITS_PER_SEC);
1011 }
1012 else
1013 break;
1014 }
1015
1016 if (pid != 0) /* pid file still exists */
1017 {
1018 print_msg(_(" failed\n"));
1019
1020 write_stderr(_("%s: server does not shut down\n"), progname);
1021 if (shutdown_mode == SMART_MODE)
1022 write_stderr(_("HINT: The \"-m fast\" option immediately disconnects sessions rather than\n"
1023 "waiting for session-initiated disconnection.\n"));
1024 exit(1);
1025 }
1026 print_msg(_(" done\n"));
1027
1028 print_msg(_("server stopped\n"));
1029 }
1030 }
1031
1032
1033 /*
1034 * restart/reload routines
1035 */
1036
1037 static void
do_restart(void)1038 do_restart(void)
1039 {
1040 int cnt;
1041 pgpid_t pid;
1042 struct stat statbuf;
1043
1044 pid = get_pgpid(false);
1045
1046 if (pid == 0) /* no pid file */
1047 {
1048 write_stderr(_("%s: PID file \"%s\" does not exist\n"),
1049 progname, pid_file);
1050 write_stderr(_("Is server running?\n"));
1051 write_stderr(_("trying to start server anyway\n"));
1052 do_start();
1053 return;
1054 }
1055 else if (pid < 0) /* standalone backend, not postmaster */
1056 {
1057 pid = -pid;
1058 if (postmaster_is_alive((pid_t) pid))
1059 {
1060 write_stderr(_("%s: cannot restart server; "
1061 "single-user server is running (PID: %ld)\n"),
1062 progname, pid);
1063 write_stderr(_("Please terminate the single-user server and try again.\n"));
1064 exit(1);
1065 }
1066 }
1067
1068 if (postmaster_is_alive((pid_t) pid))
1069 {
1070 if (kill((pid_t) pid, sig) != 0)
1071 {
1072 write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
1073 strerror(errno));
1074 exit(1);
1075 }
1076
1077 /*
1078 * If backup_label exists, an online backup is running. Warn the user
1079 * that smart shutdown will wait for it to finish. However, if the
1080 * server is in archive recovery, we're recovering from an online
1081 * backup instead of performing one.
1082 */
1083 if (shutdown_mode == SMART_MODE &&
1084 stat(backup_file, &statbuf) == 0 &&
1085 get_control_dbstate() != DB_IN_ARCHIVE_RECOVERY)
1086 {
1087 print_msg(_("WARNING: online backup mode is active\n"
1088 "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
1089 }
1090
1091 print_msg(_("waiting for server to shut down..."));
1092
1093 /* always wait for restart */
1094
1095 for (cnt = 0; cnt < wait_seconds * WAITS_PER_SEC; cnt++)
1096 {
1097 if ((pid = get_pgpid(false)) != 0)
1098 {
1099 if (cnt % WAITS_PER_SEC == 0)
1100 print_msg(".");
1101 pg_usleep(USEC_PER_SEC / WAITS_PER_SEC);
1102 }
1103 else
1104 break;
1105 }
1106
1107 if (pid != 0) /* pid file still exists */
1108 {
1109 print_msg(_(" failed\n"));
1110
1111 write_stderr(_("%s: server does not shut down\n"), progname);
1112 if (shutdown_mode == SMART_MODE)
1113 write_stderr(_("HINT: The \"-m fast\" option immediately disconnects sessions rather than\n"
1114 "waiting for session-initiated disconnection.\n"));
1115 exit(1);
1116 }
1117
1118 print_msg(_(" done\n"));
1119 print_msg(_("server stopped\n"));
1120 }
1121 else
1122 {
1123 write_stderr(_("%s: old server process (PID: %ld) seems to be gone\n"),
1124 progname, pid);
1125 write_stderr(_("starting server anyway\n"));
1126 }
1127
1128 do_start();
1129 }
1130
1131 static void
do_reload(void)1132 do_reload(void)
1133 {
1134 pgpid_t pid;
1135
1136 pid = get_pgpid(false);
1137 if (pid == 0) /* no pid file */
1138 {
1139 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
1140 write_stderr(_("Is server running?\n"));
1141 exit(1);
1142 }
1143 else if (pid < 0) /* standalone backend, not postmaster */
1144 {
1145 pid = -pid;
1146 write_stderr(_("%s: cannot reload server; "
1147 "single-user server is running (PID: %ld)\n"),
1148 progname, pid);
1149 write_stderr(_("Please terminate the single-user server and try again.\n"));
1150 exit(1);
1151 }
1152
1153 if (kill((pid_t) pid, sig) != 0)
1154 {
1155 write_stderr(_("%s: could not send reload signal (PID: %ld): %s\n"),
1156 progname, pid, strerror(errno));
1157 exit(1);
1158 }
1159
1160 print_msg(_("server signaled\n"));
1161 }
1162
1163
1164 /*
1165 * promote
1166 */
1167
1168 static void
do_promote(void)1169 do_promote(void)
1170 {
1171 FILE *prmfile;
1172 pgpid_t pid;
1173
1174 pid = get_pgpid(false);
1175
1176 if (pid == 0) /* no pid file */
1177 {
1178 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
1179 write_stderr(_("Is server running?\n"));
1180 exit(1);
1181 }
1182 else if (pid < 0) /* standalone backend, not postmaster */
1183 {
1184 pid = -pid;
1185 write_stderr(_("%s: cannot promote server; "
1186 "single-user server is running (PID: %ld)\n"),
1187 progname, pid);
1188 exit(1);
1189 }
1190
1191 if (get_control_dbstate() != DB_IN_ARCHIVE_RECOVERY)
1192 {
1193 write_stderr(_("%s: cannot promote server; "
1194 "server is not in standby mode\n"),
1195 progname);
1196 exit(1);
1197 }
1198
1199 /*
1200 * For 9.3 onwards, "fast" promotion is performed. Promotion with a full
1201 * checkpoint is still possible by writing a file called
1202 * "fallback_promote" instead of "promote"
1203 */
1204 snprintf(promote_file, MAXPGPATH, "%s/promote", pg_data);
1205
1206 if ((prmfile = fopen(promote_file, "w")) == NULL)
1207 {
1208 write_stderr(_("%s: could not create promote signal file \"%s\": %s\n"),
1209 progname, promote_file, strerror(errno));
1210 exit(1);
1211 }
1212 if (fclose(prmfile))
1213 {
1214 write_stderr(_("%s: could not write promote signal file \"%s\": %s\n"),
1215 progname, promote_file, strerror(errno));
1216 exit(1);
1217 }
1218
1219 sig = SIGUSR1;
1220 if (kill((pid_t) pid, sig) != 0)
1221 {
1222 write_stderr(_("%s: could not send promote signal (PID: %ld): %s\n"),
1223 progname, pid, strerror(errno));
1224 if (unlink(promote_file) != 0)
1225 write_stderr(_("%s: could not remove promote signal file \"%s\": %s\n"),
1226 progname, promote_file, strerror(errno));
1227 exit(1);
1228 }
1229
1230 if (do_wait)
1231 {
1232 DBState state = DB_STARTUP;
1233 int cnt;
1234
1235 print_msg(_("waiting for server to promote..."));
1236 for (cnt = 0; cnt < wait_seconds * WAITS_PER_SEC; cnt++)
1237 {
1238 state = get_control_dbstate();
1239 if (state == DB_IN_PRODUCTION)
1240 break;
1241
1242 if (cnt % WAITS_PER_SEC == 0)
1243 print_msg(".");
1244 pg_usleep(USEC_PER_SEC / WAITS_PER_SEC);
1245 }
1246 if (state == DB_IN_PRODUCTION)
1247 {
1248 print_msg(_(" done\n"));
1249 print_msg(_("server promoted\n"));
1250 }
1251 else
1252 {
1253 print_msg(_(" stopped waiting\n"));
1254 write_stderr(_("%s: server did not promote in time\n"),
1255 progname);
1256 exit(1);
1257 }
1258 }
1259 else
1260 print_msg(_("server promoting\n"));
1261 }
1262
1263 /*
1264 * log rotate
1265 */
1266
1267 static void
do_logrotate(void)1268 do_logrotate(void)
1269 {
1270 FILE *logrotatefile;
1271 pgpid_t pid;
1272
1273 pid = get_pgpid(false);
1274
1275 if (pid == 0) /* no pid file */
1276 {
1277 write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
1278 write_stderr(_("Is server running?\n"));
1279 exit(1);
1280 }
1281 else if (pid < 0) /* standalone backend, not postmaster */
1282 {
1283 pid = -pid;
1284 write_stderr(_("%s: cannot rotate log file; "
1285 "single-user server is running (PID: %ld)\n"),
1286 progname, pid);
1287 exit(1);
1288 }
1289
1290 snprintf(logrotate_file, MAXPGPATH, "%s/logrotate", pg_data);
1291
1292 if ((logrotatefile = fopen(logrotate_file, "w")) == NULL)
1293 {
1294 write_stderr(_("%s: could not create log rotation signal file \"%s\": %s\n"),
1295 progname, logrotate_file, strerror(errno));
1296 exit(1);
1297 }
1298 if (fclose(logrotatefile))
1299 {
1300 write_stderr(_("%s: could not write log rotation signal file \"%s\": %s\n"),
1301 progname, logrotate_file, strerror(errno));
1302 exit(1);
1303 }
1304
1305 sig = SIGUSR1;
1306 if (kill((pid_t) pid, sig) != 0)
1307 {
1308 write_stderr(_("%s: could not send log rotation signal (PID: %ld): %s\n"),
1309 progname, pid, strerror(errno));
1310 if (unlink(logrotate_file) != 0)
1311 write_stderr(_("%s: could not remove log rotation signal file \"%s\": %s\n"),
1312 progname, logrotate_file, strerror(errno));
1313 exit(1);
1314 }
1315
1316 print_msg(_("server signaled to rotate log file\n"));
1317 }
1318
1319
1320 /*
1321 * utility routines
1322 */
1323
1324 static bool
postmaster_is_alive(pid_t pid)1325 postmaster_is_alive(pid_t pid)
1326 {
1327 /*
1328 * Test to see if the process is still there. Note that we do not
1329 * consider an EPERM failure to mean that the process is still there;
1330 * EPERM must mean that the given PID belongs to some other userid, and
1331 * considering the permissions on $PGDATA, that means it's not the
1332 * postmaster we are after.
1333 *
1334 * Don't believe that our own PID or parent shell's PID is the postmaster,
1335 * either. (Windows hasn't got getppid(), though.)
1336 */
1337 if (pid == getpid())
1338 return false;
1339 #ifndef WIN32
1340 if (pid == getppid())
1341 return false;
1342 #endif
1343 if (kill(pid, 0) == 0)
1344 return true;
1345 return false;
1346 }
1347
1348 static void
do_status(void)1349 do_status(void)
1350 {
1351 pgpid_t pid;
1352
1353 pid = get_pgpid(true);
1354 /* Is there a pid file? */
1355 if (pid != 0)
1356 {
1357 /* standalone backend? */
1358 if (pid < 0)
1359 {
1360 pid = -pid;
1361 if (postmaster_is_alive((pid_t) pid))
1362 {
1363 printf(_("%s: single-user server is running (PID: %ld)\n"),
1364 progname, pid);
1365 return;
1366 }
1367 }
1368 else
1369 /* must be a postmaster */
1370 {
1371 if (postmaster_is_alive((pid_t) pid))
1372 {
1373 char **optlines;
1374 char **curr_line;
1375 int numlines;
1376
1377 printf(_("%s: server is running (PID: %ld)\n"),
1378 progname, pid);
1379
1380 optlines = readfile(postopts_file, &numlines);
1381 if (optlines != NULL)
1382 {
1383 for (curr_line = optlines; *curr_line != NULL; curr_line++)
1384 puts(*curr_line);
1385
1386 /* Free the results of readfile */
1387 free_readfile(optlines);
1388 }
1389 return;
1390 }
1391 }
1392 }
1393 printf(_("%s: no server running\n"), progname);
1394
1395 /*
1396 * The Linux Standard Base Core Specification 3.1 says this should return
1397 * '3, program is not running'
1398 * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
1399 */
1400 exit(3);
1401 }
1402
1403
1404
1405 static void
do_kill(pgpid_t pid)1406 do_kill(pgpid_t pid)
1407 {
1408 if (kill((pid_t) pid, sig) != 0)
1409 {
1410 write_stderr(_("%s: could not send signal %d (PID: %ld): %s\n"),
1411 progname, sig, pid, strerror(errno));
1412 exit(1);
1413 }
1414 }
1415
1416 #ifdef WIN32
1417
1418 #if (_MSC_VER < 1800)
1419 static bool
IsWindowsXPOrGreater(void)1420 IsWindowsXPOrGreater(void)
1421 {
1422 OSVERSIONINFO osv;
1423
1424 osv.dwOSVersionInfoSize = sizeof(osv);
1425
1426 /* Windows XP = Version 5.1 */
1427 return (!GetVersionEx(&osv) || /* could not get version */
1428 osv.dwMajorVersion > 5 || (osv.dwMajorVersion == 5 && osv.dwMinorVersion >= 1));
1429 }
1430
1431 static bool
IsWindows7OrGreater(void)1432 IsWindows7OrGreater(void)
1433 {
1434 OSVERSIONINFO osv;
1435
1436 osv.dwOSVersionInfoSize = sizeof(osv);
1437
1438 /* Windows 7 = Version 6.0 */
1439 return (!GetVersionEx(&osv) || /* could not get version */
1440 osv.dwMajorVersion > 6 || (osv.dwMajorVersion == 6 && osv.dwMinorVersion >= 0));
1441 }
1442 #endif
1443
1444 static bool
pgwin32_IsInstalled(SC_HANDLE hSCM)1445 pgwin32_IsInstalled(SC_HANDLE hSCM)
1446 {
1447 SC_HANDLE hService = OpenService(hSCM, register_servicename, SERVICE_QUERY_CONFIG);
1448 bool bResult = (hService != NULL);
1449
1450 if (bResult)
1451 CloseServiceHandle(hService);
1452 return bResult;
1453 }
1454
1455 static char *
pgwin32_CommandLine(bool registration)1456 pgwin32_CommandLine(bool registration)
1457 {
1458 PQExpBuffer cmdLine = createPQExpBuffer();
1459 char cmdPath[MAXPGPATH];
1460 int ret;
1461
1462 if (registration)
1463 {
1464 ret = find_my_exec(argv0, cmdPath);
1465 if (ret != 0)
1466 {
1467 write_stderr(_("%s: could not find own program executable\n"), progname);
1468 exit(1);
1469 }
1470 }
1471 else
1472 {
1473 ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
1474 cmdPath);
1475 if (ret != 0)
1476 {
1477 write_stderr(_("%s: could not find postgres program executable\n"), progname);
1478 exit(1);
1479 }
1480 }
1481
1482 /* if path does not end in .exe, append it */
1483 if (strlen(cmdPath) < 4 ||
1484 pg_strcasecmp(cmdPath + strlen(cmdPath) - 4, ".exe") != 0)
1485 snprintf(cmdPath + strlen(cmdPath), sizeof(cmdPath) - strlen(cmdPath),
1486 ".exe");
1487
1488 /* use backslashes in path to avoid problems with some third-party tools */
1489 make_native_path(cmdPath);
1490
1491 /* be sure to double-quote the executable's name in the command */
1492 appendPQExpBuffer(cmdLine, "\"%s\"", cmdPath);
1493
1494 /* append assorted switches to the command line, as needed */
1495
1496 if (registration)
1497 appendPQExpBuffer(cmdLine, " runservice -N \"%s\"",
1498 register_servicename);
1499
1500 if (pg_config)
1501 {
1502 /* We need the -D path to be absolute */
1503 char *dataDir;
1504
1505 if ((dataDir = make_absolute_path(pg_config)) == NULL)
1506 {
1507 /* make_absolute_path already reported the error */
1508 exit(1);
1509 }
1510 make_native_path(dataDir);
1511 appendPQExpBuffer(cmdLine, " -D \"%s\"", dataDir);
1512 free(dataDir);
1513 }
1514
1515 if (registration && event_source != NULL)
1516 appendPQExpBuffer(cmdLine, " -e \"%s\"", event_source);
1517
1518 if (registration && do_wait)
1519 appendPQExpBuffer(cmdLine, " -w");
1520
1521 /* Don't propagate a value from an environment variable. */
1522 if (registration && wait_seconds_arg && wait_seconds != DEFAULT_WAIT)
1523 appendPQExpBuffer(cmdLine, " -t %d", wait_seconds);
1524
1525 if (registration && silent_mode)
1526 appendPQExpBuffer(cmdLine, " -s");
1527
1528 if (post_opts)
1529 {
1530 if (registration)
1531 appendPQExpBuffer(cmdLine, " -o \"%s\"", post_opts);
1532 else
1533 appendPQExpBuffer(cmdLine, " %s", post_opts);
1534 }
1535
1536 return cmdLine->data;
1537 }
1538
1539 static void
pgwin32_doRegister(void)1540 pgwin32_doRegister(void)
1541 {
1542 SC_HANDLE hService;
1543 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1544
1545 if (hSCM == NULL)
1546 {
1547 write_stderr(_("%s: could not open service manager\n"), progname);
1548 exit(1);
1549 }
1550 if (pgwin32_IsInstalled(hSCM))
1551 {
1552 CloseServiceHandle(hSCM);
1553 write_stderr(_("%s: service \"%s\" already registered\n"), progname, register_servicename);
1554 exit(1);
1555 }
1556
1557 if ((hService = CreateService(hSCM, register_servicename, register_servicename,
1558 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
1559 pgctl_start_type, SERVICE_ERROR_NORMAL,
1560 pgwin32_CommandLine(true),
1561 NULL, NULL, "RPCSS\0", register_username, register_password)) == NULL)
1562 {
1563 CloseServiceHandle(hSCM);
1564 write_stderr(_("%s: could not register service \"%s\": error code %lu\n"),
1565 progname, register_servicename,
1566 (unsigned long) GetLastError());
1567 exit(1);
1568 }
1569 CloseServiceHandle(hService);
1570 CloseServiceHandle(hSCM);
1571 }
1572
1573 static void
pgwin32_doUnregister(void)1574 pgwin32_doUnregister(void)
1575 {
1576 SC_HANDLE hService;
1577 SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
1578
1579 if (hSCM == NULL)
1580 {
1581 write_stderr(_("%s: could not open service manager\n"), progname);
1582 exit(1);
1583 }
1584 if (!pgwin32_IsInstalled(hSCM))
1585 {
1586 CloseServiceHandle(hSCM);
1587 write_stderr(_("%s: service \"%s\" not registered\n"), progname, register_servicename);
1588 exit(1);
1589 }
1590
1591 if ((hService = OpenService(hSCM, register_servicename, DELETE)) == NULL)
1592 {
1593 CloseServiceHandle(hSCM);
1594 write_stderr(_("%s: could not open service \"%s\": error code %lu\n"),
1595 progname, register_servicename,
1596 (unsigned long) GetLastError());
1597 exit(1);
1598 }
1599 if (!DeleteService(hService))
1600 {
1601 CloseServiceHandle(hService);
1602 CloseServiceHandle(hSCM);
1603 write_stderr(_("%s: could not unregister service \"%s\": error code %lu\n"),
1604 progname, register_servicename,
1605 (unsigned long) GetLastError());
1606 exit(1);
1607 }
1608 CloseServiceHandle(hService);
1609 CloseServiceHandle(hSCM);
1610 }
1611
1612 static void
pgwin32_SetServiceStatus(DWORD currentState)1613 pgwin32_SetServiceStatus(DWORD currentState)
1614 {
1615 status.dwCurrentState = currentState;
1616 SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
1617 }
1618
1619 static void WINAPI
pgwin32_ServiceHandler(DWORD request)1620 pgwin32_ServiceHandler(DWORD request)
1621 {
1622 switch (request)
1623 {
1624 case SERVICE_CONTROL_STOP:
1625 case SERVICE_CONTROL_SHUTDOWN:
1626
1627 /*
1628 * We only need a short wait hint here as it just needs to wait
1629 * for the next checkpoint. They occur every 5 seconds during
1630 * shutdown
1631 */
1632 status.dwWaitHint = 10000;
1633 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1634 SetEvent(shutdownEvent);
1635 return;
1636
1637 case SERVICE_CONTROL_PAUSE:
1638 /* Win32 config reloading */
1639 status.dwWaitHint = 5000;
1640 kill(postmasterPID, SIGHUP);
1641 return;
1642
1643 /* FIXME: These could be used to replace other signals etc */
1644 case SERVICE_CONTROL_CONTINUE:
1645 case SERVICE_CONTROL_INTERROGATE:
1646 default:
1647 break;
1648 }
1649 }
1650
1651 static void WINAPI
pgwin32_ServiceMain(DWORD argc,LPTSTR * argv)1652 pgwin32_ServiceMain(DWORD argc, LPTSTR *argv)
1653 {
1654 PROCESS_INFORMATION pi;
1655 DWORD ret;
1656
1657 /* Initialize variables */
1658 status.dwWin32ExitCode = S_OK;
1659 status.dwCheckPoint = 0;
1660 status.dwWaitHint = 60000;
1661 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
1662 status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
1663 status.dwServiceSpecificExitCode = 0;
1664 status.dwCurrentState = SERVICE_START_PENDING;
1665
1666 memset(&pi, 0, sizeof(pi));
1667
1668 read_post_opts();
1669
1670 /* Register the control request handler */
1671 if ((hStatus = RegisterServiceCtrlHandler(register_servicename, pgwin32_ServiceHandler)) == (SERVICE_STATUS_HANDLE) 0)
1672 return;
1673
1674 if ((shutdownEvent = CreateEvent(NULL, true, false, NULL)) == NULL)
1675 return;
1676
1677 /* Start the postmaster */
1678 pgwin32_SetServiceStatus(SERVICE_START_PENDING);
1679 if (!CreateRestrictedProcess(pgwin32_CommandLine(false), &pi, true))
1680 {
1681 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1682 return;
1683 }
1684 postmasterPID = pi.dwProcessId;
1685 postmasterProcess = pi.hProcess;
1686 CloseHandle(pi.hThread);
1687
1688 if (do_wait)
1689 {
1690 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Waiting for server startup...\n"));
1691 if (wait_for_postmaster(postmasterPID, true) != POSTMASTER_READY)
1692 {
1693 write_eventlog(EVENTLOG_ERROR_TYPE, _("Timed out waiting for server startup\n"));
1694 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1695 return;
1696 }
1697 write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Server started and accepting connections\n"));
1698 }
1699
1700 pgwin32_SetServiceStatus(SERVICE_RUNNING);
1701
1702 /* Wait for quit... */
1703 ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);
1704
1705 pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
1706 switch (ret)
1707 {
1708 case WAIT_OBJECT_0: /* shutdown event */
1709 {
1710 /*
1711 * status.dwCheckPoint can be incremented by
1712 * wait_for_postmaster(), so it might not start from 0.
1713 */
1714 int maxShutdownCheckPoint = status.dwCheckPoint + 12;
1715
1716 kill(postmasterPID, SIGINT);
1717
1718 /*
1719 * Increment the checkpoint and try again. Abort after 12
1720 * checkpoints as the postmaster has probably hung.
1721 */
1722 while (WaitForSingleObject(postmasterProcess, 5000) == WAIT_TIMEOUT && status.dwCheckPoint < maxShutdownCheckPoint)
1723 {
1724 status.dwCheckPoint++;
1725 SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
1726 }
1727 break;
1728 }
1729
1730 case (WAIT_OBJECT_0 + 1): /* postmaster went down */
1731 break;
1732
1733 default:
1734 /* shouldn't get here? */
1735 break;
1736 }
1737
1738 CloseHandle(shutdownEvent);
1739 CloseHandle(postmasterProcess);
1740
1741 pgwin32_SetServiceStatus(SERVICE_STOPPED);
1742 }
1743
1744 static void
pgwin32_doRunAsService(void)1745 pgwin32_doRunAsService(void)
1746 {
1747 SERVICE_TABLE_ENTRY st[] = {{register_servicename, pgwin32_ServiceMain},
1748 {NULL, NULL}};
1749
1750 if (StartServiceCtrlDispatcher(st) == 0)
1751 {
1752 write_stderr(_("%s: could not start service \"%s\": error code %lu\n"),
1753 progname, register_servicename,
1754 (unsigned long) GetLastError());
1755 exit(1);
1756 }
1757 }
1758
1759
1760 /*
1761 * Mingw headers are incomplete, and so are the libraries. So we have to load
1762 * a whole lot of API functions dynamically. Since we have to do this anyway,
1763 * also load the couple of functions that *do* exist in minwg headers but not
1764 * on NT4. That way, we don't break on NT4.
1765 */
1766 typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
1767 typedef BOOL (WINAPI * __IsProcessInJob) (HANDLE, HANDLE, PBOOL);
1768 typedef HANDLE (WINAPI * __CreateJobObject) (LPSECURITY_ATTRIBUTES, LPCTSTR);
1769 typedef BOOL (WINAPI * __SetInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD);
1770 typedef BOOL (WINAPI * __AssignProcessToJobObject) (HANDLE, HANDLE);
1771 typedef BOOL (WINAPI * __QueryInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD);
1772
1773 /*
1774 * Create a restricted token, a job object sandbox, and execute the specified
1775 * process with it.
1776 *
1777 * Returns 0 on success, non-zero on failure, same as CreateProcess().
1778 *
1779 * On NT4, or any other system not containing the required functions, will
1780 * launch the process under the current token without doing any modifications.
1781 *
1782 * NOTE! Job object will only work when running as a service, because it's
1783 * automatically destroyed when pg_ctl exits.
1784 */
1785 static int
CreateRestrictedProcess(char * cmd,PROCESS_INFORMATION * processInfo,bool as_service)1786 CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service)
1787 {
1788 int r;
1789 BOOL b;
1790 STARTUPINFO si;
1791 HANDLE origToken;
1792 HANDLE restrictedToken;
1793 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
1794 SID_AND_ATTRIBUTES dropSids[2];
1795 PTOKEN_PRIVILEGES delPrivs;
1796
1797 /* Functions loaded dynamically */
1798 __CreateRestrictedToken _CreateRestrictedToken = NULL;
1799 __IsProcessInJob _IsProcessInJob = NULL;
1800 __CreateJobObject _CreateJobObject = NULL;
1801 __SetInformationJobObject _SetInformationJobObject = NULL;
1802 __AssignProcessToJobObject _AssignProcessToJobObject = NULL;
1803 __QueryInformationJobObject _QueryInformationJobObject = NULL;
1804 HANDLE Kernel32Handle;
1805 HANDLE Advapi32Handle;
1806
1807 ZeroMemory(&si, sizeof(si));
1808 si.cb = sizeof(si);
1809
1810 Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
1811 if (Advapi32Handle != NULL)
1812 {
1813 _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
1814 }
1815
1816 if (_CreateRestrictedToken == NULL)
1817 {
1818 /*
1819 * NT4 doesn't have CreateRestrictedToken, so just call ordinary
1820 * CreateProcess
1821 */
1822 write_stderr(_("%s: WARNING: cannot create restricted tokens on this platform\n"), progname);
1823 if (Advapi32Handle != NULL)
1824 FreeLibrary(Advapi32Handle);
1825 return CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, processInfo);
1826 }
1827
1828 /* Open the current token to use as a base for the restricted one */
1829 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
1830 {
1831 /*
1832 * Most Windows targets make DWORD a 32-bit unsigned long, but in case
1833 * it doesn't cast DWORD before printing.
1834 */
1835 write_stderr(_("%s: could not open process token: error code %lu\n"),
1836 progname, (unsigned long) GetLastError());
1837 return 0;
1838 }
1839
1840 /* Allocate list of SIDs to remove */
1841 ZeroMemory(&dropSids, sizeof(dropSids));
1842 if (!AllocateAndInitializeSid(&NtAuthority, 2,
1843 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
1844 0, &dropSids[0].Sid) ||
1845 !AllocateAndInitializeSid(&NtAuthority, 2,
1846 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
1847 0, &dropSids[1].Sid))
1848 {
1849 write_stderr(_("%s: could not allocate SIDs: error code %lu\n"),
1850 progname, (unsigned long) GetLastError());
1851 return 0;
1852 }
1853
1854 /* Get list of privileges to remove */
1855 delPrivs = GetPrivilegesToDelete(origToken);
1856 if (delPrivs == NULL)
1857 /* Error message already printed */
1858 return 0;
1859
1860 b = _CreateRestrictedToken(origToken,
1861 0,
1862 sizeof(dropSids) / sizeof(dropSids[0]),
1863 dropSids,
1864 delPrivs->PrivilegeCount, delPrivs->Privileges,
1865 0, NULL,
1866 &restrictedToken);
1867
1868 free(delPrivs);
1869 FreeSid(dropSids[1].Sid);
1870 FreeSid(dropSids[0].Sid);
1871 CloseHandle(origToken);
1872 FreeLibrary(Advapi32Handle);
1873
1874 if (!b)
1875 {
1876 write_stderr(_("%s: could not create restricted token: error code %lu\n"),
1877 progname, (unsigned long) GetLastError());
1878 return 0;
1879 }
1880
1881 AddUserToTokenDacl(restrictedToken);
1882 r = CreateProcessAsUser(restrictedToken, NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, processInfo);
1883
1884 Kernel32Handle = LoadLibrary("KERNEL32.DLL");
1885 if (Kernel32Handle != NULL)
1886 {
1887 _IsProcessInJob = (__IsProcessInJob) GetProcAddress(Kernel32Handle, "IsProcessInJob");
1888 _CreateJobObject = (__CreateJobObject) GetProcAddress(Kernel32Handle, "CreateJobObjectA");
1889 _SetInformationJobObject = (__SetInformationJobObject) GetProcAddress(Kernel32Handle, "SetInformationJobObject");
1890 _AssignProcessToJobObject = (__AssignProcessToJobObject) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject");
1891 _QueryInformationJobObject = (__QueryInformationJobObject) GetProcAddress(Kernel32Handle, "QueryInformationJobObject");
1892 }
1893
1894 /* Verify that we found all functions */
1895 if (_IsProcessInJob == NULL || _CreateJobObject == NULL || _SetInformationJobObject == NULL || _AssignProcessToJobObject == NULL || _QueryInformationJobObject == NULL)
1896 {
1897 /*
1898 * IsProcessInJob() is not available on < WinXP, so there is no need
1899 * to log the error every time in that case
1900 */
1901 if (IsWindowsXPOrGreater())
1902
1903 /*
1904 * Log error if we can't get version, or if we're on WinXP/2003 or
1905 * newer
1906 */
1907 write_stderr(_("%s: WARNING: could not locate all job object functions in system API\n"), progname);
1908 }
1909 else
1910 {
1911 BOOL inJob;
1912
1913 if (_IsProcessInJob(processInfo->hProcess, NULL, &inJob))
1914 {
1915 if (!inJob)
1916 {
1917 /*
1918 * Job objects are working, and the new process isn't in one,
1919 * so we can create one safely. If any problems show up when
1920 * setting it, we're going to ignore them.
1921 */
1922 HANDLE job;
1923 char jobname[128];
1924
1925 sprintf(jobname, "PostgreSQL_%lu",
1926 (unsigned long) processInfo->dwProcessId);
1927
1928 job = _CreateJobObject(NULL, jobname);
1929 if (job)
1930 {
1931 JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
1932 JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
1933 JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
1934
1935 ZeroMemory(&basicLimit, sizeof(basicLimit));
1936 ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
1937 ZeroMemory(&securityLimit, sizeof(securityLimit));
1938
1939 basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
1940 basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
1941 _SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));
1942
1943 uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
1944 JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
1945 JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
1946
1947 if (as_service)
1948 {
1949 if (!IsWindows7OrGreater())
1950 {
1951 /*
1952 * On Windows 7 (and presumably later),
1953 * JOB_OBJECT_UILIMIT_HANDLES prevents us from
1954 * starting as a service. So we only enable it on
1955 * Vista and earlier (version <= 6.0)
1956 */
1957 uiRestrictions.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
1958 }
1959 }
1960 _SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));
1961
1962 securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
1963 securityLimit.JobToken = restrictedToken;
1964 _SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));
1965
1966 _AssignProcessToJobObject(job, processInfo->hProcess);
1967 }
1968 }
1969 }
1970 }
1971
1972
1973 CloseHandle(restrictedToken);
1974
1975 ResumeThread(processInfo->hThread);
1976
1977 FreeLibrary(Kernel32Handle);
1978
1979 /*
1980 * We intentionally don't close the job object handle, because we want the
1981 * object to live on until pg_ctl shuts down.
1982 */
1983 return r;
1984 }
1985
1986 /*
1987 * Get a list of privileges to delete from the access token. We delete all privileges
1988 * except SeLockMemoryPrivilege which is needed to use large pages, and
1989 * SeChangeNotifyPrivilege which is enabled by default in DISABLE_MAX_PRIVILEGE.
1990 */
1991 static PTOKEN_PRIVILEGES
GetPrivilegesToDelete(HANDLE hToken)1992 GetPrivilegesToDelete(HANDLE hToken)
1993 {
1994 int i,
1995 j;
1996 DWORD length;
1997 PTOKEN_PRIVILEGES tokenPrivs;
1998 LUID luidLockPages;
1999 LUID luidChangeNotify;
2000
2001 if (!LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &luidLockPages) ||
2002 !LookupPrivilegeValue(NULL, SE_CHANGE_NOTIFY_NAME, &luidChangeNotify))
2003 {
2004 write_stderr(_("%s: could not get LUIDs for privileges: error code %lu\n"),
2005 progname, (unsigned long) GetLastError());
2006 return NULL;
2007 }
2008
2009 if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &length) &&
2010 GetLastError() != ERROR_INSUFFICIENT_BUFFER)
2011 {
2012 write_stderr(_("%s: could not get token information: error code %lu\n"),
2013 progname, (unsigned long) GetLastError());
2014 return NULL;
2015 }
2016
2017 tokenPrivs = (PTOKEN_PRIVILEGES) pg_malloc_extended(length,
2018 MCXT_ALLOC_NO_OOM);
2019 if (tokenPrivs == NULL)
2020 {
2021 write_stderr(_("%s: out of memory\n"), progname);
2022 return NULL;
2023 }
2024
2025 if (!GetTokenInformation(hToken, TokenPrivileges, tokenPrivs, length, &length))
2026 {
2027 write_stderr(_("%s: could not get token information: error code %lu\n"),
2028 progname, (unsigned long) GetLastError());
2029 free(tokenPrivs);
2030 return NULL;
2031 }
2032
2033 for (i = 0; i < tokenPrivs->PrivilegeCount; i++)
2034 {
2035 if (memcmp(&tokenPrivs->Privileges[i].Luid, &luidLockPages, sizeof(LUID)) == 0 ||
2036 memcmp(&tokenPrivs->Privileges[i].Luid, &luidChangeNotify, sizeof(LUID)) == 0)
2037 {
2038 for (j = i; j < tokenPrivs->PrivilegeCount - 1; j++)
2039 tokenPrivs->Privileges[j] = tokenPrivs->Privileges[j + 1];
2040 tokenPrivs->PrivilegeCount--;
2041 }
2042 }
2043
2044 return tokenPrivs;
2045 }
2046 #endif /* WIN32 */
2047
2048 static void
do_advice(void)2049 do_advice(void)
2050 {
2051 write_stderr(_("Try \"%s --help\" for more information.\n"), progname);
2052 }
2053
2054
2055
2056 static void
do_help(void)2057 do_help(void)
2058 {
2059 printf(_("%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n\n"), progname);
2060 printf(_("Usage:\n"));
2061 printf(_(" %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n"), progname);
2062 printf(_(" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n"
2063 " [-o OPTIONS] [-p PATH] [-c]\n"), progname);
2064 printf(_(" %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n"), progname);
2065 printf(_(" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n"
2066 " [-o OPTIONS] [-c]\n"), progname);
2067 printf(_(" %s reload [-D DATADIR] [-s]\n"), progname);
2068 printf(_(" %s status [-D DATADIR]\n"), progname);
2069 printf(_(" %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n"), progname);
2070 printf(_(" %s logrotate [-D DATADIR] [-s]\n"), progname);
2071 printf(_(" %s kill SIGNALNAME PID\n"), progname);
2072 #ifdef WIN32
2073 printf(_(" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n"
2074 " [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n"), progname);
2075 printf(_(" %s unregister [-N SERVICENAME]\n"), progname);
2076 #endif
2077
2078 printf(_("\nCommon options:\n"));
2079 printf(_(" -D, --pgdata=DATADIR location of the database storage area\n"));
2080 #ifdef WIN32
2081 printf(_(" -e SOURCE event source for logging when running as a service\n"));
2082 #endif
2083 printf(_(" -s, --silent only print errors, no informational messages\n"));
2084 printf(_(" -t, --timeout=SECS seconds to wait when using -w option\n"));
2085 printf(_(" -V, --version output version information, then exit\n"));
2086 printf(_(" -w, --wait wait until operation completes (default)\n"));
2087 printf(_(" -W, --no-wait do not wait until operation completes\n"));
2088 printf(_(" -?, --help show this help, then exit\n"));
2089 printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
2090
2091 printf(_("\nOptions for start or restart:\n"));
2092 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
2093 printf(_(" -c, --core-files allow postgres to produce core files\n"));
2094 #else
2095 printf(_(" -c, --core-files not applicable on this platform\n"));
2096 #endif
2097 printf(_(" -l, --log=FILENAME write (or append) server log to FILENAME\n"));
2098 printf(_(" -o, --options=OPTIONS command line options to pass to postgres\n"
2099 " (PostgreSQL server executable) or initdb\n"));
2100 printf(_(" -p PATH-TO-POSTGRES normally not necessary\n"));
2101 printf(_("\nOptions for stop or restart:\n"));
2102 printf(_(" -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n"));
2103
2104 printf(_("\nShutdown modes are:\n"));
2105 printf(_(" smart quit after all clients have disconnected\n"));
2106 printf(_(" fast quit directly, with proper shutdown (default)\n"));
2107 printf(_(" immediate quit without complete shutdown; will lead to recovery on restart\n"));
2108
2109 printf(_("\nAllowed signal names for kill:\n"));
2110 printf(" ABRT HUP INT KILL QUIT TERM USR1 USR2\n");
2111
2112 #ifdef WIN32
2113 printf(_("\nOptions for register and unregister:\n"));
2114 printf(_(" -N SERVICENAME service name with which to register PostgreSQL server\n"));
2115 printf(_(" -P PASSWORD password of account to register PostgreSQL server\n"));
2116 printf(_(" -U USERNAME user name of account to register PostgreSQL server\n"));
2117 printf(_(" -S START-TYPE service start type to register PostgreSQL server\n"));
2118
2119 printf(_("\nStart types are:\n"));
2120 printf(_(" auto start service automatically during system startup (default)\n"));
2121 printf(_(" demand start service on demand\n"));
2122 #endif
2123
2124 printf(_("\nReport bugs to <pgsql-bugs@lists.postgresql.org>.\n"));
2125 }
2126
2127
2128
2129 static void
set_mode(char * modeopt)2130 set_mode(char *modeopt)
2131 {
2132 if (strcmp(modeopt, "s") == 0 || strcmp(modeopt, "smart") == 0)
2133 {
2134 shutdown_mode = SMART_MODE;
2135 sig = SIGTERM;
2136 }
2137 else if (strcmp(modeopt, "f") == 0 || strcmp(modeopt, "fast") == 0)
2138 {
2139 shutdown_mode = FAST_MODE;
2140 sig = SIGINT;
2141 }
2142 else if (strcmp(modeopt, "i") == 0 || strcmp(modeopt, "immediate") == 0)
2143 {
2144 shutdown_mode = IMMEDIATE_MODE;
2145 sig = SIGQUIT;
2146 }
2147 else
2148 {
2149 write_stderr(_("%s: unrecognized shutdown mode \"%s\"\n"), progname, modeopt);
2150 do_advice();
2151 exit(1);
2152 }
2153 }
2154
2155
2156
2157 static void
set_sig(char * signame)2158 set_sig(char *signame)
2159 {
2160 if (strcmp(signame, "HUP") == 0)
2161 sig = SIGHUP;
2162 else if (strcmp(signame, "INT") == 0)
2163 sig = SIGINT;
2164 else if (strcmp(signame, "QUIT") == 0)
2165 sig = SIGQUIT;
2166 else if (strcmp(signame, "ABRT") == 0)
2167 sig = SIGABRT;
2168 else if (strcmp(signame, "KILL") == 0)
2169 sig = SIGKILL;
2170 else if (strcmp(signame, "TERM") == 0)
2171 sig = SIGTERM;
2172 else if (strcmp(signame, "USR1") == 0)
2173 sig = SIGUSR1;
2174 else if (strcmp(signame, "USR2") == 0)
2175 sig = SIGUSR2;
2176 else
2177 {
2178 write_stderr(_("%s: unrecognized signal name \"%s\"\n"), progname, signame);
2179 do_advice();
2180 exit(1);
2181 }
2182 }
2183
2184
2185 #ifdef WIN32
2186 static void
set_starttype(char * starttypeopt)2187 set_starttype(char *starttypeopt)
2188 {
2189 if (strcmp(starttypeopt, "a") == 0 || strcmp(starttypeopt, "auto") == 0)
2190 pgctl_start_type = SERVICE_AUTO_START;
2191 else if (strcmp(starttypeopt, "d") == 0 || strcmp(starttypeopt, "demand") == 0)
2192 pgctl_start_type = SERVICE_DEMAND_START;
2193 else
2194 {
2195 write_stderr(_("%s: unrecognized start type \"%s\"\n"), progname, starttypeopt);
2196 do_advice();
2197 exit(1);
2198 }
2199 }
2200 #endif
2201
2202 /*
2203 * adjust_data_dir
2204 *
2205 * If a configuration-only directory was specified, find the real data dir.
2206 */
2207 static void
adjust_data_dir(void)2208 adjust_data_dir(void)
2209 {
2210 char filename[MAXPGPATH];
2211 char *my_exec_path,
2212 *cmd;
2213 FILE *fd;
2214
2215 /* do nothing if we're working without knowledge of data dir */
2216 if (pg_config == NULL)
2217 return;
2218
2219 /* If there is no postgresql.conf, it can't be a config-only dir */
2220 snprintf(filename, sizeof(filename), "%s/postgresql.conf", pg_config);
2221 if ((fd = fopen(filename, "r")) == NULL)
2222 return;
2223 fclose(fd);
2224
2225 /* If PG_VERSION exists, it can't be a config-only dir */
2226 snprintf(filename, sizeof(filename), "%s/PG_VERSION", pg_config);
2227 if ((fd = fopen(filename, "r")) != NULL)
2228 {
2229 fclose(fd);
2230 return;
2231 }
2232
2233 /* Must be a configuration directory, so find the data directory */
2234
2235 /* we use a private my_exec_path to avoid interfering with later uses */
2236 if (exec_path == NULL)
2237 my_exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
2238 else
2239 my_exec_path = pg_strdup(exec_path);
2240
2241 /* it's important for -C to be the first option, see main.c */
2242 cmd = psprintf("\"%s\" -C data_directory %s%s",
2243 my_exec_path,
2244 pgdata_opt ? pgdata_opt : "",
2245 post_opts ? post_opts : "");
2246
2247 fd = popen(cmd, "r");
2248 if (fd == NULL || fgets(filename, sizeof(filename), fd) == NULL)
2249 {
2250 write_stderr(_("%s: could not determine the data directory using command \"%s\"\n"), progname, cmd);
2251 exit(1);
2252 }
2253 pclose(fd);
2254 free(my_exec_path);
2255
2256 /* Remove trailing newline */
2257 if (strchr(filename, '\n') != NULL)
2258 *strchr(filename, '\n') = '\0';
2259
2260 free(pg_data);
2261 pg_data = pg_strdup(filename);
2262 canonicalize_path(pg_data);
2263 }
2264
2265
2266 static DBState
get_control_dbstate(void)2267 get_control_dbstate(void)
2268 {
2269 DBState ret;
2270 bool crc_ok;
2271 ControlFileData *control_file_data = get_controlfile(pg_data, &crc_ok);
2272
2273 if (!crc_ok)
2274 {
2275 write_stderr(_("%s: control file appears to be corrupt\n"), progname);
2276 exit(1);
2277 }
2278
2279 ret = control_file_data->state;
2280 pfree(control_file_data);
2281 return ret;
2282 }
2283
2284
2285 int
main(int argc,char ** argv)2286 main(int argc, char **argv)
2287 {
2288 static struct option long_options[] = {
2289 {"help", no_argument, NULL, '?'},
2290 {"version", no_argument, NULL, 'V'},
2291 {"log", required_argument, NULL, 'l'},
2292 {"mode", required_argument, NULL, 'm'},
2293 {"pgdata", required_argument, NULL, 'D'},
2294 {"options", required_argument, NULL, 'o'},
2295 {"silent", no_argument, NULL, 's'},
2296 {"timeout", required_argument, NULL, 't'},
2297 {"core-files", no_argument, NULL, 'c'},
2298 {"wait", no_argument, NULL, 'w'},
2299 {"no-wait", no_argument, NULL, 'W'},
2300 {NULL, 0, NULL, 0}
2301 };
2302
2303 char *env_wait;
2304 int option_index;
2305 int c;
2306 pgpid_t killproc = 0;
2307
2308 pg_logging_init(argv[0]);
2309 progname = get_progname(argv[0]);
2310 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_ctl"));
2311 start_time = time(NULL);
2312
2313 /*
2314 * save argv[0] so do_start() can look for the postmaster if necessary. we
2315 * don't look for postmaster here because in many cases we won't need it.
2316 */
2317 argv0 = argv[0];
2318
2319 /* Set restrictive mode mask until PGDATA permissions are checked */
2320 umask(PG_MODE_MASK_OWNER);
2321
2322 /* support --help and --version even if invoked as root */
2323 if (argc > 1)
2324 {
2325 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
2326 {
2327 do_help();
2328 exit(0);
2329 }
2330 else if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
2331 {
2332 puts("pg_ctl (PostgreSQL) " PG_VERSION);
2333 exit(0);
2334 }
2335 }
2336
2337 /*
2338 * Disallow running as root, to forestall any possible security holes.
2339 */
2340 #ifndef WIN32
2341 if (geteuid() == 0)
2342 {
2343 write_stderr(_("%s: cannot be run as root\n"
2344 "Please log in (using, e.g., \"su\") as the "
2345 "(unprivileged) user that will\n"
2346 "own the server process.\n"),
2347 progname);
2348 exit(1);
2349 }
2350 #endif
2351
2352 env_wait = getenv("PGCTLTIMEOUT");
2353 if (env_wait != NULL)
2354 wait_seconds = atoi(env_wait);
2355
2356 /*
2357 * 'Action' can be before or after args so loop over both. Some
2358 * getopt_long() implementations will reorder argv[] to place all flags
2359 * first (GNU?), but we don't rely on it. Our /port version doesn't do
2360 * that.
2361 */
2362 optind = 1;
2363
2364 /* process command-line options */
2365 while (optind < argc)
2366 {
2367 while ((c = getopt_long(argc, argv, "cD:e:l:m:N:o:p:P:sS:t:U:wW",
2368 long_options, &option_index)) != -1)
2369 {
2370 switch (c)
2371 {
2372 case 'D':
2373 {
2374 char *pgdata_D;
2375 char *env_var;
2376
2377 pgdata_D = pg_strdup(optarg);
2378 canonicalize_path(pgdata_D);
2379 env_var = psprintf("PGDATA=%s", pgdata_D);
2380 putenv(env_var);
2381
2382 /*
2383 * We could pass PGDATA just in an environment
2384 * variable but we do -D too for clearer postmaster
2385 * 'ps' display
2386 */
2387 pgdata_opt = psprintf("-D \"%s\" ", pgdata_D);
2388 break;
2389 }
2390 case 'e':
2391 event_source = pg_strdup(optarg);
2392 break;
2393 case 'l':
2394 log_file = pg_strdup(optarg);
2395 break;
2396 case 'm':
2397 set_mode(optarg);
2398 break;
2399 case 'N':
2400 register_servicename = pg_strdup(optarg);
2401 break;
2402 case 'o':
2403 /* append option? */
2404 if (!post_opts)
2405 post_opts = pg_strdup(optarg);
2406 else
2407 {
2408 char *old_post_opts = post_opts;
2409
2410 post_opts = psprintf("%s %s", old_post_opts, optarg);
2411 free(old_post_opts);
2412 }
2413 break;
2414 case 'p':
2415 exec_path = pg_strdup(optarg);
2416 break;
2417 case 'P':
2418 register_password = pg_strdup(optarg);
2419 break;
2420 case 's':
2421 silent_mode = true;
2422 break;
2423 case 'S':
2424 #ifdef WIN32
2425 set_starttype(optarg);
2426 #else
2427 write_stderr(_("%s: -S option not supported on this platform\n"),
2428 progname);
2429 exit(1);
2430 #endif
2431 break;
2432 case 't':
2433 wait_seconds = atoi(optarg);
2434 wait_seconds_arg = true;
2435 break;
2436 case 'U':
2437 if (strchr(optarg, '\\'))
2438 register_username = pg_strdup(optarg);
2439 else
2440 /* Prepend .\ for local accounts */
2441 register_username = psprintf(".\\%s", optarg);
2442 break;
2443 case 'w':
2444 do_wait = true;
2445 break;
2446 case 'W':
2447 do_wait = false;
2448 break;
2449 case 'c':
2450 allow_core_files = true;
2451 break;
2452 default:
2453 /* getopt_long already issued a suitable error message */
2454 do_advice();
2455 exit(1);
2456 }
2457 }
2458
2459 /* Process an action */
2460 if (optind < argc)
2461 {
2462 if (ctl_command != NO_COMMAND)
2463 {
2464 write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]);
2465 do_advice();
2466 exit(1);
2467 }
2468
2469 if (strcmp(argv[optind], "init") == 0
2470 || strcmp(argv[optind], "initdb") == 0)
2471 ctl_command = INIT_COMMAND;
2472 else if (strcmp(argv[optind], "start") == 0)
2473 ctl_command = START_COMMAND;
2474 else if (strcmp(argv[optind], "stop") == 0)
2475 ctl_command = STOP_COMMAND;
2476 else if (strcmp(argv[optind], "restart") == 0)
2477 ctl_command = RESTART_COMMAND;
2478 else if (strcmp(argv[optind], "reload") == 0)
2479 ctl_command = RELOAD_COMMAND;
2480 else if (strcmp(argv[optind], "status") == 0)
2481 ctl_command = STATUS_COMMAND;
2482 else if (strcmp(argv[optind], "promote") == 0)
2483 ctl_command = PROMOTE_COMMAND;
2484 else if (strcmp(argv[optind], "logrotate") == 0)
2485 ctl_command = LOGROTATE_COMMAND;
2486 else if (strcmp(argv[optind], "kill") == 0)
2487 {
2488 if (argc - optind < 3)
2489 {
2490 write_stderr(_("%s: missing arguments for kill mode\n"), progname);
2491 do_advice();
2492 exit(1);
2493 }
2494 ctl_command = KILL_COMMAND;
2495 set_sig(argv[++optind]);
2496 killproc = atol(argv[++optind]);
2497 }
2498 #ifdef WIN32
2499 else if (strcmp(argv[optind], "register") == 0)
2500 ctl_command = REGISTER_COMMAND;
2501 else if (strcmp(argv[optind], "unregister") == 0)
2502 ctl_command = UNREGISTER_COMMAND;
2503 else if (strcmp(argv[optind], "runservice") == 0)
2504 ctl_command = RUN_AS_SERVICE_COMMAND;
2505 #endif
2506 else
2507 {
2508 write_stderr(_("%s: unrecognized operation mode \"%s\"\n"), progname, argv[optind]);
2509 do_advice();
2510 exit(1);
2511 }
2512 optind++;
2513 }
2514 }
2515
2516 if (ctl_command == NO_COMMAND)
2517 {
2518 write_stderr(_("%s: no operation specified\n"), progname);
2519 do_advice();
2520 exit(1);
2521 }
2522
2523 /* Note we put any -D switch into the env var above */
2524 pg_config = getenv("PGDATA");
2525 if (pg_config)
2526 {
2527 pg_config = pg_strdup(pg_config);
2528 canonicalize_path(pg_config);
2529 pg_data = pg_strdup(pg_config);
2530 }
2531
2532 /* -D might point at config-only directory; if so find the real PGDATA */
2533 adjust_data_dir();
2534
2535 /* Complain if -D needed and not provided */
2536 if (pg_config == NULL &&
2537 ctl_command != KILL_COMMAND && ctl_command != UNREGISTER_COMMAND)
2538 {
2539 write_stderr(_("%s: no database directory specified and environment variable PGDATA unset\n"),
2540 progname);
2541 do_advice();
2542 exit(1);
2543 }
2544
2545 if (ctl_command == RELOAD_COMMAND)
2546 {
2547 sig = SIGHUP;
2548 do_wait = false;
2549 }
2550
2551 if (pg_data)
2552 {
2553 snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);
2554 snprintf(version_file, MAXPGPATH, "%s/PG_VERSION", pg_data);
2555 snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
2556 snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data);
2557
2558 /*
2559 * Set mask based on PGDATA permissions,
2560 *
2561 * Don't error here if the data directory cannot be stat'd. This is
2562 * handled differently based on the command and we don't want to
2563 * interfere with that logic.
2564 */
2565 if (GetDataDirectoryCreatePerm(pg_data))
2566 umask(pg_mode_mask);
2567 }
2568
2569 switch (ctl_command)
2570 {
2571 case INIT_COMMAND:
2572 do_init();
2573 break;
2574 case STATUS_COMMAND:
2575 do_status();
2576 break;
2577 case START_COMMAND:
2578 do_start();
2579 break;
2580 case STOP_COMMAND:
2581 do_stop();
2582 break;
2583 case RESTART_COMMAND:
2584 do_restart();
2585 break;
2586 case RELOAD_COMMAND:
2587 do_reload();
2588 break;
2589 case PROMOTE_COMMAND:
2590 do_promote();
2591 break;
2592 case LOGROTATE_COMMAND:
2593 do_logrotate();
2594 break;
2595 case KILL_COMMAND:
2596 do_kill(killproc);
2597 break;
2598 #ifdef WIN32
2599 case REGISTER_COMMAND:
2600 pgwin32_doRegister();
2601 break;
2602 case UNREGISTER_COMMAND:
2603 pgwin32_doUnregister();
2604 break;
2605 case RUN_AS_SERVICE_COMMAND:
2606 pgwin32_doRunAsService();
2607 break;
2608 #endif
2609 default:
2610 break;
2611 }
2612
2613 exit(0);
2614 }
2615