On Thu, Feb 14, 2013 at 07:21:27PM -0500, Tom Lane wrote:
> Bruce Momjian <[email protected]> writes:
> > Agreed. The attached patch modifies pg_check_dir() to report about
> > invisible and lost+found directory entries, and give more helpful
> > messages to the user.
>
> I'm not terribly thrilled with special-casing 'lost+found' like that,
> since it's an extremely filesystem-dependent thing that even today
> probably only applies to a minority of our installed platforms.
>
> The special case for dotfiles might be useful, not because of any
> connection to mount points but just because someone might forget
> that such could be lurking in a directory that "looks empty".
I was ready to give up on this patch, but then I thought, what
percentage does lost+found and dot-file-only directories cover for mount
points? What other cases are there?
This updated version of the patch reports about dot files if they are
the _only_ files in the directory, and it suggests a top-level mount
point might be the cause.
Does this help?
--
Bruce Momjian <[email protected]> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ It's impossible for everything to be true. +
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
new file mode 100644
index 2ea3f6e..b8faf9c
*** a/src/bin/initdb/initdb.c
--- b/src/bin/initdb/initdb.c
*************** void setup_signals(void);
*** 257,262 ****
--- 257,263 ----
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);
*************** setup_signals(void)
*** 3144,3150 ****
void
create_data_directory(void)
{
! switch (pg_check_dir(pg_data))
{
case 0:
/* PGDATA not there, must create it */
--- 3145,3153 ----
void
create_data_directory(void)
{
! int ret;
!
! switch ((ret = pg_check_dir(pg_data)))
{
case 0:
/* PGDATA not there, must create it */
*************** create_data_directory(void)
*** 3179,3193 ****
break;
case 2:
/* 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);
exit(1); /* no further message needed */
default:
--- 3182,3201 ----
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);
! 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:
*************** create_xlog_symlink(void)
*** 3206,3211 ****
--- 3214,3220 ----
if (strcmp(xlog_dir, "") != 0)
{
char *linkloc;
+ int ret;
/* clean up xlog directory name, check it's absolute */
canonicalize_path(xlog_dir);
*************** create_xlog_symlink(void)
*** 3216,3222 ****
}
/* check if the specified xlog directory exists/is empty */
! switch (pg_check_dir(xlog_dir))
{
case 0:
/* xlog directory not there, must create it */
--- 3225,3231 ----
}
/* check if the specified xlog directory exists/is empty */
! switch ((ret = pg_check_dir(xlog_dir)))
{
case 0:
/* xlog directory not there, must create it */
*************** create_xlog_symlink(void)
*** 3255,3268 ****
break;
case 2:
/* 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);
exit_nicely();
default:
--- 3264,3282 ----
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);
! 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:
*************** create_xlog_symlink(void)
*** 3291,3296 ****
--- 3305,3325 ----
}
+ 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)
{
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
new file mode 100644
index b6f7744..fb5a1bd
*** a/src/bin/pg_basebackup/pg_basebackup.c
--- b/src/bin/pg_basebackup/pg_basebackup.c
*************** verify_dir_is_empty_or_create(char *dirn
*** 371,376 ****
--- 371,378 ----
*/
return;
case 2:
+ case 3:
+ case 4:
/*
* Exists, not empty
diff --git a/src/port/pgcheckdir.c b/src/port/pgcheckdir.c
new file mode 100644
index 3b8258c..aee5997
*** a/src/port/pgcheckdir.c
--- b/src/port/pgcheckdir.c
*************** pg_check_dir(const char *dir)
*** 31,36 ****
--- 31,37 ----
int result = 1;
DIR *chkdir;
struct dirent *file;
+ bool dot_found = false;
errno = 0;
*************** pg_check_dir(const char *dir)
*** 47,61 ****
/* skip this and parent directory */
continue;
}
else
{
! result = 2; /* not empty */
break;
}
}
#ifdef WIN32
-
/*
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
* released version
--- 48,73 ----
/* 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 = 4; /* not empty */
break;
}
}
#ifdef WIN32
/*
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
* released version
*************** pg_check_dir(const char *dir)
*** 69,73 ****
--- 81,89 ----
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;
}
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers