PageRenderTime 60ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/src/bin/pg_ctl/pg_ctl.c

https://github.com/larkly/postgres-docker
C | 2380 lines | 1723 code | 308 blank | 349 comment | 431 complexity | fd1cba625a5353f524c4e443bbd5a308 MD5 | raw file
Possible License(s): AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /*-------------------------------------------------------------------------
  2. *
  3. * pg_ctl --- start/stops/restarts the PostgreSQL server
  4. *
  5. * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
  6. *
  7. * src/bin/pg_ctl/pg_ctl.c
  8. *
  9. *-------------------------------------------------------------------------
  10. */
  11. #ifdef WIN32
  12. /*
  13. * Need this to get defines for restricted tokens and jobs. And it
  14. * has to be set before any header from the Win32 API is loaded.
  15. */
  16. #define _WIN32_WINNT 0x0501
  17. #endif
  18. #include "postgres_fe.h"
  19. #include "libpq-fe.h"
  20. #include "pqexpbuffer.h"
  21. #include <fcntl.h>
  22. #include <locale.h>
  23. #include <signal.h>
  24. #include <time.h>
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <unistd.h>
  28. #ifdef HAVE_SYS_RESOURCE_H
  29. #include <sys/time.h>
  30. #include <sys/resource.h>
  31. #endif
  32. #include "getopt_long.h"
  33. #include "miscadmin.h"
  34. #if defined(__CYGWIN__)
  35. #include <sys/cygwin.h>
  36. #include <windows.h>
  37. /* Cygwin defines WIN32 in windows.h, but we don't want it. */
  38. #undef WIN32
  39. #endif
  40. /* PID can be negative for standalone backend */
  41. typedef long pgpid_t;
  42. typedef enum
  43. {
  44. SMART_MODE,
  45. FAST_MODE,
  46. IMMEDIATE_MODE
  47. } ShutdownMode;
  48. typedef enum
  49. {
  50. NO_COMMAND = 0,
  51. INIT_COMMAND,
  52. START_COMMAND,
  53. STOP_COMMAND,
  54. RESTART_COMMAND,
  55. RELOAD_COMMAND,
  56. STATUS_COMMAND,
  57. PROMOTE_COMMAND,
  58. KILL_COMMAND,
  59. REGISTER_COMMAND,
  60. UNREGISTER_COMMAND,
  61. RUN_AS_SERVICE_COMMAND
  62. } CtlCommand;
  63. #define DEFAULT_WAIT 60
  64. static bool do_wait = false;
  65. static bool wait_set = false;
  66. static int wait_seconds = DEFAULT_WAIT;
  67. static bool silent_mode = false;
  68. static ShutdownMode shutdown_mode = SMART_MODE;
  69. static int sig = SIGTERM; /* default */
  70. static CtlCommand ctl_command = NO_COMMAND;
  71. static char *pg_data = NULL;
  72. static char *pg_config = NULL;
  73. static char *pgdata_opt = NULL;
  74. static char *post_opts = NULL;
  75. static const char *progname;
  76. static char *log_file = NULL;
  77. static char *exec_path = NULL;
  78. static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
  79. static char *register_username = NULL;
  80. static char *register_password = NULL;
  81. static char *argv0 = NULL;
  82. static bool allow_core_files = false;
  83. static time_t start_time;
  84. static char postopts_file[MAXPGPATH];
  85. static char version_file[MAXPGPATH];
  86. static char pid_file[MAXPGPATH];
  87. static char backup_file[MAXPGPATH];
  88. static char recovery_file[MAXPGPATH];
  89. static char promote_file[MAXPGPATH];
  90. #if defined(WIN32) || defined(__CYGWIN__)
  91. static DWORD pgctl_start_type = SERVICE_AUTO_START;
  92. static SERVICE_STATUS status;
  93. static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
  94. static HANDLE shutdownHandles[2];
  95. static pid_t postmasterPID = -1;
  96. #define shutdownEvent shutdownHandles[0]
  97. #define postmasterProcess shutdownHandles[1]
  98. #endif
  99. static void
  100. write_stderr(const char *fmt,...)
  101. /* This extension allows gcc to check the format string for consistency with
  102. the supplied arguments. */
  103. __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
  104. static void do_advice(void);
  105. static void do_help(void);
  106. static void set_mode(char *modeopt);
  107. static void set_sig(char *signame);
  108. static void do_init(void);
  109. static void do_start(void);
  110. static void do_stop(void);
  111. static void do_restart(void);
  112. static void do_reload(void);
  113. static void do_status(void);
  114. static void do_promote(void);
  115. static void do_kill(pgpid_t pid);
  116. static void print_msg(const char *msg);
  117. static void adjust_data_dir(void);
  118. #if defined(WIN32) || defined(__CYGWIN__)
  119. #if (_MSC_VER >= 1800)
  120. #include <versionhelpers.h>
  121. #else
  122. static bool IsWindowsXPOrGreater(void);
  123. static bool IsWindows7OrGreater(void);
  124. #endif
  125. static bool pgwin32_IsInstalled(SC_HANDLE);
  126. static char *pgwin32_CommandLine(bool);
  127. static void pgwin32_doRegister(void);
  128. static void pgwin32_doUnregister(void);
  129. static void pgwin32_SetServiceStatus(DWORD);
  130. static void WINAPI pgwin32_ServiceHandler(DWORD);
  131. static void WINAPI pgwin32_ServiceMain(DWORD, LPTSTR *);
  132. static void pgwin32_doRunAsService(void);
  133. static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service);
  134. #endif
  135. static pgpid_t get_pgpid(bool is_status_request);
  136. static char **readfile(const char *path);
  137. static void free_readfile(char **optlines);
  138. static int start_postmaster(void);
  139. static void read_post_opts(void);
  140. static PGPing test_postmaster_connection(bool);
  141. static bool postmaster_is_alive(pid_t pid);
  142. #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
  143. static void unlimit_core_size(void);
  144. #endif
  145. #if defined(WIN32) || defined(__CYGWIN__)
  146. static void
  147. write_eventlog(int level, const char *line)
  148. {
  149. static HANDLE evtHandle = INVALID_HANDLE_VALUE;
  150. if (silent_mode && level == EVENTLOG_INFORMATION_TYPE)
  151. return;
  152. if (evtHandle == INVALID_HANDLE_VALUE)
  153. {
  154. evtHandle = RegisterEventSource(NULL, "PostgreSQL");
  155. if (evtHandle == NULL)
  156. {
  157. evtHandle = INVALID_HANDLE_VALUE;
  158. return;
  159. }
  160. }
  161. ReportEvent(evtHandle,
  162. level,
  163. 0,
  164. 0, /* All events are Id 0 */
  165. NULL,
  166. 1,
  167. 0,
  168. &line,
  169. NULL);
  170. }
  171. #endif
  172. /*
  173. * Write errors to stderr (or by equal means when stderr is
  174. * not available).
  175. */
  176. static void
  177. write_stderr(const char *fmt,...)
  178. {
  179. va_list ap;
  180. va_start(ap, fmt);
  181. #if !defined(WIN32) && !defined(__CYGWIN__)
  182. /* On Unix, we just fprintf to stderr */
  183. vfprintf(stderr, fmt, ap);
  184. #else
  185. /*
  186. * On Win32, we print to stderr if running on a console, or write to
  187. * eventlog if running as a service
  188. */
  189. if (!isatty(fileno(stderr))) /* Running as a service */
  190. {
  191. char errbuf[2048]; /* Arbitrary size? */
  192. vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
  193. write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
  194. }
  195. else
  196. /* Not running as service, write to stderr */
  197. vfprintf(stderr, fmt, ap);
  198. #endif
  199. va_end(ap);
  200. }
  201. /*
  202. * Given an already-localized string, print it to stdout unless the
  203. * user has specified that no messages should be printed.
  204. */
  205. static void
  206. print_msg(const char *msg)
  207. {
  208. if (!silent_mode)
  209. {
  210. fputs(msg, stdout);
  211. fflush(stdout);
  212. }
  213. }
  214. static pgpid_t
  215. get_pgpid(bool is_status_request)
  216. {
  217. FILE *pidf;
  218. long pid;
  219. struct stat statbuf;
  220. if (stat(pg_data, &statbuf) != 0)
  221. {
  222. if (errno == ENOENT)
  223. write_stderr(_("%s: directory \"%s\" does not exist\n"), progname,
  224. pg_data);
  225. else
  226. write_stderr(_("%s: could not access directory \"%s\": %s\n"), progname,
  227. pg_data, strerror(errno));
  228. /*
  229. * The Linux Standard Base Core Specification 3.1 says this should
  230. * return '4, program or service status is unknown'
  231. * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
  232. */
  233. exit(is_status_request ? 4 : 1);
  234. }
  235. if (stat(version_file, &statbuf) != 0 && errno == ENOENT)
  236. {
  237. write_stderr(_("%s: directory \"%s\" is not a database cluster directory\n"),
  238. progname, pg_data);
  239. exit(is_status_request ? 4 : 1);
  240. }
  241. pidf = fopen(pid_file, "r");
  242. if (pidf == NULL)
  243. {
  244. /* No pid file, not an error on startup */
  245. if (errno == ENOENT)
  246. return 0;
  247. else
  248. {
  249. write_stderr(_("%s: could not open PID file \"%s\": %s\n"),
  250. progname, pid_file, strerror(errno));
  251. exit(1);
  252. }
  253. }
  254. if (fscanf(pidf, "%ld", &pid) != 1)
  255. {
  256. /* Is the file empty? */
  257. if (ftell(pidf) == 0 && feof(pidf))
  258. write_stderr(_("%s: the PID file \"%s\" is empty\n"),
  259. progname, pid_file);
  260. else
  261. write_stderr(_("%s: invalid data in PID file \"%s\"\n"),
  262. progname, pid_file);
  263. exit(1);
  264. }
  265. fclose(pidf);
  266. return (pgpid_t) pid;
  267. }
  268. /*
  269. * get the lines from a text file - return NULL if file can't be opened
  270. */
  271. static char **
  272. readfile(const char *path)
  273. {
  274. int fd;
  275. int nlines;
  276. char **result;
  277. char *buffer;
  278. char *linebegin;
  279. int i;
  280. int n;
  281. int len;
  282. struct stat statbuf;
  283. /*
  284. * Slurp the file into memory.
  285. *
  286. * The file can change concurrently, so we read the whole file into memory
  287. * with a single read() call. That's not guaranteed to get an atomic
  288. * snapshot, but in practice, for a small file, it's close enough for the
  289. * current use.
  290. */
  291. fd = open(path, O_RDONLY | PG_BINARY, 0);
  292. if (fd < 0)
  293. return NULL;
  294. if (fstat(fd, &statbuf) < 0)
  295. {
  296. close(fd);
  297. return NULL;
  298. }
  299. if (statbuf.st_size == 0)
  300. {
  301. /* empty file */
  302. close(fd);
  303. result = (char **) pg_malloc(sizeof(char *));
  304. *result = NULL;
  305. return result;
  306. }
  307. buffer = pg_malloc(statbuf.st_size + 1);
  308. len = read(fd, buffer, statbuf.st_size + 1);
  309. close(fd);
  310. if (len != statbuf.st_size)
  311. {
  312. /* oops, the file size changed between fstat and read */
  313. free(buffer);
  314. return NULL;
  315. }
  316. /*
  317. * Count newlines. We expect there to be a newline after each full line,
  318. * including one at the end of file. If there isn't a newline at the end,
  319. * any characters after the last newline will be ignored.
  320. */
  321. nlines = 0;
  322. for (i = 0; i < len; i++)
  323. {
  324. if (buffer[i] == '\n')
  325. nlines++;
  326. }
  327. /* set up the result buffer */
  328. result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
  329. /* now split the buffer into lines */
  330. linebegin = buffer;
  331. n = 0;
  332. for (i = 0; i < len; i++)
  333. {
  334. if (buffer[i] == '\n')
  335. {
  336. int slen = &buffer[i] - linebegin + 1;
  337. char *linebuf = pg_malloc(slen + 1);
  338. memcpy(linebuf, linebegin, slen);
  339. linebuf[slen] = '\0';
  340. result[n++] = linebuf;
  341. linebegin = &buffer[i + 1];
  342. }
  343. }
  344. result[n] = NULL;
  345. free(buffer);
  346. return result;
  347. }
  348. /*
  349. * Free memory allocated for optlines through readfile()
  350. */
  351. static void
  352. free_readfile(char **optlines)
  353. {
  354. char *curr_line = NULL;
  355. int i = 0;
  356. if (!optlines)
  357. return;
  358. while ((curr_line = optlines[i++]))
  359. free(curr_line);
  360. free(optlines);
  361. return;
  362. }
  363. /*
  364. * start/test/stop routines
  365. */
  366. static int
  367. start_postmaster(void)
  368. {
  369. char cmd[MAXPGPATH];
  370. #ifndef WIN32
  371. /*
  372. * Since there might be quotes to handle here, it is easier simply to pass
  373. * everything to a shell to process them.
  374. *
  375. * XXX it would be better to fork and exec so that we would know the child
  376. * postmaster's PID directly; then test_postmaster_connection could use
  377. * the PID without having to rely on reading it back from the pidfile.
  378. */
  379. if (log_file != NULL)
  380. snprintf(cmd, MAXPGPATH, "\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1 &",
  381. exec_path, pgdata_opt, post_opts,
  382. DEVNULL, log_file);
  383. else
  384. snprintf(cmd, MAXPGPATH, "\"%s\" %s%s < \"%s\" 2>&1 &",
  385. exec_path, pgdata_opt, post_opts, DEVNULL);
  386. return system(cmd);
  387. #else /* WIN32 */
  388. /*
  389. * On win32 we don't use system(). So we don't need to use & (which would
  390. * be START /B on win32). However, we still call the shell (CMD.EXE) with
  391. * it to handle redirection etc.
  392. */
  393. PROCESS_INFORMATION pi;
  394. if (log_file != NULL)
  395. snprintf(cmd, MAXPGPATH, "CMD /C \"\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1\"",
  396. exec_path, pgdata_opt, post_opts, DEVNULL, log_file);
  397. else
  398. snprintf(cmd, MAXPGPATH, "CMD /C \"\"%s\" %s%s < \"%s\" 2>&1\"",
  399. exec_path, pgdata_opt, post_opts, DEVNULL);
  400. if (!CreateRestrictedProcess(cmd, &pi, false))
  401. return GetLastError();
  402. CloseHandle(pi.hProcess);
  403. CloseHandle(pi.hThread);
  404. return 0;
  405. #endif /* WIN32 */
  406. }
  407. /*
  408. * Find the pgport and try a connection
  409. *
  410. * Note that the checkpoint parameter enables a Windows service control
  411. * manager checkpoint, it's got nothing to do with database checkpoints!!
  412. */
  413. static PGPing
  414. test_postmaster_connection(bool do_checkpoint)
  415. {
  416. PGPing ret = PQPING_NO_RESPONSE;
  417. bool found_stale_pidfile = false;
  418. pgpid_t pm_pid = 0;
  419. char connstr[MAXPGPATH * 2 + 256];
  420. int i;
  421. /* if requested wait time is zero, return "still starting up" code */
  422. if (wait_seconds <= 0)
  423. return PQPING_REJECT;
  424. connstr[0] = '\0';
  425. for (i = 0; i < wait_seconds; i++)
  426. {
  427. /* Do we need a connection string? */
  428. if (connstr[0] == '\0')
  429. {
  430. /*----------
  431. * The number of lines in postmaster.pid tells us several things:
  432. *
  433. * # of lines
  434. * 0 lock file created but status not written
  435. * 2 pre-9.1 server, shared memory not created
  436. * 3 pre-9.1 server, shared memory created
  437. * 5 9.1+ server, ports not opened
  438. * 6 9.1+ server, shared memory not created
  439. * 7 9.1+ server, shared memory created
  440. *
  441. * This code does not support pre-9.1 servers. On Unix machines
  442. * we could consider extracting the port number from the shmem
  443. * key, but that (a) is not robust, and (b) doesn't help with
  444. * finding out the socket directory. And it wouldn't work anyway
  445. * on Windows.
  446. *
  447. * If we see less than 6 lines in postmaster.pid, just keep
  448. * waiting.
  449. *----------
  450. */
  451. char **optlines;
  452. /* Try to read the postmaster.pid file */
  453. if ((optlines = readfile(pid_file)) != NULL &&
  454. optlines[0] != NULL &&
  455. optlines[1] != NULL &&
  456. optlines[2] != NULL)
  457. {
  458. if (optlines[3] == NULL)
  459. {
  460. /* File is exactly three lines, must be pre-9.1 */
  461. write_stderr(_("\n%s: -w option is not supported when starting a pre-9.1 server\n"),
  462. progname);
  463. return PQPING_NO_ATTEMPT;
  464. }
  465. else if (optlines[4] != NULL &&
  466. optlines[5] != NULL)
  467. {
  468. /* File is complete enough for us, parse it */
  469. long pmpid;
  470. time_t pmstart;
  471. /*
  472. * Make sanity checks. If it's for a standalone backend
  473. * (negative PID), or the recorded start time is before
  474. * pg_ctl started, then either we are looking at the wrong
  475. * data directory, or this is a pre-existing pidfile that
  476. * hasn't (yet?) been overwritten by our child postmaster.
  477. * Allow 2 seconds slop for possible cross-process clock
  478. * skew.
  479. */
  480. pmpid = atol(optlines[LOCK_FILE_LINE_PID - 1]);
  481. pmstart = atol(optlines[LOCK_FILE_LINE_START_TIME - 1]);
  482. if (pmpid <= 0 || pmstart < start_time - 2)
  483. {
  484. /*
  485. * Set flag to report stale pidfile if it doesn't get
  486. * overwritten before we give up waiting.
  487. */
  488. found_stale_pidfile = true;
  489. }
  490. else
  491. {
  492. /*
  493. * OK, seems to be a valid pidfile from our child.
  494. */
  495. int portnum;
  496. char *sockdir;
  497. char *hostaddr;
  498. char host_str[MAXPGPATH];
  499. found_stale_pidfile = false;
  500. pm_pid = (pgpid_t) pmpid;
  501. /*
  502. * Extract port number and host string to use. Prefer
  503. * using Unix socket if available.
  504. */
  505. portnum = atoi(optlines[LOCK_FILE_LINE_PORT - 1]);
  506. sockdir = optlines[LOCK_FILE_LINE_SOCKET_DIR - 1];
  507. hostaddr = optlines[LOCK_FILE_LINE_LISTEN_ADDR - 1];
  508. /*
  509. * While unix_socket_directories can accept relative
  510. * directories, libpq's host parameter must have a
  511. * leading slash to indicate a socket directory. So,
  512. * ignore sockdir if it's relative, and try to use TCP
  513. * instead.
  514. */
  515. if (sockdir[0] == '/')
  516. strlcpy(host_str, sockdir, sizeof(host_str));
  517. else
  518. strlcpy(host_str, hostaddr, sizeof(host_str));
  519. /* remove trailing newline */
  520. if (strchr(host_str, '\n') != NULL)
  521. *strchr(host_str, '\n') = '\0';
  522. /* Fail if couldn't get either sockdir or host addr */
  523. if (host_str[0] == '\0')
  524. {
  525. write_stderr(_("\n%s: -w option cannot use a relative socket directory specification\n"),
  526. progname);
  527. return PQPING_NO_ATTEMPT;
  528. }
  529. /* If postmaster is listening on "*", use localhost */
  530. if (strcmp(host_str, "*") == 0)
  531. strcpy(host_str, "localhost");
  532. /*
  533. * We need to set connect_timeout otherwise on Windows
  534. * the Service Control Manager (SCM) will probably
  535. * timeout first.
  536. */
  537. snprintf(connstr, sizeof(connstr),
  538. "dbname=postgres port=%d host='%s' connect_timeout=5",
  539. portnum, host_str);
  540. }
  541. }
  542. }
  543. /*
  544. * Free the results of readfile.
  545. *
  546. * This is safe to call even if optlines is NULL.
  547. */
  548. free_readfile(optlines);
  549. }
  550. /* If we have a connection string, ping the server */
  551. if (connstr[0] != '\0')
  552. {
  553. ret = PQping(connstr);
  554. if (ret == PQPING_OK || ret == PQPING_NO_ATTEMPT)
  555. break;
  556. }
  557. /*
  558. * The postmaster should create postmaster.pid very soon after being
  559. * started. If it's not there after we've waited 5 or more seconds,
  560. * assume startup failed and give up waiting. (Note this covers both
  561. * cases where the pidfile was never created, and where it was created
  562. * and then removed during postmaster exit.) Also, if there *is* a
  563. * file there but it appears stale, issue a suitable warning and give
  564. * up waiting.
  565. */
  566. if (i >= 5)
  567. {
  568. struct stat statbuf;
  569. if (stat(pid_file, &statbuf) != 0)
  570. return PQPING_NO_RESPONSE;
  571. if (found_stale_pidfile)
  572. {
  573. write_stderr(_("\n%s: this data directory appears to be running a pre-existing postmaster\n"),
  574. progname);
  575. return PQPING_NO_RESPONSE;
  576. }
  577. }
  578. /*
  579. * If we've been able to identify the child postmaster's PID, check
  580. * the process is still alive. This covers cases where the postmaster
  581. * successfully created the pidfile but then crashed without removing
  582. * it.
  583. */
  584. if (pm_pid > 0 && !postmaster_is_alive((pid_t) pm_pid))
  585. return PQPING_NO_RESPONSE;
  586. /* No response, or startup still in process; wait */
  587. #if defined(WIN32)
  588. if (do_checkpoint)
  589. {
  590. /*
  591. * Increment the wait hint by 6 secs (connection timeout + sleep)
  592. * We must do this to indicate to the SCM that our startup time is
  593. * changing, otherwise it'll usually send a stop signal after 20
  594. * seconds, despite incrementing the checkpoint counter.
  595. */
  596. status.dwWaitHint += 6000;
  597. status.dwCheckPoint++;
  598. SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
  599. }
  600. else
  601. #endif
  602. print_msg(".");
  603. pg_usleep(1000000); /* 1 sec */
  604. }
  605. /* return result of last call to PQping */
  606. return ret;
  607. }
  608. #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
  609. static void
  610. unlimit_core_size(void)
  611. {
  612. struct rlimit lim;
  613. getrlimit(RLIMIT_CORE, &lim);
  614. if (lim.rlim_max == 0)
  615. {
  616. write_stderr(_("%s: cannot set core file size limit; disallowed by hard limit\n"),
  617. progname);
  618. return;
  619. }
  620. else if (lim.rlim_max == RLIM_INFINITY || lim.rlim_cur < lim.rlim_max)
  621. {
  622. lim.rlim_cur = lim.rlim_max;
  623. setrlimit(RLIMIT_CORE, &lim);
  624. }
  625. }
  626. #endif
  627. static void
  628. read_post_opts(void)
  629. {
  630. if (post_opts == NULL)
  631. {
  632. post_opts = ""; /* default */
  633. if (ctl_command == RESTART_COMMAND)
  634. {
  635. char **optlines;
  636. optlines = readfile(postopts_file);
  637. if (optlines == NULL)
  638. {
  639. write_stderr(_("%s: could not read file \"%s\"\n"), progname, postopts_file);
  640. exit(1);
  641. }
  642. else if (optlines[0] == NULL || optlines[1] != NULL)
  643. {
  644. write_stderr(_("%s: option file \"%s\" must have exactly one line\n"),
  645. progname, postopts_file);
  646. exit(1);
  647. }
  648. else
  649. {
  650. int len;
  651. char *optline;
  652. char *arg1;
  653. optline = optlines[0];
  654. /* trim off line endings */
  655. len = strcspn(optline, "\r\n");
  656. optline[len] = '\0';
  657. /*
  658. * Are we at the first option, as defined by space and
  659. * double-quote?
  660. */
  661. if ((arg1 = strstr(optline, " \"")) != NULL)
  662. {
  663. *arg1 = '\0'; /* terminate so we get only program
  664. * name */
  665. post_opts = pg_strdup(arg1 + 1); /* point past whitespace */
  666. }
  667. if (exec_path == NULL)
  668. exec_path = pg_strdup(optline);
  669. }
  670. /* Free the results of readfile. */
  671. free_readfile(optlines);
  672. }
  673. }
  674. }
  675. static char *
  676. find_other_exec_or_die(const char *argv0, const char *target, const char *versionstr)
  677. {
  678. int ret;
  679. char *found_path;
  680. found_path = pg_malloc(MAXPGPATH);
  681. if ((ret = find_other_exec(argv0, target, versionstr, found_path)) < 0)
  682. {
  683. char full_path[MAXPGPATH];
  684. if (find_my_exec(argv0, full_path) < 0)
  685. strlcpy(full_path, progname, sizeof(full_path));
  686. if (ret == -1)
  687. write_stderr(_("The program \"%s\" is needed by %s "
  688. "but was not found in the\n"
  689. "same directory as \"%s\".\n"
  690. "Check your installation.\n"),
  691. target, progname, full_path);
  692. else
  693. write_stderr(_("The program \"%s\" was found by \"%s\"\n"
  694. "but was not the same version as %s.\n"
  695. "Check your installation.\n"),
  696. target, full_path, progname);
  697. exit(1);
  698. }
  699. return found_path;
  700. }
  701. static void
  702. do_init(void)
  703. {
  704. char cmd[MAXPGPATH];
  705. if (exec_path == NULL)
  706. exec_path = find_other_exec_or_die(argv0, "initdb", "initdb (PostgreSQL) " PG_VERSION "\n");
  707. if (pgdata_opt == NULL)
  708. pgdata_opt = "";
  709. if (post_opts == NULL)
  710. post_opts = "";
  711. if (!silent_mode)
  712. snprintf(cmd, MAXPGPATH, "\"%s\" %s%s",
  713. exec_path, pgdata_opt, post_opts);
  714. else
  715. snprintf(cmd, MAXPGPATH, "\"%s\" %s%s > \"%s\"",
  716. exec_path, pgdata_opt, post_opts, DEVNULL);
  717. if (system(cmd) != 0)
  718. {
  719. write_stderr(_("%s: database system initialization failed\n"), progname);
  720. exit(1);
  721. }
  722. }
  723. static void
  724. do_start(void)
  725. {
  726. pgpid_t old_pid = 0;
  727. int exitcode;
  728. if (ctl_command != RESTART_COMMAND)
  729. {
  730. old_pid = get_pgpid(false);
  731. if (old_pid != 0)
  732. write_stderr(_("%s: another server might be running; "
  733. "trying to start server anyway\n"),
  734. progname);
  735. }
  736. read_post_opts();
  737. /* No -D or -D already added during server start */
  738. if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
  739. pgdata_opt = "";
  740. if (exec_path == NULL)
  741. exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
  742. #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
  743. if (allow_core_files)
  744. unlimit_core_size();
  745. #endif
  746. /*
  747. * If possible, tell the postmaster our parent shell's PID (see the
  748. * comments in CreateLockFile() for motivation). Windows hasn't got
  749. * getppid() unfortunately.
  750. */
  751. #ifndef WIN32
  752. {
  753. static char env_var[32];
  754. snprintf(env_var, sizeof(env_var), "PG_GRANDPARENT_PID=%d",
  755. (int) getppid());
  756. putenv(env_var);
  757. }
  758. #endif
  759. exitcode = start_postmaster();
  760. if (exitcode != 0)
  761. {
  762. write_stderr(_("%s: could not start server: exit code was %d\n"),
  763. progname, exitcode);
  764. exit(1);
  765. }
  766. if (do_wait)
  767. {
  768. print_msg(_("waiting for server to start..."));
  769. switch (test_postmaster_connection(false))
  770. {
  771. case PQPING_OK:
  772. print_msg(_(" done\n"));
  773. print_msg(_("server started\n"));
  774. break;
  775. case PQPING_REJECT:
  776. print_msg(_(" stopped waiting\n"));
  777. print_msg(_("server is still starting up\n"));
  778. break;
  779. case PQPING_NO_RESPONSE:
  780. print_msg(_(" stopped waiting\n"));
  781. write_stderr(_("%s: could not start server\n"
  782. "Examine the log output.\n"),
  783. progname);
  784. exit(1);
  785. break;
  786. case PQPING_NO_ATTEMPT:
  787. print_msg(_(" failed\n"));
  788. write_stderr(_("%s: could not wait for server because of misconfiguration\n"),
  789. progname);
  790. exit(1);
  791. }
  792. }
  793. else
  794. print_msg(_("server starting\n"));
  795. }
  796. static void
  797. do_stop(void)
  798. {
  799. int cnt;
  800. pgpid_t pid;
  801. struct stat statbuf;
  802. pid = get_pgpid(false);
  803. if (pid == 0) /* no pid file */
  804. {
  805. write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
  806. write_stderr(_("Is server running?\n"));
  807. exit(1);
  808. }
  809. else if (pid < 0) /* standalone backend, not postmaster */
  810. {
  811. pid = -pid;
  812. write_stderr(_("%s: cannot stop server; "
  813. "single-user server is running (PID: %ld)\n"),
  814. progname, pid);
  815. exit(1);
  816. }
  817. if (kill((pid_t) pid, sig) != 0)
  818. {
  819. write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
  820. strerror(errno));
  821. exit(1);
  822. }
  823. if (!do_wait)
  824. {
  825. print_msg(_("server shutting down\n"));
  826. return;
  827. }
  828. else
  829. {
  830. /*
  831. * If backup_label exists, an online backup is running. Warn the user
  832. * that smart shutdown will wait for it to finish. However, if
  833. * recovery.conf is also present, we're recovering from an online
  834. * backup instead of performing one.
  835. */
  836. if (shutdown_mode == SMART_MODE &&
  837. stat(backup_file, &statbuf) == 0 &&
  838. stat(recovery_file, &statbuf) != 0)
  839. {
  840. print_msg(_("WARNING: online backup mode is active\n"
  841. "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
  842. }
  843. print_msg(_("waiting for server to shut down..."));
  844. for (cnt = 0; cnt < wait_seconds; cnt++)
  845. {
  846. if ((pid = get_pgpid(false)) != 0)
  847. {
  848. print_msg(".");
  849. pg_usleep(1000000); /* 1 sec */
  850. }
  851. else
  852. break;
  853. }
  854. if (pid != 0) /* pid file still exists */
  855. {
  856. print_msg(_(" failed\n"));
  857. write_stderr(_("%s: server does not shut down\n"), progname);
  858. if (shutdown_mode == SMART_MODE)
  859. write_stderr(_("HINT: The \"-m fast\" option immediately disconnects sessions rather than\n"
  860. "waiting for session-initiated disconnection.\n"));
  861. exit(1);
  862. }
  863. print_msg(_(" done\n"));
  864. print_msg(_("server stopped\n"));
  865. }
  866. }
  867. /*
  868. * restart/reload routines
  869. */
  870. static void
  871. do_restart(void)
  872. {
  873. int cnt;
  874. pgpid_t pid;
  875. struct stat statbuf;
  876. pid = get_pgpid(false);
  877. if (pid == 0) /* no pid file */
  878. {
  879. write_stderr(_("%s: PID file \"%s\" does not exist\n"),
  880. progname, pid_file);
  881. write_stderr(_("Is server running?\n"));
  882. write_stderr(_("starting server anyway\n"));
  883. do_start();
  884. return;
  885. }
  886. else if (pid < 0) /* standalone backend, not postmaster */
  887. {
  888. pid = -pid;
  889. if (postmaster_is_alive((pid_t) pid))
  890. {
  891. write_stderr(_("%s: cannot restart server; "
  892. "single-user server is running (PID: %ld)\n"),
  893. progname, pid);
  894. write_stderr(_("Please terminate the single-user server and try again.\n"));
  895. exit(1);
  896. }
  897. }
  898. if (postmaster_is_alive((pid_t) pid))
  899. {
  900. if (kill((pid_t) pid, sig) != 0)
  901. {
  902. write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), progname, pid,
  903. strerror(errno));
  904. exit(1);
  905. }
  906. /*
  907. * If backup_label exists, an online backup is running. Warn the user
  908. * that smart shutdown will wait for it to finish. However, if
  909. * recovery.conf is also present, we're recovering from an online
  910. * backup instead of performing one.
  911. */
  912. if (shutdown_mode == SMART_MODE &&
  913. stat(backup_file, &statbuf) == 0 &&
  914. stat(recovery_file, &statbuf) != 0)
  915. {
  916. print_msg(_("WARNING: online backup mode is active\n"
  917. "Shutdown will not complete until pg_stop_backup() is called.\n\n"));
  918. }
  919. print_msg(_("waiting for server to shut down..."));
  920. /* always wait for restart */
  921. for (cnt = 0; cnt < wait_seconds; cnt++)
  922. {
  923. if ((pid = get_pgpid(false)) != 0)
  924. {
  925. print_msg(".");
  926. pg_usleep(1000000); /* 1 sec */
  927. }
  928. else
  929. break;
  930. }
  931. if (pid != 0) /* pid file still exists */
  932. {
  933. print_msg(_(" failed\n"));
  934. write_stderr(_("%s: server does not shut down\n"), progname);
  935. if (shutdown_mode == SMART_MODE)
  936. write_stderr(_("HINT: The \"-m fast\" option immediately disconnects sessions rather than\n"
  937. "waiting for session-initiated disconnection.\n"));
  938. exit(1);
  939. }
  940. print_msg(_(" done\n"));
  941. print_msg(_("server stopped\n"));
  942. }
  943. else
  944. {
  945. write_stderr(_("%s: old server process (PID: %ld) seems to be gone\n"),
  946. progname, pid);
  947. write_stderr(_("starting server anyway\n"));
  948. }
  949. do_start();
  950. }
  951. static void
  952. do_reload(void)
  953. {
  954. pgpid_t pid;
  955. pid = get_pgpid(false);
  956. if (pid == 0) /* no pid file */
  957. {
  958. write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
  959. write_stderr(_("Is server running?\n"));
  960. exit(1);
  961. }
  962. else if (pid < 0) /* standalone backend, not postmaster */
  963. {
  964. pid = -pid;
  965. write_stderr(_("%s: cannot reload server; "
  966. "single-user server is running (PID: %ld)\n"),
  967. progname, pid);
  968. write_stderr(_("Please terminate the single-user server and try again.\n"));
  969. exit(1);
  970. }
  971. if (kill((pid_t) pid, sig) != 0)
  972. {
  973. write_stderr(_("%s: could not send reload signal (PID: %ld): %s\n"),
  974. progname, pid, strerror(errno));
  975. exit(1);
  976. }
  977. print_msg(_("server signaled\n"));
  978. }
  979. /*
  980. * promote
  981. */
  982. static void
  983. do_promote(void)
  984. {
  985. FILE *prmfile;
  986. pgpid_t pid;
  987. struct stat statbuf;
  988. pid = get_pgpid(false);
  989. if (pid == 0) /* no pid file */
  990. {
  991. write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
  992. write_stderr(_("Is server running?\n"));
  993. exit(1);
  994. }
  995. else if (pid < 0) /* standalone backend, not postmaster */
  996. {
  997. pid = -pid;
  998. write_stderr(_("%s: cannot promote server; "
  999. "single-user server is running (PID: %ld)\n"),
  1000. progname, pid);
  1001. exit(1);
  1002. }
  1003. /* If recovery.conf doesn't exist, the server is not in standby mode */
  1004. if (stat(recovery_file, &statbuf) != 0)
  1005. {
  1006. write_stderr(_("%s: cannot promote server; "
  1007. "server is not in standby mode\n"),
  1008. progname);
  1009. exit(1);
  1010. }
  1011. /*
  1012. * For 9.3 onwards, "fast" promotion is performed. Promotion with a full
  1013. * checkpoint is still possible by writing a file called
  1014. * "fallback_promote" instead of "promote"
  1015. */
  1016. snprintf(promote_file, MAXPGPATH, "%s/promote", pg_data);
  1017. if ((prmfile = fopen(promote_file, "w")) == NULL)
  1018. {
  1019. write_stderr(_("%s: could not create promote signal file \"%s\": %s\n"),
  1020. progname, promote_file, strerror(errno));
  1021. exit(1);
  1022. }
  1023. if (fclose(prmfile))
  1024. {
  1025. write_stderr(_("%s: could not write promote signal file \"%s\": %s\n"),
  1026. progname, promote_file, strerror(errno));
  1027. exit(1);
  1028. }
  1029. sig = SIGUSR1;
  1030. if (kill((pid_t) pid, sig) != 0)
  1031. {
  1032. write_stderr(_("%s: could not send promote signal (PID: %ld): %s\n"),
  1033. progname, pid, strerror(errno));
  1034. if (unlink(promote_file) != 0)
  1035. write_stderr(_("%s: could not remove promote signal file \"%s\": %s\n"),
  1036. progname, promote_file, strerror(errno));
  1037. exit(1);
  1038. }
  1039. print_msg(_("server promoting\n"));
  1040. }
  1041. /*
  1042. * utility routines
  1043. */
  1044. static bool
  1045. postmaster_is_alive(pid_t pid)
  1046. {
  1047. /*
  1048. * Test to see if the process is still there. Note that we do not
  1049. * consider an EPERM failure to mean that the process is still there;
  1050. * EPERM must mean that the given PID belongs to some other userid, and
  1051. * considering the permissions on $PGDATA, that means it's not the
  1052. * postmaster we are after.
  1053. *
  1054. * Don't believe that our own PID or parent shell's PID is the postmaster,
  1055. * either. (Windows hasn't got getppid(), though.)
  1056. */
  1057. if (pid == getpid())
  1058. return false;
  1059. #ifndef WIN32
  1060. if (pid == getppid())
  1061. return false;
  1062. #endif
  1063. if (kill(pid, 0) == 0)
  1064. return true;
  1065. return false;
  1066. }
  1067. static void
  1068. do_status(void)
  1069. {
  1070. pgpid_t pid;
  1071. pid = get_pgpid(true);
  1072. /* Is there a pid file? */
  1073. if (pid != 0)
  1074. {
  1075. /* standalone backend? */
  1076. if (pid < 0)
  1077. {
  1078. pid = -pid;
  1079. if (postmaster_is_alive((pid_t) pid))
  1080. {
  1081. printf(_("%s: single-user server is running (PID: %ld)\n"),
  1082. progname, pid);
  1083. return;
  1084. }
  1085. }
  1086. else
  1087. /* must be a postmaster */
  1088. {
  1089. if (postmaster_is_alive((pid_t) pid))
  1090. {
  1091. char **optlines;
  1092. char **curr_line;
  1093. printf(_("%s: server is running (PID: %ld)\n"),
  1094. progname, pid);
  1095. optlines = readfile(postopts_file);
  1096. if (optlines != NULL)
  1097. {
  1098. for (curr_line = optlines; *curr_line != NULL; curr_line++)
  1099. fputs(*curr_line, stdout);
  1100. /* Free the results of readfile */
  1101. free_readfile(optlines);
  1102. }
  1103. return;
  1104. }
  1105. }
  1106. }
  1107. printf(_("%s: no server running\n"), progname);
  1108. /*
  1109. * The Linux Standard Base Core Specification 3.1 says this should return
  1110. * '3, program is not running'
  1111. * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-gener
  1112. * ic/iniscrptact.html
  1113. */
  1114. exit(3);
  1115. }
  1116. static void
  1117. do_kill(pgpid_t pid)
  1118. {
  1119. if (kill((pid_t) pid, sig) != 0)
  1120. {
  1121. write_stderr(_("%s: could not send signal %d (PID: %ld): %s\n"),
  1122. progname, sig, pid, strerror(errno));
  1123. exit(1);
  1124. }
  1125. }
  1126. #if defined(WIN32) || defined(__CYGWIN__)
  1127. #if (_MSC_VER < 1800)
  1128. static bool
  1129. IsWindowsXPOrGreater(void)
  1130. {
  1131. OSVERSIONINFO osv;
  1132. osv.dwOSVersionInfoSize = sizeof(osv);
  1133. /* Windows XP = Version 5.1 */
  1134. return (!GetVersionEx(&osv) || /* could not get version */
  1135. osv.dwMajorVersion > 5 || (osv.dwMajorVersion == 5 && osv.dwMinorVersion >= 1));
  1136. }
  1137. static bool
  1138. IsWindows7OrGreater(void)
  1139. {
  1140. OSVERSIONINFO osv;
  1141. osv.dwOSVersionInfoSize = sizeof(osv);
  1142. /* Windows 7 = Version 6.0 */
  1143. return (!GetVersionEx(&osv) || /* could not get version */
  1144. osv.dwMajorVersion > 6 || (osv.dwMajorVersion == 6 && osv.dwMinorVersion >= 0));
  1145. }
  1146. #endif
  1147. static bool
  1148. pgwin32_IsInstalled(SC_HANDLE hSCM)
  1149. {
  1150. SC_HANDLE hService = OpenService(hSCM, register_servicename, SERVICE_QUERY_CONFIG);
  1151. bool bResult = (hService != NULL);
  1152. if (bResult)
  1153. CloseServiceHandle(hService);
  1154. return bResult;
  1155. }
  1156. static char *
  1157. pgwin32_CommandLine(bool registration)
  1158. {
  1159. PQExpBuffer cmdLine = createPQExpBuffer();
  1160. char cmdPath[MAXPGPATH];
  1161. int ret;
  1162. if (registration)
  1163. {
  1164. ret = find_my_exec(argv0, cmdPath);
  1165. if (ret != 0)
  1166. {
  1167. write_stderr(_("%s: could not find own program executable\n"), progname);
  1168. exit(1);
  1169. }
  1170. }
  1171. else
  1172. {
  1173. ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
  1174. cmdPath);
  1175. if (ret != 0)
  1176. {
  1177. write_stderr(_("%s: could not find postgres program executable\n"), progname);
  1178. exit(1);
  1179. }
  1180. }
  1181. #ifdef __CYGWIN__
  1182. /* need to convert to windows path */
  1183. {
  1184. char buf[MAXPGPATH];
  1185. #if CYGWIN_VERSION_DLL_MAJOR >= 1007
  1186. cygwin_conv_path(CCP_POSIX_TO_WIN_A, cmdPath, buf, sizeof(buf));
  1187. #else
  1188. cygwin_conv_to_full_win32_path(cmdPath, buf);
  1189. #endif
  1190. strcpy(cmdPath, buf);
  1191. }
  1192. #endif
  1193. /* if path does not end in .exe, append it */
  1194. if (strlen(cmdPath) < 4 ||
  1195. pg_strcasecmp(cmdPath + strlen(cmdPath) - 4, ".exe") != 0)
  1196. snprintf(cmdPath + strlen(cmdPath), sizeof(cmdPath) - strlen(cmdPath),
  1197. ".exe");
  1198. /* use backslashes in path to avoid problems with some third-party tools */
  1199. make_native_path(cmdPath);
  1200. /* be sure to double-quote the executable's name in the command */
  1201. appendPQExpBuffer(cmdLine, "\"%s\"", cmdPath);
  1202. /* append assorted switches to the command line, as needed */
  1203. if (registration)
  1204. appendPQExpBuffer(cmdLine, " runservice -N \"%s\"",
  1205. register_servicename);
  1206. if (pg_config)
  1207. {
  1208. /* We need the -D path to be absolute */
  1209. char *dataDir;
  1210. if ((dataDir = make_absolute_path(pg_config)) == NULL)
  1211. {
  1212. /* make_absolute_path already reported the error */
  1213. exit(1);
  1214. }
  1215. make_native_path(dataDir);
  1216. appendPQExpBuffer(cmdLine, " -D \"%s\"", dataDir);
  1217. free(dataDir);
  1218. }
  1219. if (registration && do_wait)
  1220. appendPQExpBuffer(cmdLine, " -w");
  1221. if (registration && wait_seconds != DEFAULT_WAIT)
  1222. appendPQExpBuffer(cmdLine, " -t %d", wait_seconds);
  1223. if (registration && silent_mode)
  1224. appendPQExpBuffer(cmdLine, " -s");
  1225. if (post_opts)
  1226. {
  1227. if (registration)
  1228. appendPQExpBuffer(cmdLine, " -o \"%s\"", post_opts);
  1229. else
  1230. appendPQExpBuffer(cmdLine, " %s", post_opts);
  1231. }
  1232. return cmdLine->data;
  1233. }
  1234. static void
  1235. pgwin32_doRegister(void)
  1236. {
  1237. SC_HANDLE hService;
  1238. SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  1239. if (hSCM == NULL)
  1240. {
  1241. write_stderr(_("%s: could not open service manager\n"), progname);
  1242. exit(1);
  1243. }
  1244. if (pgwin32_IsInstalled(hSCM))
  1245. {
  1246. CloseServiceHandle(hSCM);
  1247. write_stderr(_("%s: service \"%s\" already registered\n"), progname, register_servicename);
  1248. exit(1);
  1249. }
  1250. if ((hService = CreateService(hSCM, register_servicename, register_servicename,
  1251. SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
  1252. pgctl_start_type, SERVICE_ERROR_NORMAL,
  1253. pgwin32_CommandLine(true),
  1254. NULL, NULL, "RPCSS\0", register_username, register_password)) == NULL)
  1255. {
  1256. CloseServiceHandle(hSCM);
  1257. write_stderr(_("%s: could not register service \"%s\": error code %lu\n"), progname, register_servicename, GetLastError());
  1258. exit(1);
  1259. }
  1260. CloseServiceHandle(hService);
  1261. CloseServiceHandle(hSCM);
  1262. }
  1263. static void
  1264. pgwin32_doUnregister(void)
  1265. {
  1266. SC_HANDLE hService;
  1267. SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  1268. if (hSCM == NULL)
  1269. {
  1270. write_stderr(_("%s: could not open service manager\n"), progname);
  1271. exit(1);
  1272. }
  1273. if (!pgwin32_IsInstalled(hSCM))
  1274. {
  1275. CloseServiceHandle(hSCM);
  1276. write_stderr(_("%s: service \"%s\" not registered\n"), progname, register_servicename);
  1277. exit(1);
  1278. }
  1279. if ((hService = OpenService(hSCM, register_servicename, DELETE)) == NULL)
  1280. {
  1281. CloseServiceHandle(hSCM);
  1282. write_stderr(_("%s: could not open service \"%s\": error code %lu\n"), progname, register_servicename, GetLastError());
  1283. exit(1);
  1284. }
  1285. if (!DeleteService(hService))
  1286. {
  1287. CloseServiceHandle(hService);
  1288. CloseServiceHandle(hSCM);
  1289. write_stderr(_("%s: could not unregister service \"%s\": error code %lu\n"), progname, register_servicename, GetLastError());
  1290. exit(1);
  1291. }
  1292. CloseServiceHandle(hService);
  1293. CloseServiceHandle(hSCM);
  1294. }
  1295. static void
  1296. pgwin32_SetServiceStatus(DWORD currentState)
  1297. {
  1298. status.dwCurrentState = currentState;
  1299. SetServiceStatus(hStatus, (LPSERVICE_STATUS) &status);
  1300. }
  1301. static void WINAPI
  1302. pgwin32_ServiceHandler(DWORD request)
  1303. {
  1304. switch (request)
  1305. {
  1306. case SERVICE_CONTROL_STOP:
  1307. case SERVICE_CONTROL_SHUTDOWN:
  1308. /*
  1309. * We only need a short wait hint here as it just needs to wait
  1310. * for the next checkpoint. They occur every 5 seconds during
  1311. * shutdown
  1312. */
  1313. status.dwWaitHint = 10000;
  1314. pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
  1315. SetEvent(shutdownEvent);
  1316. return;
  1317. case SERVICE_CONTROL_PAUSE:
  1318. /* Win32 config reloading */
  1319. status.dwWaitHint = 5000;
  1320. kill(postmasterPID, SIGHUP);
  1321. return;
  1322. /* FIXME: These could be used to replace other signals etc */
  1323. case SERVICE_CONTROL_CONTINUE:
  1324. case SERVICE_CONTROL_INTERROGATE:
  1325. default:
  1326. break;
  1327. }
  1328. }
  1329. static void WINAPI
  1330. pgwin32_ServiceMain(DWORD argc, LPTSTR *argv)
  1331. {
  1332. PROCESS_INFORMATION pi;
  1333. DWORD ret;
  1334. /* Initialize variables */
  1335. status.dwWin32ExitCode = S_OK;
  1336. status.dwCheckPoint = 0;
  1337. status.dwWaitHint = 60000;
  1338. status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  1339. status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
  1340. status.dwServiceSpecificExitCode = 0;
  1341. status.dwCurrentState = SERVICE_START_PENDING;
  1342. memset(&pi, 0, sizeof(pi));
  1343. read_post_opts();
  1344. /* Register the control request handler */
  1345. if ((hStatus = RegisterServiceCtrlHandler(register_servicename, pgwin32_ServiceHandler)) == (SERVICE_STATUS_HANDLE) 0)
  1346. return;
  1347. if ((shutdownEvent = CreateEvent(NULL, true, false, NULL)) == NULL)
  1348. return;
  1349. /* Start the postmaster */
  1350. pgwin32_SetServiceStatus(SERVICE_START_PENDING);
  1351. if (!CreateRestrictedProcess(pgwin32_CommandLine(false), &pi, true))
  1352. {
  1353. pgwin32_SetServiceStatus(SERVICE_STOPPED);
  1354. return;
  1355. }
  1356. postmasterPID = pi.dwProcessId;
  1357. postmasterProcess = pi.hProcess;
  1358. CloseHandle(pi.hThread);
  1359. if (do_wait)
  1360. {
  1361. write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Waiting for server startup...\n"));
  1362. if (test_postmaster_connection(true) != PQPING_OK)
  1363. {
  1364. write_eventlog(EVENTLOG_ERROR_TYPE, _("Timed out waiting for server startup\n"));
  1365. pgwin32_SetServiceStatus(SERVICE_STOPPED);
  1366. return;
  1367. }
  1368. write_eventlog(EVENTLOG_INFORMATION_TYPE, _("Server started and accepting connections\n"));
  1369. }
  1370. pgwin32_SetServiceStatus(SERVICE_RUNNING);
  1371. /* Wait for quit... */
  1372. ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);
  1373. pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);
  1374. switch (ret)
  1375. {
  1376. case WAIT_OBJECT_0: /* shutdown event */
  1377. kill(postmasterPID, SIGINT);
  1378. /*
  1379. * Increment the checkpoint and try again Abort after 12
  1380. * checkpoints as the postmaster has probably hung
  1381. */
  1382. while (WaitForSingleObject(postmasterProcess, 5000) == WAIT_TIMEOUT && status.dwCheckPoint < 12)
  1383. status.dwCheckPoint++;
  1384. break;
  1385. case (WAIT_OBJECT_0 + 1): /* postmaster went down */
  1386. break;
  1387. default:
  1388. /* shouldn't get here? */
  1389. break;
  1390. }
  1391. CloseHandle(shutdownEvent);
  1392. CloseHandle(postmasterProcess);
  1393. pgwin32_SetServiceStatus(SERVICE_STOPPED);
  1394. }
  1395. static void
  1396. pgwin32_doRunAsService(void)
  1397. {
  1398. SERVICE_TABLE_ENTRY st[] = {{register_servicename, pgwin32_ServiceMain},
  1399. {NULL, NULL}};
  1400. if (StartServiceCtrlDispatcher(st) == 0)
  1401. {
  1402. write_stderr(_("%s: could not start service \"%s\": error code %lu\n"), progname, register_servicename, GetLastError());
  1403. exit(1);
  1404. }
  1405. }
  1406. /*
  1407. * Mingw headers are incomplete, and so are the libraries. So we have to load
  1408. * a whole lot of API functions dynamically. Since we have to do this anyway,
  1409. * also load the couple of functions that *do* exist in minwg headers but not
  1410. * on NT4. That way, we don't break on NT4.
  1411. */
  1412. typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE);
  1413. typedef BOOL (WINAPI * __IsProcessInJob) (HANDLE, HANDLE, PBOOL);
  1414. typedef HANDLE (WINAPI * __CreateJobObject) (LPSECURITY_ATTRIBUTES, LPCTSTR);
  1415. typedef BOOL (WINAPI * __SetInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD);
  1416. typedef BOOL (WINAPI * __AssignProcessToJobObject) (HANDLE, HANDLE);
  1417. typedef BOOL (WINAPI * __QueryInformationJobObject) (HANDLE, JOBOBJECTINFOCLASS, LPVOID, DWORD, LPDWORD);
  1418. /* Windows API define missing from some versions of MingW headers */
  1419. #ifndef DISABLE_MAX_PRIVILEGE
  1420. #define DISABLE_MAX_PRIVILEGE 0x1
  1421. #endif
  1422. /*
  1423. * Create a restricted token, a job object sandbox, and execute the specified
  1424. * process with it.
  1425. *
  1426. * Returns 0 on success, non-zero on failure, same as CreateProcess().
  1427. *
  1428. * On NT4, or any other system not containing the required functions, will
  1429. * launch the process under the current token without doing any modifications.
  1430. *
  1431. * NOTE! Job object will only work when running as a service, because it's
  1432. * automatically destroyed when pg_ctl exits.
  1433. */
  1434. static int
  1435. CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service)
  1436. {
  1437. int r;
  1438. BOOL b;
  1439. STARTUPINFO si;
  1440. HANDLE origToken;
  1441. HANDLE restrictedToken;
  1442. SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
  1443. SID_AND_ATTRIBUTES dropSids[2];
  1444. /* Functions loaded dynamically */
  1445. __CreateRestrictedToken _CreateRestrictedToken = NULL;
  1446. __IsProcessInJob _IsProcessInJob = NULL;
  1447. __CreateJobObject _CreateJobObject = NULL;
  1448. __SetInformationJobObject _SetInformationJobObject = NULL;
  1449. __AssignProcessToJobObject _AssignProcessToJobObject = NULL;
  1450. __QueryInformationJobObject _QueryInformationJobObject = NULL;
  1451. HANDLE Kernel32Handle;
  1452. HANDLE Advapi32Handle;
  1453. ZeroMemory(&si, sizeof(si));
  1454. si.cb = sizeof(si);
  1455. Advapi32Handle = LoadLibrary("ADVAPI32.DLL");
  1456. if (Advapi32Handle != NULL)
  1457. {
  1458. _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
  1459. }
  1460. if (_CreateRestrictedToken == NULL)
  1461. {
  1462. /*
  1463. * NT4 doesn't have CreateRestrictedToken, so just call ordinary
  1464. * CreateProcess
  1465. */
  1466. write_stderr(_("%s: WARNING: cannot create restricted tokens on this platform\n"), progname);
  1467. if (Advapi32Handle != NULL)
  1468. FreeLibrary(Advapi32Handle);
  1469. return CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, processInfo);
  1470. }
  1471. /* Open the current token to use as a base for the restricted one */
  1472. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
  1473. {
  1474. write_stderr(_("%s: could not open process token: error code %lu\n"), progname, GetLastError());
  1475. return 0;
  1476. }
  1477. /* Allocate list of SIDs to remove */
  1478. ZeroMemory(&dropSids, sizeof(dropSids));
  1479. if (!AllocateAndInitializeSid(&NtAuthority, 2,
  1480. SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
  1481. 0, &dropSids[0].Sid) ||
  1482. !AllocateAndInitializeSid(&NtAuthority, 2,
  1483. SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
  1484. 0, &dropSids[1].Sid))
  1485. {
  1486. write_stderr(_("%s: could not allocate SIDs: error code %lu\n"), progname, GetLastError());
  1487. return 0;
  1488. }
  1489. b = _CreateRestrictedToken(origToken,
  1490. DISABLE_MAX_PRIVILEGE,
  1491. sizeof(dropSids) / sizeof(dropSids[0]),
  1492. dropSids,
  1493. 0, NULL,
  1494. 0, NULL,
  1495. &restrictedToken);
  1496. FreeSid(dropSids[1].Sid);
  1497. FreeSid(dropSids[0].Sid);
  1498. CloseHandle(origToken);
  1499. FreeLibrary(Advapi32Handle);
  1500. if (!b)
  1501. {
  1502. write_stderr(_("%s: could not create restricted token: error code %lu\n"), progname, GetLastError());
  1503. return 0;
  1504. }
  1505. #ifndef __CYGWIN__
  1506. AddUserToTokenDacl(restrictedToken);
  1507. #endif
  1508. r = CreateProcessAsUser(restrictedToken, NULL, cmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, processInfo);
  1509. Kernel32Handle = LoadLibrary("KERNEL32.DLL");
  1510. if (Kernel32Handle != NULL)
  1511. {
  1512. _IsProcessInJob = (__IsProcessInJob) GetProcAddress(Kernel32Handle, "IsProcessInJob");
  1513. _CreateJobObject = (__CreateJobObject) GetProcAddress(Kernel32Handle, "CreateJobObjectA");
  1514. _SetInformationJobObject = (__SetInformationJobObject) GetProcAddress(Kernel32Handle, "SetInformationJobObject");
  1515. _AssignProcessToJobObject = (__AssignProcessToJobObject) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject");
  1516. _QueryInformationJobObject = (__QueryInformationJobObject) GetProcAddress(Kernel32Handle, "QueryInformationJobObject");
  1517. }
  1518. /* Verify that we found all functions */
  1519. if (_IsProcessInJob == NULL || _CreateJobObject == NULL || _SetInformationJobObject == NULL || _AssignProcessToJobObject == NULL || _QueryInformationJobObject == NULL)
  1520. {
  1521. /*
  1522. * IsProcessInJob() is not available on < WinXP, so there is no need
  1523. * to log the error every time in that case
  1524. */
  1525. if (IsWindowsXPOrGreater())
  1526. /*
  1527. * Log error if we can't get version, or if we're on WinXP/2003 or
  1528. * newer
  1529. */
  1530. write_stderr(_("%s: WARNING: could not locate all job object functions in system API\n"), progname);
  1531. }
  1532. else
  1533. {
  1534. BOOL inJob;
  1535. if (_IsProcessInJob(processInfo->hProcess, NULL, &inJob))
  1536. {
  1537. if (!inJob)
  1538. {
  1539. /*
  1540. * Job objects are working, and the new process isn't in one,
  1541. * so we can create one safely. If any problems show up when
  1542. * setting it, we're going to ignore them.
  1543. */
  1544. HANDLE job;
  1545. char jobname[128];
  1546. sprintf(jobname, "PostgreSQL_%lu", processInfo->dwProcessId);
  1547. job = _CreateJobObject(NULL, jobname);
  1548. if (job)
  1549. {
  1550. JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
  1551. JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
  1552. JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
  1553. ZeroMemory(&basicLimit, sizeof(basicLimit));
  1554. ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
  1555. ZeroMemory(&securityLimit, sizeof(securityLimit));
  1556. basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
  1557. basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
  1558. _SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));
  1559. uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
  1560. JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
  1561. JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;
  1562. if (as_service)
  1563. {
  1564. if (!IsWindows7OrGreater())
  1565. {
  1566. /*
  1567. * On Windows 7 (and presumably later),
  1568. * JOB_OBJECT_UILIMIT_HANDLES prevents us from
  1569. * starting as a service. So we only enable it on
  1570. * Vista and earlier (version <= 6.0)
  1571. */
  1572. uiRestrictions.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
  1573. }
  1574. }
  1575. _SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));
  1576. securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
  1577. securityLimit.JobToken = restrictedToken;
  1578. _SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));
  1579. _AssignProcessToJobObject(job, processInfo->hProcess);
  1580. }
  1581. }
  1582. }
  1583. }
  1584. CloseHandle(restrictedToken);
  1585. ResumeThread(processInfo->hThread);
  1586. FreeLibrary(Kernel32Handle);
  1587. /*
  1588. * We intentionally don't close the job object handle, because we want the
  1589. * object to live on until pg_ctl shuts down.
  1590. */
  1591. return r;
  1592. }
  1593. #endif /* defined(WIN32) || defined(__CYGWIN__) */
  1594. static void
  1595. do_advice(void)
  1596. {
  1597. write_stderr(_("Try \"%s --help\" for more information.\n"), progname);
  1598. }
  1599. static void
  1600. do_help(void)
  1601. {
  1602. printf(_("%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n\n"), progname);
  1603. printf(_("Usage:\n"));
  1604. printf(_(" %s init[db] [-D DATADIR] [-s] [-o \"OPTIONS\"]\n"), progname);
  1605. printf(_(" %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n"), progname);
  1606. printf(_(" %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"), progname);
  1607. printf(_(" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"
  1608. " [-o \"OPTIONS\"]\n"), progname);
  1609. printf(_(" %s reload [-D DATADIR] [-s]\n"), progname);
  1610. printf(_(" %s status [-D DATADIR]\n"), progname);
  1611. printf(_(" %s promote [-D DATADIR] [-s]\n"), progname);
  1612. printf(_(" %s kill SIGNALNAME PID\n"), progname);
  1613. #if defined(WIN32) || defined(__CYGWIN__)
  1614. printf(_(" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n"
  1615. " [-S START-TYPE] [-w] [-t SECS] [-o \"OPTIONS\"]\n"), progname);
  1616. printf(_(" %s unregister [-N SERVICENAME]\n"), progname);
  1617. #endif
  1618. printf(_("\nCommon options:\n"));
  1619. printf(_(" -D, --pgdata=DATADIR location of the database storage area\n"));
  1620. printf(_(" -s, --silent only print errors, no informational messages\n"));
  1621. printf(_(" -t, --timeout=SECS seconds to wait when using -w option\n"));
  1622. printf(_(" -V, --version output version information, then exit\n"));
  1623. printf(_(" -w wait until operation completes\n"));
  1624. printf(_(" -W do not wait until operation completes\n"));
  1625. printf(_(" -?, --help show this help, then exit\n"));
  1626. printf(_("(The default is to wait for shutdown, but not for start or restart.)\n\n"));
  1627. printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
  1628. printf(_("\nOptions for start or restart:\n"));
  1629. #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
  1630. printf(_(" -c, --core-files allow postgres to produce core files\n"));
  1631. #else
  1632. printf(_(" -c, --core-files not applicable on this platform\n"));
  1633. #endif
  1634. printf(_(" -l, --log=FILENAME write (or append) server log to FILENAME\n"));
  1635. printf(_(" -o OPTIONS command line options to pass to postgres\n"
  1636. " (PostgreSQL server executable) or initdb\n"));
  1637. printf(_(" -p PATH-TO-POSTGRES normally not necessary\n"));
  1638. printf(_("\nOptions for stop, restart, or promote:\n"));
  1639. printf(_(" -m, --mode=M…

Large files files are truncated, but you can click here to view the full file