Commit 11d205e2 authored by Bruce Momjian's avatar Bruce Momjian

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
parent 3624acd3
...@@ -208,7 +208,8 @@ PostgreSQL documentation ...@@ -208,7 +208,8 @@ PostgreSQL documentation
the specified data directory. If it is, the <acronym>PID</acronym> the specified data directory. If it is, the <acronym>PID</acronym>
and the command line options that were used to invoke it are and the command line options that were used to invoke it are
displayed. If the server is not running, the process returns an 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.
</para> </para>
<para> <para>
......
...@@ -97,6 +97,7 @@ static bool allow_core_files = false; ...@@ -97,6 +97,7 @@ static bool allow_core_files = false;
static time_t start_time; static time_t start_time;
static char postopts_file[MAXPGPATH]; static char postopts_file[MAXPGPATH];
static char version_file[MAXPGPATH];
static char pid_file[MAXPGPATH]; static char pid_file[MAXPGPATH];
static char backup_file[MAXPGPATH]; static char backup_file[MAXPGPATH];
static char recovery_file[MAXPGPATH]; static char recovery_file[MAXPGPATH];
...@@ -152,7 +153,7 @@ static void pgwin32_doRunAsService(void); ...@@ -152,7 +153,7 @@ static void pgwin32_doRunAsService(void);
static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service); static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service);
#endif #endif
static pgpid_t get_pgpid(void); static pgpid_t get_pgpid(bool is_status_request);
static char **readfile(const char *path); static char **readfile(const char *path);
static void free_readfile(char **optlines); static void free_readfile(char **optlines);
static int start_postmaster(void); static int start_postmaster(void);
...@@ -246,10 +247,34 @@ print_msg(const char *msg) ...@@ -246,10 +247,34 @@ print_msg(const char *msg)
} }
static pgpid_t static pgpid_t
get_pgpid(void) get_pgpid(bool is_status_request)
{ {
FILE *pidf; FILE *pidf;
long pid; 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"); pidf = fopen(pid_file, "r");
if (pidf == NULL) if (pidf == NULL)
...@@ -810,7 +835,7 @@ do_start(void) ...@@ -810,7 +835,7 @@ do_start(void)
if (ctl_command != RESTART_COMMAND) if (ctl_command != RESTART_COMMAND)
{ {
old_pid = get_pgpid(); old_pid = get_pgpid(false);
if (old_pid != 0) if (old_pid != 0)
write_stderr(_("%s: another server might be running; " write_stderr(_("%s: another server might be running; "
"trying to start server anyway\n"), "trying to start server anyway\n"),
...@@ -894,7 +919,7 @@ do_stop(void) ...@@ -894,7 +919,7 @@ do_stop(void)
pgpid_t pid; pgpid_t pid;
struct stat statbuf; struct stat statbuf;
pid = get_pgpid(); pid = get_pgpid(false);
if (pid == 0) /* no pid file */ if (pid == 0) /* no pid file */
{ {
...@@ -943,7 +968,7 @@ do_stop(void) ...@@ -943,7 +968,7 @@ do_stop(void)
for (cnt = 0; cnt < wait_seconds; cnt++) for (cnt = 0; cnt < wait_seconds; cnt++)
{ {
if ((pid = get_pgpid()) != 0) if ((pid = get_pgpid(false)) != 0)
{ {
print_msg("."); print_msg(".");
pg_usleep(1000000); /* 1 sec */ pg_usleep(1000000); /* 1 sec */
...@@ -980,7 +1005,7 @@ do_restart(void) ...@@ -980,7 +1005,7 @@ do_restart(void)
pgpid_t pid; pgpid_t pid;
struct stat statbuf; struct stat statbuf;
pid = get_pgpid(); pid = get_pgpid(false);
if (pid == 0) /* no pid file */ if (pid == 0) /* no pid file */
{ {
...@@ -1033,7 +1058,7 @@ do_restart(void) ...@@ -1033,7 +1058,7 @@ do_restart(void)
for (cnt = 0; cnt < wait_seconds; cnt++) for (cnt = 0; cnt < wait_seconds; cnt++)
{ {
if ((pid = get_pgpid()) != 0) if ((pid = get_pgpid(false)) != 0)
{ {
print_msg("."); print_msg(".");
pg_usleep(1000000); /* 1 sec */ pg_usleep(1000000); /* 1 sec */
...@@ -1071,7 +1096,7 @@ do_reload(void) ...@@ -1071,7 +1096,7 @@ do_reload(void)
{ {
pgpid_t pid; pgpid_t pid;
pid = get_pgpid(); pid = get_pgpid(false);
if (pid == 0) /* no pid file */ if (pid == 0) /* no pid file */
{ {
write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file); write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
...@@ -1110,7 +1135,7 @@ do_promote(void) ...@@ -1110,7 +1135,7 @@ do_promote(void)
pgpid_t pid; pgpid_t pid;
struct stat statbuf; struct stat statbuf;
pid = get_pgpid(); pid = get_pgpid(false);
if (pid == 0) /* no pid file */ if (pid == 0) /* no pid file */
{ {
...@@ -1204,7 +1229,7 @@ do_status(void) ...@@ -1204,7 +1229,7 @@ do_status(void)
{ {
pgpid_t pid; pgpid_t pid;
pid = get_pgpid(); pid = get_pgpid(true);
/* Is there a pid file? */ /* Is there a pid file? */
if (pid != 0) if (pid != 0)
{ {
...@@ -1247,7 +1272,7 @@ do_status(void) ...@@ -1247,7 +1272,7 @@ do_status(void)
/* /*
* The Linux Standard Base Core Specification 3.1 says this should return * 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 * https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
*/ */
exit(3); exit(3);
...@@ -2285,6 +2310,7 @@ main(int argc, char **argv) ...@@ -2285,6 +2310,7 @@ main(int argc, char **argv)
if (pg_data) if (pg_data)
{ {
snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", 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(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data); snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data);
snprintf(recovery_file, MAXPGPATH, "%s/recovery.conf", pg_data); snprintf(recovery_file, MAXPGPATH, "%s/recovery.conf", pg_data);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment