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 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:
@ -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
initialize_data_directory(void)
{

View File

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

View File

@ -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;
}