Fix for re-reading /etc/mtab.

This is a continuation of fb5c53ea65:

    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 <jml@frijid.net>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2215
Issue #1611
This commit is contained in:
John M. Layman 2014-03-26 13:17:17 -04:00 committed by Brian Behlendorf
parent f3ad9cd67a
commit cbca6076b3
3 changed files with 22 additions and 5 deletions

View File

@ -5862,7 +5862,11 @@ share_mount(int op, int argc, char **argv)
* display any active ZFS mounts. We hide any snapshots, since * display any active ZFS mounts. We hide any snapshots, since
* they are controlled automatically. * 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) { while (getmntent(mnttab_file, &entry) == 0) {
if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0 || if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0 ||
strchr(entry.mnt_special, '@') != NULL) 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. * 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) { while ((ret = getextmntent(mnttab_file, &entry, 0)) == 0) {
if (entry.mnt_major == major(statbuf.st_dev) && if (entry.mnt_major == major(statbuf.st_dev) &&
entry.mnt_minor == minor(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)) ((tree = uu_avl_create(pool, NULL, UU_DEFAULT)) == NULL))
nomem(); 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) { while (getmntent(mnttab_file, &entry) == 0) {
/* ignore non-ZFS entries */ /* ignore non-ZFS entries */

View File

@ -1165,7 +1165,10 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
namelen = strlen(zhp->zpool_name); 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; used = alloc = 0;
while (getmntent(hdl->libzfs_mnttab, &entry) == 0) { while (getmntent(hdl->libzfs_mnttab, &entry) == 0) {
/* /*

View File

@ -793,7 +793,10 @@ zfs_path_to_zhandle(libzfs_handle_t *hdl, char *path, zfs_type_t argtype)
return (NULL); 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) { while ((ret = getextmntent(hdl->libzfs_mnttab, &entry, 0)) == 0) {
if (makedevice(entry.mnt_major, entry.mnt_minor) == if (makedevice(entry.mnt_major, entry.mnt_minor) ==
statbuf.st_dev) { statbuf.st_dev) {