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