aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2013-02-16 18:52:50 -0500
committerBruce Momjian <bruce@momjian.us>2013-02-16 18:52:50 -0500
commit17f15239325a88581bb4f9cf91d38005f1f52d69 (patch)
treeac36248037fcd3ea1c8b0c2e253e065ee98b92a4 /src
parent1bd42cd70abdbc946ad64c3c8eaefed4bb8b1145 (diff)
downloadpostgresql-17f15239325a88581bb4f9cf91d38005f1f52d69.tar.gz
postgresql-17f15239325a88581bb4f9cf91d38005f1f52d69.zip
Warn about initdb using mount-points
Add code to detect and warn about trying to initdb or create pg_xlog on mount points.
Diffstat (limited to 'src')
-rw-r--r--src/bin/initdb/initdb.c51
-rw-r--r--src/bin/pg_basebackup/pg_basebackup.c2
-rw-r--r--src/port/pgcheckdir.c20
3 files changed, 60 insertions, 13 deletions
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 2ea3f6ed02b..b8faf9cba6a 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -257,6 +257,7 @@ void setup_signals(void);
void setup_text_search(void);
void create_data_directory(void);
void create_xlog_symlink(void);
+void warn_on_mount_point(int error);
void initialize_data_directory(void);
@@ -3144,7 +3145,9 @@ setup_signals(void)
void
create_data_directory(void)
{
- switch (pg_check_dir(pg_data))
+ int ret;
+
+ switch ((ret = pg_check_dir(pg_data)))
{
case 0:
/* PGDATA not there, must create it */
@@ -3179,15 +3182,20 @@ create_data_directory(void)
break;
case 2:
+ case 3:
+ case 4:
/* Present and not empty */
fprintf(stderr,
_("%s: directory \"%s\" exists but is not empty\n"),
progname, pg_data);
- fprintf(stderr,
- _("If you want to create a new database system, either remove or empty\n"
- "the directory \"%s\" or run %s\n"
- "with an argument other than \"%s\".\n"),
- pg_data, progname, pg_data);
+ if (ret != 4)
+ warn_on_mount_point(ret);
+ else
+ fprintf(stderr,
+ _("If you want to create a new database system, either remove or empty\n"
+ "the directory \"%s\" or run %s\n"
+ "with an argument other than \"%s\".\n"),
+ pg_data, progname, pg_data);
exit(1); /* no further message needed */
default:
@@ -3206,6 +3214,7 @@ create_xlog_symlink(void)
if (strcmp(xlog_dir, "") != 0)
{
char *linkloc;
+ int ret;
/* clean up xlog directory name, check it's absolute */
canonicalize_path(xlog_dir);
@@ -3216,7 +3225,7 @@ create_xlog_symlink(void)
}
/* check if the specified xlog directory exists/is empty */
- switch (pg_check_dir(xlog_dir))
+ switch ((ret = pg_check_dir(xlog_dir)))
{
case 0:
/* xlog directory not there, must create it */
@@ -3255,14 +3264,19 @@ create_xlog_symlink(void)
break;
case 2:
+ case 3:
+ case 4:
/* Present and not empty */
fprintf(stderr,
_("%s: directory \"%s\" exists but is not empty\n"),
progname, xlog_dir);
- fprintf(stderr,
- _("If you want to store the transaction log there, either\n"
- "remove or empty the directory \"%s\".\n"),
- xlog_dir);
+ if (ret != 4)
+ warn_on_mount_point(ret);
+ else
+ fprintf(stderr,
+ _("If you want to store the transaction log there, either\n"
+ "remove or empty the directory \"%s\".\n"),
+ xlog_dir);
exit_nicely();
default:
@@ -3292,6 +3306,21 @@ create_xlog_symlink(void)
void
+warn_on_mount_point(int error)
+{
+ if (error == 2)
+ fprintf(stderr,
+ _("It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n"));
+ else if (error == 3)
+ fprintf(stderr,
+ _("It contains a lost+found directory, perhaps due to it being a mount point.\n"));
+
+ fprintf(stderr,
+ _("Using the top-level directory of a mount point is not recommended.\n"));
+}
+
+
+void
initialize_data_directory(void)
{
int i;
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index b6f774469b1..fb5a1bd1c19 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -371,6 +371,8 @@ verify_dir_is_empty_or_create(char *dirname)
*/
return;
case 2:
+ case 3:
+ case 4:
/*
* Exists, not empty
diff --git a/src/port/pgcheckdir.c b/src/port/pgcheckdir.c
index 3b8258c0353..aee59975afc 100644
--- a/src/port/pgcheckdir.c
+++ b/src/port/pgcheckdir.c
@@ -31,6 +31,7 @@ pg_check_dir(const char *dir)
int result = 1;
DIR *chkdir;
struct dirent *file;
+ bool dot_found = false;
errno = 0;
@@ -47,15 +48,26 @@ pg_check_dir(const char *dir)
/* skip this and parent directory */
continue;
}
+#ifndef WIN32
+ /* file starts with "." */
+ else if (file->d_name[0] == '.')
+ {
+ dot_found = true;
+ }
+ else if (strcmp("lost+found", file->d_name) == 0)
+ {
+ result = 3; /* not empty, mount point */
+ break;
+ }
+#endif
else
{
- result = 2; /* not empty */
+ result = 4; /* not empty */
break;
}
}
#ifdef WIN32
-
/*
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
* released version
@@ -69,5 +81,9 @@ pg_check_dir(const char *dir)
if (errno != 0)
result = -1; /* some kind of I/O error? */
+ /* We report on dot-files if we _only_ find dot files */
+ if (result == 1 && dot_found)
+ result = 2;
+
return result;
}