Skip to content

Commit 11d205e

Browse files
committed
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
1 parent 3624acd commit 11d205e

File tree

2 files changed

+39
-12
lines changed

2 files changed

+39
-12
lines changed

doc/src/sgml/ref/pg_ctl-ref.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ PostgreSQL documentation
208208
the specified data directory. If it is, the <acronym>PID</acronym>
209209
and the command line options that were used to invoke it are
210210
displayed. If the server is not running, the process returns an
211-
exit status of 3.
211+
exit status of 3. If an accessible data directory is not specified,
212+
the process returns an exit status of 4.
212213
</para>
213214

214215
<para>

src/bin/pg_ctl/pg_ctl.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ static bool allow_core_files = false;
9797
static time_t start_time;
9898

9999
static char postopts_file[MAXPGPATH];
100+
static char version_file[MAXPGPATH];
100101
static char pid_file[MAXPGPATH];
101102
static char backup_file[MAXPGPATH];
102103
static char recovery_file[MAXPGPATH];
@@ -152,7 +153,7 @@ static void pgwin32_doRunAsService(void);
152153
static int CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_service);
153154
#endif
154155

155-
static pgpid_t get_pgpid(void);
156+
static pgpid_t get_pgpid(bool is_status_request);
156157
static char **readfile(const char *path);
157158
static void free_readfile(char **optlines);
158159
static int start_postmaster(void);
@@ -246,10 +247,34 @@ print_msg(const char *msg)
246247
}
247248

248249
static pgpid_t
249-
get_pgpid(void)
250+
get_pgpid(bool is_status_request)
250251
{
251252
FILE *pidf;
252253
long pid;
254+
struct stat statbuf;
255+
256+
if (stat(pg_data, &statbuf) != 0)
257+
{
258+
if (errno == ENOENT)
259+
printf(_("%s: directory \"%s\" does not exist\n"), progname,
260+
pg_data);
261+
else
262+
printf(_("%s: cannot access directory \"%s\"\n"), progname,
263+
pg_data);
264+
/*
265+
* The Linux Standard Base Core Specification 3.1 says this should return
266+
* '4, program or service status is unknown'
267+
* https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
268+
*/
269+
exit(is_status_request ? 4 : 1);
270+
}
271+
272+
if (stat(version_file, &statbuf) != 0 && errno == ENOENT)
273+
{
274+
printf(_("%s: directory \"%s\" is not a database cluster directory\n"),
275+
progname, pg_data);
276+
exit(is_status_request ? 4 : 1);
277+
}
253278

254279
pidf = fopen(pid_file, "r");
255280
if (pidf == NULL)
@@ -810,7 +835,7 @@ do_start(void)
810835

811836
if (ctl_command != RESTART_COMMAND)
812837
{
813-
old_pid = get_pgpid();
838+
old_pid = get_pgpid(false);
814839
if (old_pid != 0)
815840
write_stderr(_("%s: another server might be running; "
816841
"trying to start server anyway\n"),
@@ -894,7 +919,7 @@ do_stop(void)
894919
pgpid_t pid;
895920
struct stat statbuf;
896921

897-
pid = get_pgpid();
922+
pid = get_pgpid(false);
898923

899924
if (pid == 0) /* no pid file */
900925
{
@@ -943,7 +968,7 @@ do_stop(void)
943968

944969
for (cnt = 0; cnt < wait_seconds; cnt++)
945970
{
946-
if ((pid = get_pgpid()) != 0)
971+
if ((pid = get_pgpid(false)) != 0)
947972
{
948973
print_msg(".");
949974
pg_usleep(1000000); /* 1 sec */
@@ -980,7 +1005,7 @@ do_restart(void)
9801005
pgpid_t pid;
9811006
struct stat statbuf;
9821007

983-
pid = get_pgpid();
1008+
pid = get_pgpid(false);
9841009

9851010
if (pid == 0) /* no pid file */
9861011
{
@@ -1033,7 +1058,7 @@ do_restart(void)
10331058

10341059
for (cnt = 0; cnt < wait_seconds; cnt++)
10351060
{
1036-
if ((pid = get_pgpid()) != 0)
1061+
if ((pid = get_pgpid(false)) != 0)
10371062
{
10381063
print_msg(".");
10391064
pg_usleep(1000000); /* 1 sec */
@@ -1071,7 +1096,7 @@ do_reload(void)
10711096
{
10721097
pgpid_t pid;
10731098

1074-
pid = get_pgpid();
1099+
pid = get_pgpid(false);
10751100
if (pid == 0) /* no pid file */
10761101
{
10771102
write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file);
@@ -1110,7 +1135,7 @@ do_promote(void)
11101135
pgpid_t pid;
11111136
struct stat statbuf;
11121137

1113-
pid = get_pgpid();
1138+
pid = get_pgpid(false);
11141139

11151140
if (pid == 0) /* no pid file */
11161141
{
@@ -1204,7 +1229,7 @@ do_status(void)
12041229
{
12051230
pgpid_t pid;
12061231

1207-
pid = get_pgpid();
1232+
pid = get_pgpid(true);
12081233
/* Is there a pid file? */
12091234
if (pid != 0)
12101235
{
@@ -1247,7 +1272,7 @@ do_status(void)
12471272

12481273
/*
12491274
* The Linux Standard Base Core Specification 3.1 says this should return
1250-
* '3'
1275+
* '3, program is not running'
12511276
* https://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
12521277
*/
12531278
exit(3);
@@ -2285,6 +2310,7 @@ main(int argc, char **argv)
22852310
if (pg_data)
22862311
{
22872312
snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);
2313+
snprintf(version_file, MAXPGPATH, "%s/PG_VERSION", pg_data);
22882314
snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);
22892315
snprintf(backup_file, MAXPGPATH, "%s/backup_label", pg_data);
22902316
snprintf(recovery_file, MAXPGPATH, "%s/recovery.conf", pg_data);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy