diff options
Diffstat (limited to 'cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c')
-rw-r--r-- | cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c | 73 |
1 files changed, 42 insertions, 31 deletions
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c index 49a43855d5fe..c4e9adae98ab 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c @@ -18,10 +18,11 @@ * * CDDL HEADER END */ + /* + * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ /* @@ -198,8 +199,10 @@ fix_paths(nvlist_t *nv, name_entry_t *names) if ((devid = get_devid(best->ne_name)) == NULL) { (void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID); } else { - if (nvlist_add_string(nv, ZPOOL_CONFIG_DEVID, devid) != 0) + if (nvlist_add_string(nv, ZPOOL_CONFIG_DEVID, devid) != 0) { + devid_str_free(devid); return (-1); + } devid_str_free(devid); } @@ -665,8 +668,10 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok) nvlist_add_uint64(holey, ZPOOL_CONFIG_ID, c) != 0 || nvlist_add_uint64(holey, - ZPOOL_CONFIG_GUID, 0ULL) != 0) + ZPOOL_CONFIG_GUID, 0ULL) != 0) { + nvlist_free(holey); goto nomem; + } child[c] = holey; } } @@ -952,7 +957,7 @@ slice_cache_compare(const void *arg1, const void *arg2) return (rv > 0 ? 1 : -1); } -#ifdef sun +#ifdef illumos static void check_one_slice(avl_tree_t *r, char *diskname, uint_t partno, diskaddr_t size, uint_t blksz) @@ -975,12 +980,12 @@ check_one_slice(avl_tree_t *r, char *diskname, uint_t partno, (node = avl_find(r, &tmpnode, NULL))) node->rn_nozpool = B_TRUE; } -#endif /* sun */ +#endif /* illumos */ static void nozpool_all_slices(avl_tree_t *r, const char *sname) { -#ifdef sun +#ifdef illumos char diskname[MAXNAMELEN]; char *ptr; int i; @@ -996,10 +1001,10 @@ nozpool_all_slices(avl_tree_t *r, const char *sname) ptr[0] = 'p'; for (i = 0; i <= FD_NUMPART; i++) check_one_slice(r, diskname, i, 0, 1); -#endif /* sun */ +#endif /* illumos */ } -#ifdef sun +#ifdef illumos static void check_slices(avl_tree_t *r, int fd, const char *sname) { @@ -1033,7 +1038,7 @@ check_slices(avl_tree_t *r, int fd, const char *sname) efi_free(gpt); } } -#endif /* sun */ +#endif /* illumos */ static void zpool_open_func(void *arg) @@ -1063,7 +1068,7 @@ zpool_open_func(void *arg) return; } /* this file is too small to hold a zpool */ -#ifdef sun +#ifdef illumos if (S_ISREG(statbuf.st_mode) && statbuf.st_size < SPA_MINDEVSIZE) { (void) close(fd); @@ -1075,12 +1080,12 @@ zpool_open_func(void *arg) */ check_slices(rn->rn_avl, fd, rn->rn_name); } -#else /* !sun */ +#else /* !illumos */ if (statbuf.st_size < SPA_MINDEVSIZE) { (void) close(fd); return; } -#endif /* sun */ +#endif /* illumos */ if ((zpool_read_label(fd, &config)) != 0) { (void) close(fd); @@ -1118,8 +1123,10 @@ zpool_clear_label(int fd) for (l = 0; l < VDEV_LABELS; l++) { if (pwrite64(fd, label, sizeof (vdev_label_t), - label_offset(size, l)) != sizeof (vdev_label_t)) + label_offset(size, l)) != sizeof (vdev_label_t)) { + free(label); return (-1); + } } free(label); @@ -1137,7 +1144,6 @@ static nvlist_t * zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) { int i, dirs = iarg->paths; - DIR *dirp = NULL; struct dirent64 *dp; char path[MAXPATHLEN]; char *end, **dir = iarg->path; @@ -1167,6 +1173,8 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) tpool_t *t; char *rdsk; int dfd; + boolean_t config_failed = B_FALSE; + DIR *dirp; /* use realpath to normalize the path */ if (realpath(dir[i], path) == 0) { @@ -1191,6 +1199,8 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) if ((dfd = open64(rdsk, O_RDONLY)) < 0 || (dirp = fdopendir(dfd)) == NULL) { + if (dfd >= 0) + (void) close(dfd); zfs_error_aux(hdl, strerror(errno)); (void) zfs_error_fmt(hdl, EZFS_BADPATH, dgettext(TEXT_DOMAIN, "cannot open '%s'"), @@ -1272,7 +1282,7 @@ skipdir: cookie = NULL; while ((slice = avl_destroy_nodes(&slice_cache, &cookie)) != NULL) { - if (slice->rn_config != NULL) { + if (slice->rn_config != NULL && !config_failed) { nvlist_t *config = slice->rn_config; boolean_t matched = B_TRUE; @@ -1293,13 +1303,16 @@ skipdir: } if (!matched) { nvlist_free(config); - config = NULL; - continue; + } else { + /* + * use the non-raw path for the config + */ + (void) strlcpy(end, slice->rn_name, + pathleft); + if (add_config(hdl, &pools, path, + config) != 0) + config_failed = B_TRUE; } - /* use the non-raw path for the config */ - (void) strlcpy(end, slice->rn_name, pathleft); - if (add_config(hdl, &pools, path, config) != 0) - goto error; } free(slice->rn_name); free(slice); @@ -1307,7 +1320,9 @@ skipdir: avl_destroy(&slice_cache); (void) closedir(dirp); - dirp = NULL; + + if (config_failed) + goto error; } ret = get_configs(hdl, &pools, iarg->can_be_active); @@ -1330,14 +1345,10 @@ error: for (ne = pools.names; ne != NULL; ne = nenext) { nenext = ne->ne_next; - if (ne->ne_name) - free(ne->ne_name); + free(ne->ne_name); free(ne); } - if (dirp) - (void) closedir(dirp); - return (ret); } @@ -1695,9 +1706,9 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr, cb.cb_type = ZPOOL_CONFIG_SPARES; if (zpool_iter(hdl, find_aux, &cb) == 1) { name = (char *)zpool_get_name(cb.cb_zhp); - ret = TRUE; + ret = B_TRUE; } else { - ret = FALSE; + ret = B_FALSE; } break; @@ -1711,9 +1722,9 @@ zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr, cb.cb_type = ZPOOL_CONFIG_L2CACHE; if (zpool_iter(hdl, find_aux, &cb) == 1) { name = (char *)zpool_get_name(cb.cb_zhp); - ret = TRUE; + ret = B_TRUE; } else { - ret = FALSE; + ret = B_FALSE; } break; |