summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorslashdd <[email protected]>2016-09-20 13:07:58 -0400
committerBrian Behlendorf <[email protected]>2016-09-20 10:07:58 -0700
commit792517389fad5c495a2738b61c2e9c65dedaaa9a (patch)
tree5eef2ac0ecc1db47b3f11ec4ba12a97b6427e1b7
parent25e2ab16be74cb37934e6736a1dc10fd50a00c56 (diff)
Change /etc/mtab to /proc/self/mounts
Fix misleading error message: "The /dev/zfs device is missing and must be created.", if /etc/mtab is missing. Reviewed-by: Richard Laager <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Eric Desrochers <[email protected]> Closes #4680 Closes #5029
-rw-r--r--cmd/mount_zfs/mount_zfs.c14
-rw-r--r--cmd/zfs/zfs_main.c23
-rw-r--r--cmd/zinject/translate.c2
-rw-r--r--config/user-commands.m42
-rw-r--r--contrib/initramfs/scripts/zfs7
-rw-r--r--etc/init.d/zfs-functions.in2
-rwxr-xr-xetc/init.d/zfs-mount.in4
-rw-r--r--lib/libspl/include/sys/mnttab.h2
-rwxr-xr-xlib/libzfs/libzfs_dataset.c11
-rw-r--r--lib/libzfs/libzfs_mount.c8
-rwxr-xr-xlib/libzfs/libzfs_util.c6
-rwxr-xr-xscripts/ziltest.sh6
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zfs/zfs_003_neg.ksh9
13 files changed, 53 insertions, 43 deletions
diff --git a/cmd/mount_zfs/mount_zfs.c b/cmd/mount_zfs/mount_zfs.c
index b78c91c7c..f6631a527 100644
--- a/cmd/mount_zfs/mount_zfs.c
+++ b/cmd/mount_zfs/mount_zfs.c
@@ -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);
}
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c
index dd165da0e..cca52dbe7 100644
--- a/cmd/zfs/zfs_main.c
+++ b/cmd/zfs/zfs_main.c
@@ -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
diff --git a/cmd/zinject/translate.c b/cmd/zinject/translate.c
index 5cc9d9fdc..adace72ff 100644
--- a/cmd/zinject/translate.c
+++ b/cmd/zinject/translate.c
@@ -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);
}
diff --git a/config/user-commands.m4 b/config/user-commands.m4
index 58633b4a0..6e9c3d103 100644
--- a/config/user-commands.m4
+++ b/config/user-commands.m4
@@ -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)
])
diff --git a/contrib/initramfs/scripts/zfs b/contrib/initramfs/scripts/zfs
index 6a78a46d2..250dc5717 100644
--- a/contrib/initramfs/scripts/zfs
+++ b/contrib/initramfs/scripts/zfs
@@ -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.
diff --git a/etc/init.d/zfs-functions.in b/etc/init.d/zfs-functions.in
index acfdf9926..97f2ea039 100644
--- a/etc/init.d/zfs-functions.in
+++ b/etc/init.d/zfs-functions.in
@@ -368,7 +368,7 @@ read_mtab()
# Set the variable.
eval export MTAB_$mntpnt=\"$fs\"
fi
- done < /proc/mounts
+ done < /proc/self/mounts
}
in_mtab()
diff --git a/etc/init.d/zfs-mount.in b/etc/init.d/zfs-mount.in
index 34db057c8..2722a31e4 100755
--- a/etc/init.d/zfs-mount.in
+++ b/etc/init.d/zfs-mount.in
@@ -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
diff --git a/lib/libspl/include/sys/mnttab.h b/lib/libspl/include/sys/mnttab.h
index 21d89658c..026a8fa7b 100644
--- a/lib/libspl/include/sys/mnttab.h
+++ b/lib/libspl/include/sys/mnttab.h
@@ -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 */
diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c
index 3ac31ad1d..84fe71734 100755
--- a/lib/libzfs/libzfs_dataset.c
+++ b/lib/libzfs/libzfs_dataset.c
@@ -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)) {
diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c
index 8c7f32638..44781679d 100644
--- a/lib/libzfs/libzfs_mount.c
+++ b/lib/libzfs/libzfs_mount.c
@@ -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)
diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c
index 3c388a3a0..4988e8115 100755
--- a/lib/libzfs/libzfs_util.c
+++ b/lib/libzfs/libzfs_util.c
@@ -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 "
diff --git a/scripts/ziltest.sh b/scripts/ziltest.sh
index 62cf09e88..bb816293f 100755
--- a/scripts/ziltest.sh
+++ b/scripts/ziltest.sh
@@ -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
#
diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs/zfs_003_neg.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs/zfs_003_neg.ksh
index d094d1a7d..63c735f31 100755
--- a/tests/zfs-tests/tests/functional/cli_root/zfs/zfs_003_neg.ksh
+++ b/tests/zfs-tests/tests/functional/cli_root/zfs/zfs_003_neg.ksh
@@ -40,11 +40,16 @@
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."