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