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