diff options
author | ck153898 <none@none> | 2008-06-06 06:10:12 -0700 |
---|---|---|
committer | ck153898 <none@none> | 2008-06-06 06:10:12 -0700 |
commit | 24e697d414a4df0377b91a2875f029e7b5f97247 (patch) | |
tree | 76cd9e0d52b3aeae008c3267fe38952342ce3bc1 /usr/src/lib/libzfs/common/libzfs_import.c | |
parent | ae223a066cba696abaa519b470ae094ebf274314 (diff) | |
download | illumos-joyent-24e697d414a4df0377b91a2875f029e7b5f97247.tar.gz |
6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
Diffstat (limited to 'usr/src/lib/libzfs/common/libzfs_import.c')
-rw-r--r-- | usr/src/lib/libzfs/common/libzfs_import.c | 86 |
1 files changed, 79 insertions, 7 deletions
diff --git a/usr/src/lib/libzfs/common/libzfs_import.c b/usr/src/lib/libzfs/common/libzfs_import.c index f01555f6d1..8efd53a0d3 100644 --- a/usr/src/lib/libzfs/common/libzfs_import.c +++ b/usr/src/lib/libzfs/common/libzfs_import.c @@ -429,6 +429,7 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok) boolean_t isactive; uint64_t hostid; nvlist_t *nvl; + boolean_t found_one = B_FALSE; if (nvlist_alloc(&ret, 0, 0) != 0) goto nomem; @@ -689,10 +690,16 @@ add_pool: if (nvlist_add_nvlist(ret, name, config) != 0) goto nomem; + found_one = B_TRUE; nvlist_free(config); config = NULL; } + if (!found_one) { + nvlist_free(ret); + ret = NULL; + } + return (ret); nomem: @@ -774,10 +781,12 @@ zpool_read_label(int fd, nvlist_t **config) * Given a list of directories to search, find all pools stored on disk. This * includes partial pools which are not available to import. If no args are * given (argc is 0), then the default directory (/dev/dsk) is searched. + * poolname or guid (but not both) are provided by the caller when trying + * to import a specific pool. */ -nvlist_t * -zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv, - boolean_t active_ok) +static nvlist_t * +zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv, + boolean_t active_ok, char *poolname, uint64_t guid) { int i; DIR *dirp = NULL; @@ -795,6 +804,8 @@ zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv, config_entry_t *ce, *cenext; name_entry_t *ne, *nenext; + verify(poolname == NULL || guid == 0); + if (argc == 0) { argc = 1; argv = &default_dir; @@ -873,6 +884,28 @@ zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv, (void) close(fd); if (config != NULL) { + boolean_t matched = B_TRUE; + + if (poolname != NULL) { + char *pname; + verify(nvlist_lookup_string(config, + ZPOOL_CONFIG_POOL_NAME, + &pname) == 0); + if (strcmp(poolname, pname) != 0) + matched = B_FALSE; + } else if (guid != 0) { + uint64_t this_guid; + verify(nvlist_lookup_uint64(config, + ZPOOL_CONFIG_POOL_GUID, + &this_guid) == 0); + if (guid != this_guid) + matched = B_FALSE; + } + if (!matched) { + nvlist_free(config); + config = NULL; + continue; + } /* use the non-raw path for the config */ (void) strlcpy(end, name, pathleft); if (add_config(hdl, &pools, path, config) != 0) @@ -915,12 +948,40 @@ error: return (ret); } +nvlist_t * +zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv) +{ + return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, 0)); +} + +nvlist_t * +zpool_find_import_byname(libzfs_handle_t *hdl, int argc, char **argv, + char *pool) +{ + return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, pool, 0)); +} + +nvlist_t * +zpool_find_import_byguid(libzfs_handle_t *hdl, int argc, char **argv, + uint64_t guid) +{ + return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, guid)); +} + +nvlist_t * +zpool_find_import_activeok(libzfs_handle_t *hdl, int argc, char **argv) +{ + return (zpool_find_import_impl(hdl, argc, argv, B_TRUE, NULL, 0)); +} + /* * Given a cache file, return the contents as a list of importable pools. + * poolname or guid (but not both) are provided by the caller when trying + * to import a specific pool. */ nvlist_t * zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile, - boolean_t active_ok) + boolean_t active_ok, char *poolname, uint64_t guid) { char *buf; int fd; @@ -929,9 +990,11 @@ zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile, nvlist_t *pools; nvpair_t *elem; char *name; - uint64_t guid; + uint64_t this_guid; boolean_t active; + verify(poolname == NULL || guid == 0); + if ((fd = open(cachefile, O_RDONLY)) < 0) { zfs_error_aux(hdl, "%s", strerror(errno)); (void) zfs_error(hdl, EZFS_BADCACHE, @@ -989,11 +1052,20 @@ zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile, verify(nvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME, &name) == 0); + if (poolname != NULL && strcmp(poolname, name) != 0) + continue; + verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID, - &guid) == 0); + &this_guid) == 0); + if (guid != 0) { + verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID, + &this_guid) == 0); + if (guid != this_guid) + continue; + } if (!active_ok) { - if (pool_active(hdl, name, guid, &active) != 0) { + if (pool_active(hdl, name, this_guid, &active) != 0) { nvlist_free(raw); nvlist_free(pools); return (NULL); |