libzfs: get rid of libzfs_handle::libzfs_mnttab

All users did a freopen() on it. Even some non-users did!
This is point-less ‒ just open the mtab when needed

If I understand Solaris' getextmntent(3C) correctly, the non-user
freopen()s are very likely an odd, twisted vestigial tail of that ‒
but it's got a completely different calling convention and caching
semantics than any platform we support

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #11868
This commit is contained in:
наб 2021-04-09 00:44:23 +02:00 committed by Brian Behlendorf
parent 74e48f470e
commit 533527725b
7 changed files with 2563 additions and 2713 deletions

View File

@ -83,7 +83,6 @@
libzfs_handle_t *g_zfs; libzfs_handle_t *g_zfs;
static FILE *mnttab_file;
static char history_str[HIS_MAX_RECORD_LEN]; static char history_str[HIS_MAX_RECORD_LEN];
static boolean_t log_history = B_TRUE; static boolean_t log_history = B_TRUE;
@ -7063,8 +7062,7 @@ share_mount(int op, int argc, char **argv)
get_all_datasets(&cb, verbose); get_all_datasets(&cb, verbose);
if (cb.cb_used == 0) { if (cb.cb_used == 0) {
if (options != NULL) free(options);
free(options);
return (0); return (0);
} }
@ -7094,6 +7092,7 @@ share_mount(int op, int argc, char **argv)
zfs_close(cb.cb_handles[i]); zfs_close(cb.cb_handles[i]);
free(cb.cb_handles); free(cb.cb_handles);
} else if (argc == 0) { } else if (argc == 0) {
FILE *mnttab;
struct mnttab entry; struct mnttab entry;
if ((op == OP_SHARE) || (options != NULL)) { if ((op == OP_SHARE) || (options != NULL)) {
@ -7109,14 +7108,12 @@ share_mount(int op, int argc, char **argv)
* automatically. * automatically.
*/ */
/* Reopen MNTTAB to prevent reading stale data from open file */ if ((mnttab = fopen(MNTTAB, "re")) == NULL) {
if (freopen(MNTTAB, "r", mnttab_file) == NULL) { free(options);
if (options != NULL)
free(options);
return (ENOENT); return (ENOENT);
} }
while (getmntent(mnttab_file, &entry) == 0) { while (getmntent(mnttab, &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)
continue; continue;
@ -7125,6 +7122,7 @@ share_mount(int op, int argc, char **argv)
entry.mnt_mountp); entry.mnt_mountp);
} }
(void) fclose(mnttab);
} else { } else {
zfs_handle_t *zhp; zfs_handle_t *zhp;
@ -7145,9 +7143,7 @@ share_mount(int op, int argc, char **argv)
} }
} }
if (options != NULL) free(options);
free(options);
return (ret); return (ret);
} }
@ -7210,10 +7206,6 @@ 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.
*/ */
/* Reopen MNTTAB to prevent reading stale data from open file */
if (freopen(MNTTAB, "r", mnttab_file) == NULL)
return (ENOENT);
if (getextmntent(path, &entry, &statbuf) != 0) { if (getextmntent(path, &entry, &statbuf) != 0) {
if (op == OP_SHARE) { if (op == OP_SHARE) {
(void) fprintf(stderr, gettext("cannot %s '%s': not " (void) fprintf(stderr, gettext("cannot %s '%s': not "
@ -7353,6 +7345,7 @@ unshare_unmount(int op, int argc, char **argv)
* the special type (dataset name), and walk the result in * the special type (dataset name), and walk the result in
* reverse to make sure to get any snapshots first. * reverse to make sure to get any snapshots first.
*/ */
FILE *mnttab;
struct mnttab entry; struct mnttab entry;
uu_avl_pool_t *pool; uu_avl_pool_t *pool;
uu_avl_t *tree = NULL; uu_avl_t *tree = NULL;
@ -7385,11 +7378,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();
/* Reopen MNTTAB to prevent reading stale data from open file */ if ((mnttab = fopen(MNTTAB, "re")) == NULL)
if (freopen(MNTTAB, "r", mnttab_file) == NULL)
return (ENOENT); return (ENOENT);
while (getmntent(mnttab_file, &entry) == 0) { while (getmntent(mnttab, &entry) == 0) {
/* ignore non-ZFS entries */ /* ignore non-ZFS entries */
if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0) if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
@ -7459,6 +7451,7 @@ unshare_unmount(int op, int argc, char **argv)
free(node); free(node);
} }
} }
(void) fclose(mnttab);
/* /*
* Walk the AVL tree in reverse, unmounting each filesystem and * Walk the AVL tree in reverse, unmounting each filesystem and
@ -8649,8 +8642,6 @@ main(int argc, char **argv)
return (1); return (1);
} }
mnttab_file = g_zfs->libzfs_mnttab;
zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); zfs_save_arguments(argc, argv, history_str, sizeof (history_str));
libzfs_print_on_error(g_zfs, B_TRUE); libzfs_print_on_error(g_zfs, B_TRUE);

View File

@ -48,7 +48,6 @@ extern "C" {
struct libzfs_handle { struct libzfs_handle {
int libzfs_error; int libzfs_error;
int libzfs_fd; int libzfs_fd;
FILE *libzfs_mnttab;
zpool_handle_t *libzfs_pool_handles; zpool_handle_t *libzfs_pool_handles;
uu_avl_pool_t *libzfs_ns_avlpool; uu_avl_pool_t *libzfs_ns_avlpool;
uu_avl_t *libzfs_ns_avl; uu_avl_t *libzfs_ns_avl;

View File

@ -127,11 +127,7 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
} }
#ifdef HAVE_SETMNTENT
if ((fp = setmntent(MNTTAB, "re")) == NULL) {
#else
if ((fp = fopen(MNTTAB, "re")) == NULL) { if ((fp = fopen(MNTTAB, "re")) == NULL) {
#endif
(void) fprintf(stderr, "cannot open %s\n", MNTTAB); (void) fprintf(stderr, "cannot open %s\n", MNTTAB);
return (-1); return (-1);
} }

File diff suppressed because it is too large Load Diff

View File

@ -808,13 +808,13 @@ libzfs_mnttab_init(libzfs_handle_t *hdl)
static int static int
libzfs_mnttab_update(libzfs_handle_t *hdl) libzfs_mnttab_update(libzfs_handle_t *hdl)
{ {
FILE *mnttab;
struct mnttab entry; struct mnttab entry;
/* Reopen MNTTAB to prevent reading stale data from open file */ if ((mnttab = fopen(MNTTAB, "re")) == NULL)
if (freopen(MNTTAB, "re", hdl->libzfs_mnttab) == NULL)
return (ENOENT); return (ENOENT);
while (getmntent(hdl->libzfs_mnttab, &entry) == 0) { while (getmntent(mnttab, &entry) == 0) {
mnttab_node_t *mtn; mnttab_node_t *mtn;
avl_index_t where; avl_index_t where;
@ -840,6 +840,7 @@ libzfs_mnttab_update(libzfs_handle_t *hdl)
avl_add(&hdl->libzfs_mnttab_cache, mtn); avl_add(&hdl->libzfs_mnttab_cache, mtn);
} }
(void) fclose(mnttab);
return (0); return (0);
} }
@ -871,6 +872,7 @@ int
libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname, libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
struct mnttab *entry) struct mnttab *entry)
{ {
FILE *mnttab;
mnttab_node_t find; mnttab_node_t find;
mnttab_node_t *mtn; mnttab_node_t *mtn;
int ret = ENOENT; int ret = ENOENT;
@ -881,16 +883,14 @@ libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
if (avl_numnodes(&hdl->libzfs_mnttab_cache)) if (avl_numnodes(&hdl->libzfs_mnttab_cache))
libzfs_mnttab_fini(hdl); libzfs_mnttab_fini(hdl);
/* Reopen MNTTAB to prevent reading stale data from open file */ if ((mnttab = fopen(MNTTAB, "re")) == NULL)
if (freopen(MNTTAB, "re", hdl->libzfs_mnttab) == NULL)
return (ENOENT); return (ENOENT);
srch.mnt_special = (char *)fsname; srch.mnt_special = (char *)fsname;
srch.mnt_fstype = MNTTYPE_ZFS; srch.mnt_fstype = MNTTYPE_ZFS;
if (getmntany(hdl->libzfs_mnttab, entry, &srch) == 0) ret = getmntany(mnttab, entry, &srch) ? ENOENT : 0;
return (0); (void) fclose(mnttab);
else return (ret);
return (ENOENT);
} }
pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock); pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);

View File

@ -1528,6 +1528,7 @@ int
zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force) zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
{ {
int used, alloc; int used, alloc;
FILE *mnttab;
struct mnttab entry; struct mnttab entry;
size_t namelen; size_t namelen;
char **mountpoints = NULL; char **mountpoints = NULL;
@ -1539,12 +1540,11 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
namelen = strlen(zhp->zpool_name); namelen = strlen(zhp->zpool_name);
/* Reopen MNTTAB to prevent reading stale data from open file */ if ((mnttab = fopen(MNTTAB, "re")) == NULL)
if (freopen(MNTTAB, "re", hdl->libzfs_mnttab) == NULL)
return (ENOENT); return (ENOENT);
used = alloc = 0; used = alloc = 0;
while (getmntent(hdl->libzfs_mnttab, &entry) == 0) { while (getmntent(mnttab, &entry) == 0) {
/* /*
* Ignore non-ZFS entries. * Ignore non-ZFS entries.
*/ */
@ -1646,6 +1646,7 @@ zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
ret = 0; ret = 0;
out: out:
(void) fclose(mnttab);
for (i = 0; i < used; i++) { for (i = 0; i < used; i++) {
if (datasets[i]) if (datasets[i])
zfs_close(datasets[i]); zfs_close(datasets[i]);

View File

@ -1025,19 +1025,8 @@ libzfs_init(void)
return (NULL); return (NULL);
} }
#ifdef HAVE_SETMNTENT
if ((hdl->libzfs_mnttab = setmntent(MNTTAB, "re")) == NULL) {
#else
if ((hdl->libzfs_mnttab = fopen(MNTTAB, "re")) == NULL) {
#endif
(void) close(hdl->libzfs_fd);
free(hdl);
return (NULL);
}
if (libzfs_core_init() != 0) { if (libzfs_core_init() != 0) {
(void) close(hdl->libzfs_fd); (void) close(hdl->libzfs_fd);
(void) fclose(hdl->libzfs_mnttab);
free(hdl); free(hdl);
return (NULL); return (NULL);
} }
@ -1056,7 +1045,6 @@ libzfs_init(void)
&hdl->libzfs_max_nvlist))) { &hdl->libzfs_max_nvlist))) {
errno = error; errno = error;
(void) close(hdl->libzfs_fd); (void) close(hdl->libzfs_fd);
(void) fclose(hdl->libzfs_mnttab);
free(hdl); free(hdl);
return (NULL); return (NULL);
} }
@ -1087,12 +1075,6 @@ void
libzfs_fini(libzfs_handle_t *hdl) libzfs_fini(libzfs_handle_t *hdl)
{ {
(void) close(hdl->libzfs_fd); (void) close(hdl->libzfs_fd);
if (hdl->libzfs_mnttab)
#ifdef HAVE_SETMNTENT
(void) endmntent(hdl->libzfs_mnttab);
#else
(void) fclose(hdl->libzfs_mnttab);
#endif
zpool_free_handles(hdl); zpool_free_handles(hdl);
namespace_clear(hdl); namespace_clear(hdl);
libzfs_mnttab_fini(hdl); libzfs_mnttab_fini(hdl);
@ -1139,10 +1121,6 @@ zfs_path_to_zhandle(libzfs_handle_t *hdl, const char *path, zfs_type_t argtype)
return (zfs_open(hdl, path, argtype)); return (zfs_open(hdl, path, argtype));
} }
/* Reopen MNTTAB to prevent reading stale data from open file */
if (freopen(MNTTAB, "re", hdl->libzfs_mnttab) == NULL)
return (NULL);
if (getextmntent(path, &entry, &statbuf) != 0) if (getextmntent(path, &entry, &statbuf) != 0)
return (NULL); return (NULL);