]> granicus.if.org Git - postgresql/commitdiff
Warn about initdb using mount-points
authorBruce Momjian <bruce@momjian.us>
Sat, 16 Feb 2013 23:52:50 +0000 (18:52 -0500)
committerBruce Momjian <bruce@momjian.us>
Sat, 16 Feb 2013 23:52:50 +0000 (18:52 -0500)
Add code to detect and warn about trying to initdb or create pg_xlog on
mount points.

src/bin/initdb/initdb.c
src/bin/pg_basebackup/pg_basebackup.c
src/port/pgcheckdir.c

index 2ea3f6ed02bebb7d2040fd7769b0db52b23f98fa..b8faf9cba6a391cbfdb56daef3b54198f7ff9b0a 100644 (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)
 {
index b6f774469b1b4ef42a5b2ee55073127fd948fa71..fb5a1bd1c199035b4d75295aa63b8743960926f0 100644 (file)
@@ -371,6 +371,8 @@ verify_dir_is_empty_or_create(char *dirname)
                         */
                        return;
                case 2:
+               case 3:
+               case 4:
 
                        /*
                         * Exists, not empty
index 3b8258c0353429814d118a4a239f9225eda70854..aee59975afcc9d22480f5c0c7c8c05703bca35f0 100644 (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;
 }