summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-01-07 15:22:01 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2016-01-07 15:22:01 -0500
commit099541e8f1988cd8c1ae1a00ded015370fbc61b2 (patch)
tree11346e4fc6b48d11f45e2df07823a582fa1b2a30
parentb96f6f4443fcc68336c7ed45e470c577a4891c00 (diff)
downloadpostgresql-099541e8f1988cd8c1ae1a00ded015370fbc61b2.tar.gz
Use plain mkdir() not pg_mkdir_p() to create subdirectories of PGDATA.
When we're creating subdirectories of PGDATA during initdb, we know darn well that the parent directory exists (or should exist) and that the new subdirectory doesn't (or shouldn't). There is therefore no need to use anything more complicated than mkdir(). Using pg_mkdir_p() just opens us up to unexpected failure modes, such as the one exhibited in bug #13853 from Nuri Boardman. It's not very clear why pg_mkdir_p() went wrong there, but it is clear that we didn't need to be trying to create parent directories in the first place. We're not even saving any code, as proven by the fact that this patch nets out at minus five lines. Since this is a response to a field bug report, back-patch to all branches.
-rw-r--r--src/bin/initdb/initdb.c53
1 files changed, 23 insertions, 30 deletions
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 41368ec8c7..179393424e 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -155,7 +155,6 @@ static FILE *popen_check(const char *command, const char *mode);
static void exit_nicely(void);
static char *get_id(void);
static char *get_encoding_id(char *encoding_name);
-static bool mkdatadir(const char *subdir);
static void set_input(char **dest, char *filename);
static void check_input(char *path);
static void write_version_file(char *extrapath);
@@ -704,32 +703,6 @@ find_matching_ts_config(const char *lc_type)
/*
- * make the data directory (or one of its subdirectories if subdir is not NULL)
- */
-static bool
-mkdatadir(const char *subdir)
-{
- char *path;
-
- path = pg_malloc(strlen(pg_data) + 2 +
- (subdir == NULL ? 0 : strlen(subdir)));
-
- if (subdir != NULL)
- sprintf(path, "%s/%s", pg_data, subdir);
- else
- strcpy(path, pg_data);
-
- if (pg_mkdir_p(path, S_IRWXU) == 0)
- return true;
-
- fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"),
- progname, path, strerror(errno));
-
- return false;
-}
-
-
-/*
* set name of given input file variable under data directory
*/
static void
@@ -2547,6 +2520,7 @@ main(int argc, char *argv[])
"pg_serial",
"pg_subtrans",
"pg_twophase",
+ "pg_multixact",
"pg_multixact/members",
"pg_multixact/offsets",
"base",
@@ -3059,8 +3033,12 @@ main(int argc, char *argv[])
pg_data);
fflush(stdout);
- if (!mkdatadir(NULL))
+ if (pg_mkdir_p(pg_data, S_IRWXU) != 0)
+ {
+ fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"),
+ progname, pg_data, strerror(errno));
exit_nicely();
+ }
else
check_ok();
@@ -3195,10 +3173,25 @@ main(int argc, char *argv[])
printf(_("creating subdirectories ... "));
fflush(stdout);
- for (i = 0; i < (sizeof(subdirs) / sizeof(char *)); i++)
+ for (i = 0; i < lengthof(subdirs); i++)
{
- if (!mkdatadir(subdirs[i]))
+ char *path;
+
+ path = pg_malloc(strlen(pg_data) + strlen(subdirs[i]) + 2);
+ sprintf(path, "%s/%s", pg_data, subdirs[i]);
+
+ /*
+ * The parent directory already exists, so we only need mkdir() not
+ * pg_mkdir_p() here, which avoids some failure modes; cf bug #13853.
+ */
+ if (mkdir(path, S_IRWXU) < 0)
+ {
+ fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"),
+ progname, path, strerror(errno));
exit_nicely();
+ }
+
+ free(path);
}
check_ok();