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