summaryrefslogtreecommitdiff
path: root/usr/src/lib/libzfs/common/libzfs_import.c
diff options
context:
space:
mode:
authorck153898 <none@none>2008-06-06 06:10:12 -0700
committerck153898 <none@none>2008-06-06 06:10:12 -0700
commit24e697d414a4df0377b91a2875f029e7b5f97247 (patch)
tree76cd9e0d52b3aeae008c3267fe38952342ce3bc1 /usr/src/lib/libzfs/common/libzfs_import.c
parentae223a066cba696abaa519b470ae094ebf274314 (diff)
downloadillumos-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.c86
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);