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