From 11d205e2bd66cefe0b7d69c02e831cd055cbb5bb Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Sat, 8 Mar 2014 12:15:25 -0500 Subject: [PATCH] pg_ctl: improve handling of invalid data directory Return '4' and report a meaningful error message when a non-existent or invalid data directory is passed. Previously, pg_ctl would just report the server was not running. Patch by me and Amit Kapila Report from Peter Eisentraut --- doc/src/sgml/ref/pg_ctl-ref.sgml | 3 +- src/bin/pg_ctl/pg_ctl.c | 48 ++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/doc/src/sgml/ref/pg_ctl-ref.sgml b/doc/src/sgml/ref/pg_ctl-ref.sgml index 45b53ce1a1..52bcf5e815 100644 --- a/doc/src/sgml/ref/pg_ctl-ref.sgml +++ b/doc/src/sgml/ref/pg_ctl-ref.sgml @@ -208,7 +208,8 @@ PostgreSQL documentation the specified data directory. If it is, the PID and the command line options that were used to invoke it are displayed. If the server is not running, the process returns an - exit status of 3. + exit status of 3. If an accessible data directory is not specified, + the process returns an exit status of 4. diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index 0dbaa6e27f..56d238f394 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -97,6 +97,7 @@ static bool allow_core_files = false; static time_t start_time; static char postopts_file[MAXPGPATH]; +static char version_file[MAXPGPATH]; static char pid_file[MAXPGPATH]; static char backup_file[MAXPGPATH]; static char recovery_file[MAXPGPATH]; @@ -152,7 +153,7 @@ static void pgwin32_doRunAsService(void); static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service); #endif -static pgpid_t get_pgpid(void); +static pgpid_t get_pgpid(bool is_status_request); static char **readfile(const char *path); static void free_readfile(char **optlines); static int start_postmaster(void); @@ -246,10 +247,34 @@ print_msg(const char *msg) } static pgpid_t -get_pgpid(void) +get_pgpid(bool is_status_request) { FILE *pidf; long pid; + struct stat statbuf; + + if (stat(pg_data, &statbuf) != 0) + { + if (errno == ENOENT) + printf(_("%s: directory \"%s\" does not exist\n"), progname, + pg_data); + else + printf(_("%s: cannot access directory \"%s\"\n"), progname, + pg_data); + /* + * The Linux Standard Base Core Specification 3.1 says this should return + * '4, program or service status is unknown' + * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html + */ + exit(is_status_request ? 4 : 1); + } + + if (stat(version_file, &statbuf) != 0 && errno == ENOENT) + { + printf(_("%s: directory \"%s\" is not a database cluster directory\n"), + progname, pg_data); + exit(is_status_request ? 4 : 1); + } pidf = fopen(pid_file, "r"); if (pidf == NULL) @@ -810,7 +835,7 @@ do_start(void) if (ctl_command != RESTART_COMMAND) { - old_pid = get_pgpid(); + old_pid = get_pgpid(false); if (old_pid != 0) write_stderr(_("%s: another server might be running; " "trying to start server anyway\n"), @@ -894,7 +919,7 @@ do_stop(void) pgpid_t pid; struct stat statbuf; - pid = get_pgpid(); + pid = get_pgpid(false); if (pid == 0) /* no pid file */ { @@ -943,7 +968,7 @@ do_stop(void) for (cnt = 0; cnt < wait_seconds; cnt++) { - if ((pid = get_pgpid()) != 0) + if ((pid = get_pgpid(false)) != 0) { print_msg("."); pg_usleep(1000000); /* 1 sec */ @@ -980,7 +1005,7 @@ do_restart(void) pgpid_t pid; struct stat statbuf; - pid = get_pgpid(); + pid = get_pgpid(false); if (pid == 0) /* no pid file */ { @@ -1033,7 +1058,7 @@ do_restart(void) for (cnt = 0; cnt < wait_seconds; cnt++) { - if ((pid = get_pgpid()) != 0) + if ((pid = get_pgpid(false)) != 0) { print_msg("."); pg_usleep(1000000); /* 1 sec */ @@ -1071,7 +1096,7 @@ do_reload(void) { pgpid_t pid; - pid = get_pgpid(); + pid = get_pgpid(false); if (pid == 0) /* no pid file */ { write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file); @@ -1110,7 +1135,7 @@ do_promote(void) pgpid_t pid; struct stat statbuf; - pid = get_pgpid(); + pid = get_pgpid(false); if (pid == 0) /* no pid file */ { @@ -1204,7 +1229,7 @@ do_status(void) { pgpid_t pid; - pid = get_pgpid(); + pid = get_pgpid(true); /* Is there a pid file? */ if (pid != 0) { @@ -1247,7 +1272,7 @@ do_status(void) /* * The Linux Standard Base Core Specification 3.1 says this should return - * '3' + * '3, program is not running' * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html */ exit(3); @@ -2285,6 +2310,7 @@ main(int argc, char **argv) if (pg_data) { snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data); + snprintf(version_file, MAXPGPATH, "%s/PG_VERSION", pg_data); snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data); snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data); snprintf(recovery_file, MAXPGPATH, "%s/recovery.conf", pg_data); -- 2.40.0