From cbca6076b33e3d1af330e0e1f00cbf1baaf26d82 Mon Sep 17 00:00:00 2001 From: "John M. Layman" Date: Wed, 26 Mar 2014 13:17:17 -0400 Subject: [PATCH] Fix for re-reading /etc/mtab. This is a continuation of fb5c53ea65b75c67c23f90ebbbb1134a5bb6c140: When /etc/mtab is updated on Linux it's done atomically with rename(2). A new mtab is written, the existing mtab is unlinked, and the new mtab is renamed to /etc/mtab. This means that we must close the old file and open the new file to get the updated contents. Using rewind(3) will just move the file pointer back to the start of the file, freopen(3) will close and open the file. In this commit, a few more rewind(3) calls were replaced with freopen(3) to allow updated mtab entries to be picked up immediately. Signed-off-by: John M. Layman Signed-off-by: Brian Behlendorf Closes #2215 Issue #1611 --- cmd/zfs/zfs_main.c | 17 ++++++++++++++--- lib/libzfs/libzfs_mount.c | 5 ++++- lib/libzfs/libzfs_util.c | 5 ++++- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 836979bdf741..d7c1a2a4774b 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -5862,7 +5862,11 @@ share_mount(int op, int argc, char **argv) * display any active ZFS mounts. We hide any snapshots, since * they are controlled automatically. */ - rewind(mnttab_file); + + /* Reopen MNTTAB to prevent reading stale data from open file */ + if (freopen(MNTTAB, "r", mnttab_file) == NULL) + return (ENOENT); + while (getmntent(mnttab_file, &entry) == 0) { if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0 || strchr(entry.mnt_special, '@') != NULL) @@ -5965,7 +5969,11 @@ unshare_unmount_path(int op, char *path, int flags, boolean_t is_manual) /* * Search for the given (major,minor) pair in the mount table. */ - rewind(mnttab_file); + + /* Reopen MNTTAB to prevent reading stale data from open file */ + if (freopen(MNTTAB, "r", mnttab_file) == NULL) + return (ENOENT); + while ((ret = getextmntent(mnttab_file, &entry, 0)) == 0) { if (entry.mnt_major == major(statbuf.st_dev) && entry.mnt_minor == minor(statbuf.st_dev)) @@ -6119,7 +6127,10 @@ unshare_unmount(int op, int argc, char **argv) ((tree = uu_avl_create(pool, NULL, UU_DEFAULT)) == NULL)) nomem(); - rewind(mnttab_file); + /* Reopen MNTTAB to prevent reading stale data from open file */ + if (freopen(MNTTAB, "r", mnttab_file) == NULL) + return (ENOENT); + while (getmntent(mnttab_file, &entry) == 0) { /* ignore non-ZFS entries */ diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index 3cd6406b26c0..b85c5d04ffea 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -1165,7 +1165,10 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force) namelen = strlen(zhp->zpool_name); - rewind(hdl->libzfs_mnttab); + /* Reopen MNTTAB to prevent reading stale data from open file */ + if (freopen(MNTTAB, "r", hdl->libzfs_mnttab) == NULL) + return (ENOENT); + used = alloc = 0; while (getmntent(hdl->libzfs_mnttab, &entry) == 0) { /* diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c index 706ae1769f69..e99603b49ed9 100644 --- a/lib/libzfs/libzfs_util.c +++ b/lib/libzfs/libzfs_util.c @@ -793,7 +793,10 @@ zfs_path_to_zhandle(libzfs_handle_t *hdl, char *path, zfs_type_t argtype) return (NULL); } - rewind(hdl->libzfs_mnttab); + /* Reopen MNTTAB to prevent reading stale data from open file */ + if (freopen(MNTTAB, "r", hdl->libzfs_mnttab) == NULL) + return (NULL); + while ((ret = getextmntent(hdl->libzfs_mnttab, &entry, 0)) == 0) { if (makedevice(entry.mnt_major, entry.mnt_minor) == statbuf.st_dev) {