]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Change /etc/mtab to /proc/self/mounts
authorslashdd <eric.desrochers@canonical.com>
Tue, 20 Sep 2016 17:07:58 +0000 (13:07 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 20 Sep 2016 17:07:58 +0000 (10:07 -0700)
Fix misleading error message:

 "The /dev/zfs device is missing and must be created.", if /etc/mtab is missing.

Reviewed-by: Richard Laager <rlaager@wiktel.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Eric Desrochers <eric.desrochers@canonical.com>
Closes #4680
Closes #5029

13 files changed:
cmd/mount_zfs/mount_zfs.c
cmd/zfs/zfs_main.c
cmd/zinject/translate.c
config/user-commands.m4
contrib/initramfs/scripts/zfs
etc/init.d/zfs-functions.in
etc/init.d/zfs-mount.in
lib/libspl/include/sys/mnttab.h
lib/libzfs/libzfs_dataset.c
lib/libzfs/libzfs_mount.c
lib/libzfs/libzfs_util.c
scripts/ziltest.sh
tests/zfs-tests/tests/functional/cli_root/zfs/zfs_003_neg.ksh

index b78c91c7ccfd439df51c4996c7f7cf564da5c909..f6631a5276bcf18c58c4ce7243df64bf5f704e70 100644 (file)
@@ -294,11 +294,11 @@ mtab_is_writeable(void)
        struct stat st;
        int error, fd;
 
-       error = lstat(MNTTAB, &st);
+       error = lstat("/etc/mtab", &st);
        if (error || S_ISLNK(st.st_mode))
                return (0);
 
-       fd = open(MNTTAB, O_RDWR | O_CREAT, 0644);
+       fd = open("/etc/mtab", O_RDWR | O_CREAT, 0644);
        if (fd < 0)
                return (0);
 
@@ -320,21 +320,21 @@ mtab_update(char *dataset, char *mntpoint, char *type, char *mntopts)
        mnt.mnt_freq = 0;
        mnt.mnt_passno = 0;
 
-       fp = setmntent(MNTTAB, "a+");
+       fp = setmntent("/etc/mtab", "a+");
        if (!fp) {
                (void) fprintf(stderr, gettext(
-                   "filesystem '%s' was mounted, but %s "
+                   "filesystem '%s' was mounted, but /etc/mtab "
                    "could not be opened due to error %d\n"),
-                   dataset, MNTTAB, errno);
+                   dataset, errno);
                return (MOUNT_FILEIO);
        }
 
        error = addmntent(fp, &mnt);
        if (error) {
                (void) fprintf(stderr, gettext(
-                   "filesystem '%s' was mounted, but %s "
+                   "filesystem '%s' was mounted, but /etc/mtab "
                    "could not be updated due to error %d\n"),
-                   dataset, MNTTAB, errno);
+                   dataset, errno);
                return (MOUNT_FILEIO);
        }
 
index dd165da0ea03195e63797698dd847df9afac3d88..cca52dbe77a1e208e55bf424396a2b26078c92fb 100644 (file)
@@ -6146,9 +6146,10 @@ share_mount(int op, int argc, char **argv)
                }
 
                /*
-                * When mount is given no arguments, go through /etc/mtab and
-                * display any active ZFS mounts.  We hide any snapshots, since
-                * they are controlled automatically.
+                * When mount is given no arguments, go through
+                * /proc/self/mounts and display any active ZFS mounts.
+                * We hide any snapshots, since they are controlled
+                * automatically.
                 */
 
                /* Reopen MNTTAB to prevent reading stale data from open file */
@@ -6228,8 +6229,8 @@ unshare_unmount_compare(const void *larg, const void *rarg, void *unused)
 
 /*
  * Convenience routine used by zfs_do_umount() and manual_unmount().  Given an
- * absolute path, find the entry /etc/mtab, verify that its a ZFS filesystem,
- * and unmount it appropriately.
+ * absolute path, find the entry /proc/self/mounts, verify that its a
+ * ZFS filesystems, and unmount it appropriately.
  */
 static int
 unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
@@ -6242,7 +6243,7 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
        ino_t path_inode;
 
        /*
-        * Search for the path in /etc/mtab.  Rather than looking for the
+        * Search for the path in /proc/self/mounts. Rather than looking for the
         * specific path, which can be fooled by non-standard paths (i.e. ".."
         * or "//"), we stat() the path and search for the corresponding
         * (major,minor) device pair.
@@ -6273,8 +6274,8 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual)
                            "currently mounted\n"), cmdname, path);
                        return (1);
                }
-               (void) fprintf(stderr, gettext("warning: %s not in mtab\n"),
-                   path);
+               (void) fprintf(stderr, gettext("warning: %s not in"
+                   "/proc/self/mounts\n"), path);
                if ((ret = umount2(path, flags)) != 0)
                        (void) fprintf(stderr, gettext("%s: %s\n"), path,
                            strerror(errno));
@@ -6385,9 +6386,9 @@ unshare_unmount(int op, int argc, char **argv)
                /*
                 * We could make use of zfs_for_each() to walk all datasets in
                 * the system, but this would be very inefficient, especially
-                * since we would have to linearly search /etc/mtab for each
-                * one.  Instead, do one pass through /etc/mtab looking for
-                * zfs entries and call zfs_unmount() for each one.
+                * since we would have to linearly search /proc/self/mounts for
+                * each one. Instead, do one pass through /proc/self/mounts
+                * looking for zfs entries and call zfs_unmount() for each one.
                 *
                 * Things get a little tricky if the administrator has created
                 * mountpoints beneath other ZFS filesystems.  In this case, we
index 5cc9d9fdc7078f7828fbf977cee63005e28564b3..adace72ff845c569233a66b22e114550f9c58e5b 100644 (file)
@@ -120,7 +120,7 @@ parse_pathname(const char *inpath, char *dataset, char *relpath,
 #else
        if ((fp = fopen(MNTTAB, "r")) == NULL) {
 #endif
-               (void) fprintf(stderr, "cannot open /etc/mtab\n");
+               (void) fprintf(stderr, "cannot open %s\n", MNTTAB);
                return (-1);
        }
 
index 58633b4a0ccb4ceab3374f3519c25387f99fe09c..6e9c3d10383ab4c118b680454031cb4f17628010 100644 (file)
@@ -127,7 +127,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER_COMMANDS_LINUX], [
        PAGESIZE=$($GETCONF PAGESIZE)
        AC_SUBST(PAGESIZE)
 
-       MNTTAB=/etc/mtab
+       MNTTAB=/proc/self/mounts
        AC_SUBST(MNTTAB)
 ])
 
index 6a78a46d29a111e7cc206c10b3fec1cd0cd48cee..250dc57171898e225ae565d1b2dd8a8be240318c 100644 (file)
@@ -288,9 +288,8 @@ load_module_initrd()
                wait_for_dev
        fi
 
-       # zpool import refuse to import without a valid mtab
-       [ ! -f /proc/mounts ] && mount proc /proc
-       [ ! -f /etc/mtab ] && cat /proc/mounts > /etc/mtab
+       # zpool import refuse to import without a valid /proc/self/mounts
+       [ ! -f /proc/self/mounts ] && mount proc /proc
 
        # Load the module
        load_module "zfs" || return 1
@@ -919,7 +918,7 @@ mountroot()
        #
        #   but the MOUNTPOINT prefix is preserved on descendent filesystem
        #   after the pivot into the regular root, which later breaks things
-       #   like `zfs mount -a` and the /etc/mtab refresh.
+       #   like `zfs mount -a` and the /proc/self/mounts refresh.
        #
        # * Mount additional filesystems required
        #   Such as /usr, /var, /usr/local etc.
index acfdf99263d89c65e31eee482ed6748860d63799..97f2ea039d7b0c57d477e513b448fa0103e6832f 100644 (file)
@@ -368,7 +368,7 @@ read_mtab()
                        # Set the variable.
                        eval export MTAB_$mntpnt=\"$fs\"
                fi
-       done < /proc/mounts
+       done < /proc/self/mounts
 }
 
 in_mtab()
index 34db057c813ec6e09ca837ced091e8ef55b1d9e2..2722a31e4080d020d9a60a17da8913f60741d233 100755 (executable)
@@ -39,7 +39,7 @@ chkroot() {
                if [ "$2" = "/" ]; then
                        return 0
                fi
-       done < /etc/mtab
+       done < /proc/self/mounts
 
        return 1
 }
@@ -178,7 +178,7 @@ do_start()
 
        check_module_loaded "zfs" || exit 0
 
-       # Ensure / exists in /etc/mtab, if not update mtab accordingly.
+       # Ensure / exists in /proc/self/mounts.
        # This should be handled by rc.sysinit but lets be paranoid.
        if ! chkroot
        then
index 21d89658c6bf2db24c3aca7ed1b0eb8c291aa06c..026a8fa7beeeaa1cc8d87c2c2a9da5ff7c4f48e2 100644 (file)
@@ -38,7 +38,7 @@
 #undef MNTTAB
 #endif /* MNTTAB */
 
-#define        MNTTAB          "/etc/mtab"
+#define        MNTTAB          "/proc/self/mounts"
 #define        MNT_LINE_MAX    4096
 
 #define        MNT_TOOLONG     1       /* entry exceeds MNT_LINE_MAX */
index 3ac31ad1d48124973bafe73bc6e0406b225c4e96..84fe71734f7c4ba8d4740203c21763b00010d974 100755 (executable)
@@ -1908,9 +1908,9 @@ zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
  * zfs_prop_get_int() are built using this interface.
  *
  * Certain properties can be overridden using 'mount -o'.  In this case, scan
- * the contents of the /etc/mtab entry, searching for the appropriate options.
- * If they differ from the on-disk values, report the current values and mark
- * the source "temporary".
+ * the contents of the /proc/self/mounts entry, searching for the
+ * appropriate options. If they differ from the on-disk values, report the
+ * current values and mark the source "temporary".
  */
 static int
 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
@@ -1981,8 +1981,9 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
 
        /*
         * Because looking up the mount options is potentially expensive
-        * (iterating over all of /etc/mtab), we defer its calculation until
-        * we're looking up a property which requires its presence.
+        * (iterating over all of /proc/self/mounts), we defer its
+        * calculation until we're looking up a property which requires
+        * its presence.
         */
        if (!zhp->zfs_mntcheck &&
            (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) {
index 8c7f326380d91443b9684067e7055c37336e13c0..44781679de4a2844e0ac394fa3470d6661a53afe 100644 (file)
@@ -347,8 +347,8 @@ zfs_add_option(zfs_handle_t *zhp, char *options, int len,
                return (0);
 
        /*
-        * zfs_prop_get_int() to not used to ensure our mount options
-        * are not influenced by the current /etc/mtab contents.
+        * zfs_prop_get_int() is not used to ensure our mount options
+        * are not influenced by the current /proc/self/mounts contents.
         */
        value = getprop_uint64(zhp, prop, &source);
 
@@ -1184,8 +1184,8 @@ mountpoint_compare(const void *a, const void *b)
  * Unshare and unmount all datasets within the given pool.  We don't want to
  * rely on traversing the DSL to discover the filesystems within the pool,
  * because this may be expensive (if not all of them are mounted), and can fail
- * arbitrarily (on I/O error, for example).  Instead, we walk /etc/mtab and
- * gather all the filesystems that are currently mounted.
+ * arbitrarily (on I/O error, for example).  Instead, we walk /proc/self/mounts
+ * and gather all the filesystems that are currently mounted.
  */
 int
 zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
index 3c388a3a0be2dc61e149b4e05819ed33ae4f834c..4988e8115dca4c5f30a75a53b5e1afae421e6826 100755 (executable)
@@ -67,9 +67,9 @@ libzfs_error_init(int error)
                    "loaded.\nTry running '/sbin/modprobe zfs' as root "
                    "to load them.\n"));
        case ENOENT:
-               return (dgettext(TEXT_DOMAIN, "The /dev/zfs device is "
-                   "missing and must be created.\nTry running 'udevadm "
-                   "trigger' as root to create it.\n"));
+               return (dgettext(TEXT_DOMAIN, "/dev/zfs and /proc/self/mounts "
+                   "are required.\nTry running 'udevadm trigger' and 'mount "
+                   "-t proc proc /proc' as root.\n"));
        case ENOEXEC:
                return (dgettext(TEXT_DOMAIN, "The ZFS modules cannot be "
                    "auto-loaded.\nTry running '/sbin/modprobe zfs' as "
index 62cf09e88e0de68e1cf1765ad2e554b240b55955..bb816293f1a57d5ab40a39b437a3b2e6ccfb2f27 100755 (executable)
@@ -185,7 +185,11 @@ CHECKSUM_BEFORE=$(sha256sum -b "$PAYLOAD")
 #
 # TX_WRITE (small file with ordering)
 #
-cp /etc/mtab $ROOT/small_file
+if is_linux; then
+       cp /proc/self/mounts $ROOT/small_file
+else
+       cp /etc/mtab $ROOT/small_file
+fi
 cp /etc/profile $ROOT/small_file
 
 #
index d094d1a7d22decd87bcb892e406b5298d0a1be4e..63c735f3138ddfdbf6579e11bfbb853e486bc168 100755 (executable)
 
 verify_runnable "global"
 
-log_assert "zfs fails with unexpected scenarios."
+log_assert "zfs fails with unexpected scenario."
 
 #verify zfs failed if ZFS_DEV cannot be opened
 ZFS_DEV=/dev/zfs
 
+if is_linux; then
+       # On Linux, we use /proc/self/mounts, which cannot be moved.
+       MNTTAB=
+fi
+
 for file in $ZFS_DEV $MNTTAB; do
        if [[ -e $file ]]; then
                $MV $file ${file}.bak
@@ -55,4 +60,4 @@ for file in $ZFS_DEV $MNTTAB; do
        $MV ${file}.bak $file
 done
 
-log_pass "zfs fails with unexpected scenarios as expected."
+log_pass "zfs fails with unexpected scenario as expected."