Skip to content

Commit

Permalink
Fix for re-reading /etc/mtab in zfs_is_mounted()
Browse files Browse the repository at this point in the history
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 openzfs#1611
  • Loading branch information
John Layman authored and unya committed Dec 13, 2013
1 parent 5815ebb commit b0abff1
Showing 1 changed file with 15 additions and 4 deletions.
19 changes: 15 additions & 4 deletions lib/libzfs/libzfs_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down

0 comments on commit b0abff1

Please sign in to comment.