aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Layman <jlayman@sagecloud.com>2013-08-13 15:24:58 -0400
committerBrian Behlendorf <behlendorf1@llnl.gov>2013-08-14 11:37:06 -0700
commitfb5c53ea65b75c67c23f90ebbbb1134a5bb6c140 (patch)
tree065e9259c2d73bed859c8de8039ca2c2c221e184
parent105afebb1529c21c3fb1ef7101918ed9fb704942 (diff)
Fix for re-reading /etc/mtab in zfs_is_mounted()
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. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #1611
-rw-r--r--lib/libzfs/libzfs_dataset.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c
index 554b0eadc..244b687ed 100644
--- a/lib/libzfs/libzfs_dataset.c
+++ b/lib/libzfs/libzfs_dataset.c
@@ -629,12 +629,15 @@ libzfs_mnttab_init(libzfs_handle_t *hdl)
sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
}
-void
+int
libzfs_mnttab_update(libzfs_handle_t *hdl)
{
struct mnttab entry;
- rewind(hdl->libzfs_mnttab);
+ /* Reopen MNTTAB to prevent reading stale data from open file */
+ if (freopen(MNTTAB, "r", hdl->libzfs_mnttab) == NULL)
+ return (ENOENT);
+
while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
mnttab_node_t *mtn;
@@ -647,6 +650,8 @@ libzfs_mnttab_update(libzfs_handle_t *hdl)
mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts);
avl_add(&hdl->libzfs_mnttab_cache, mtn);
}
+
+ return (0);
}
void
@@ -677,13 +682,18 @@ libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
{
mnttab_node_t find;
mnttab_node_t *mtn;
+ int error;
if (!hdl->libzfs_mnttab_enable) {
struct mnttab srch = { 0 };
if (avl_numnodes(&hdl->libzfs_mnttab_cache))
libzfs_mnttab_fini(hdl);
- rewind(hdl->libzfs_mnttab);
+
+ /* Reopen MNTTAB to prevent reading stale data from open file */
+ if (freopen(MNTTAB, "r", hdl->libzfs_mnttab) == NULL)
+ return (ENOENT);
+
srch.mnt_special = (char *)fsname;
srch.mnt_fstype = MNTTYPE_ZFS;
if (getmntany(hdl->libzfs_mnttab, entry, &srch) == 0)
@@ -693,7 +703,8 @@ libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
}
if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0)
- libzfs_mnttab_update(hdl);
+ if ((error = libzfs_mnttab_update(hdl)) != 0)
+ return (error);
find.mtn_mt.mnt_special = (char *)fsname;
mtn = avl_find(&hdl->libzfs_mnttab_cache, &find, NULL);