Warn about initdb using mount-points

Add code to detect and warn about trying to initdb or create pg_xlog on
mount points.
This commit is contained in:
Bruce Momjian 2013-02-16 18:52:50 -05:00
parent 1bd42cd70a
commit 17f1523932
3 changed files with 60 additions and 13 deletions

View File

@ -257,6 +257,7 @@ void setup_signals(void);
void setup_text_search(void); void setup_text_search(void);
void create_data_directory(void); void create_data_directory(void);
void create_xlog_symlink(void); void create_xlog_symlink(void);
void warn_on_mount_point(int error);
void initialize_data_directory(void); void initialize_data_directory(void);
@ -3144,7 +3145,9 @@ setup_signals(void)
void void
create_data_directory(void) create_data_directory(void)
{ {
switch (pg_check_dir(pg_data)) int ret;
switch ((ret = pg_check_dir(pg_data)))
{ {
case 0: case 0:
/* PGDATA not there, must create it */ /* PGDATA not there, must create it */
@ -3179,15 +3182,20 @@ create_data_directory(void)
break; break;
case 2: case 2:
case 3:
case 4:
/* Present and not empty */ /* Present and not empty */
fprintf(stderr, fprintf(stderr,
_("%s: directory \"%s\" exists but is not empty\n"), _("%s: directory \"%s\" exists but is not empty\n"),
progname, pg_data); progname, pg_data);
fprintf(stderr, if (ret != 4)
_("If you want to create a new database system, either remove or empty\n" warn_on_mount_point(ret);
"the directory \"%s\" or run %s\n" else
"with an argument other than \"%s\".\n"), fprintf(stderr,
pg_data, progname, pg_data); _("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 */ exit(1); /* no further message needed */
default: default:
@ -3206,6 +3214,7 @@ create_xlog_symlink(void)
if (strcmp(xlog_dir, "") != 0) if (strcmp(xlog_dir, "") != 0)
{ {
char *linkloc; char *linkloc;
int ret;
/* clean up xlog directory name, check it's absolute */ /* clean up xlog directory name, check it's absolute */
canonicalize_path(xlog_dir); canonicalize_path(xlog_dir);
@ -3216,7 +3225,7 @@ create_xlog_symlink(void)
} }
/* check if the specified xlog directory exists/is empty */ /* check if the specified xlog directory exists/is empty */
switch (pg_check_dir(xlog_dir)) switch ((ret = pg_check_dir(xlog_dir)))
{ {
case 0: case 0:
/* xlog directory not there, must create it */ /* xlog directory not there, must create it */
@ -3255,14 +3264,19 @@ create_xlog_symlink(void)
break; break;
case 2: case 2:
case 3:
case 4:
/* Present and not empty */ /* Present and not empty */
fprintf(stderr, fprintf(stderr,
_("%s: directory \"%s\" exists but is not empty\n"), _("%s: directory \"%s\" exists but is not empty\n"),
progname, xlog_dir); progname, xlog_dir);
fprintf(stderr, if (ret != 4)
_("If you want to store the transaction log there, either\n" warn_on_mount_point(ret);
"remove or empty the directory \"%s\".\n"), else
xlog_dir); fprintf(stderr,
_("If you want to store the transaction log there, either\n"
"remove or empty the directory \"%s\".\n"),
xlog_dir);
exit_nicely(); exit_nicely();
default: default:
@ -3291,6 +3305,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 void
initialize_data_directory(void) initialize_data_directory(void)
{ {

View File

@ -371,6 +371,8 @@ verify_dir_is_empty_or_create(char *dirname)
*/ */
return; return;
case 2: case 2:
case 3:
case 4:
/* /*
* Exists, not empty * Exists, not empty

View File

@ -31,6 +31,7 @@ pg_check_dir(const char *dir)
int result = 1; int result = 1;
DIR *chkdir; DIR *chkdir;
struct dirent *file; struct dirent *file;
bool dot_found = false;
errno = 0; errno = 0;
@ -47,15 +48,26 @@ pg_check_dir(const char *dir)
/* skip this and parent directory */ /* skip this and parent directory */
continue; 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 else
{ {
result = 2; /* not empty */ result = 4; /* not empty */
break; break;
} }
} }
#ifdef WIN32 #ifdef WIN32
/* /*
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
* released version * released version
@ -69,5 +81,9 @@ pg_check_dir(const char *dir)
if (errno != 0) if (errno != 0)
result = -1; /* some kind of I/O error? */ 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; return result;
} }