]> git.proxmox.com Git - mirror_zfs.git/blobdiff - cmd/zpool/zpool_main.c
Parallel pool import
[mirror_zfs.git] / cmd / zpool / zpool_main.c
index d670cd1afeb1bf53de1e83fe3b0ea4ff712c4d96..e6664b918be483314628b63046697adf4e047037 100644 (file)
@@ -50,6 +50,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <thread_pool.h>
 #include <time.h>
 #include <unistd.h>
 #include <pwd.h>
@@ -3455,15 +3456,40 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
        return (ret);
 }
 
+typedef struct import_parameters {
+       nvlist_t *ip_config;
+       const char *ip_mntopts;
+       nvlist_t *ip_props;
+       int ip_flags;
+       int *ip_err;
+} import_parameters_t;
+
+static void
+do_import_task(void *arg)
+{
+       import_parameters_t *ip = arg;
+       *ip->ip_err |= do_import(ip->ip_config, NULL, ip->ip_mntopts,
+           ip->ip_props, ip->ip_flags);
+       free(ip);
+}
+
+
 static int
 import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
-    char *orig_name, char *new_name,
-    boolean_t do_destroyed, boolean_t pool_specified, boolean_t do_all,
-    importargs_t *import)
+    char *orig_name, char *new_name, importargs_t *import)
 {
        nvlist_t *config = NULL;
        nvlist_t *found_config = NULL;
        uint64_t pool_state;
+       boolean_t pool_specified = (import->poolname != NULL ||
+           import->guid != 0);
+
+
+       tpool_t *tp = NULL;
+       if (import->do_all) {
+               tp = tpool_create(1, 5 * sysconf(_SC_NPROCESSORS_ONLN),
+                   0, NULL);
+       }
 
        /*
         * At this point we have a list of import candidate configs. Even if
@@ -3480,9 +3506,11 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
 
                verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
                    &pool_state) == 0);
-               if (!do_destroyed && pool_state == POOL_STATE_DESTROYED)
+               if (!import->do_destroyed &&
+                   pool_state == POOL_STATE_DESTROYED)
                        continue;
-               if (do_destroyed && pool_state != POOL_STATE_DESTROYED)
+               if (import->do_destroyed &&
+                   pool_state != POOL_STATE_DESTROYED)
                        continue;
 
                verify(nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY,
@@ -3491,12 +3519,21 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
                if (!pool_specified) {
                        if (first)
                                first = B_FALSE;
-                       else if (!do_all)
+                       else if (!import->do_all)
                                (void) fputc('\n', stdout);
 
-                       if (do_all) {
-                               err |= do_import(config, NULL, mntopts,
-                                   props, flags);
+                       if (import->do_all) {
+                               import_parameters_t *ip = safe_malloc(
+                                   sizeof (import_parameters_t));
+
+                               ip->ip_config = config;
+                               ip->ip_mntopts = mntopts;
+                               ip->ip_props = props;
+                               ip->ip_flags = flags;
+                               ip->ip_err = &err;
+
+                               (void) tpool_dispatch(tp, do_import_task,
+                                   (void *)ip);
                        } else {
                                /*
                                 * If we're importing from cachefile, then
@@ -3544,6 +3581,10 @@ import_pools(nvlist_t *pools, nvlist_t *props, char *mntopts, int flags,
                                found_config = config;
                }
        }
+       if (import->do_all) {
+               tpool_wait(tp);
+               tpool_destroy(tp);
+       }
 
        /*
         * If we were searching for a specific pool, verify that we found a
@@ -3773,7 +3814,6 @@ zpool_do_import(int argc, char **argv)
        boolean_t xtreme_rewind = B_FALSE;
        boolean_t do_scan = B_FALSE;
        boolean_t pool_exists = B_FALSE;
-       boolean_t pool_specified = B_FALSE;
        uint64_t txg = -1ULL;
        char *cachefile = NULL;
        importargs_t idata = { 0 };
@@ -3972,7 +4012,6 @@ zpool_do_import(int argc, char **argv)
                        searchname = argv[0];
                        searchguid = 0;
                }
-               pool_specified = B_TRUE;
 
                /*
                 * User specified a name or guid.  Ensure it's unique.
@@ -4005,6 +4044,8 @@ zpool_do_import(int argc, char **argv)
        idata.cachefile = cachefile;
        idata.scan = do_scan;
        idata.policy = policy;
+       idata.do_destroyed = do_destroyed;
+       idata.do_all = do_all;
 
        libpc_handle_t lpch = {
                .lpc_lib_handle = g_zfs,
@@ -4047,9 +4088,7 @@ zpool_do_import(int argc, char **argv)
        }
 
        err = import_pools(pools, props, mntopts, flags,
-           argc >= 1 ? argv[0] : NULL,
-           argc >= 2 ? argv[1] : NULL,
-           do_destroyed, pool_specified, do_all, &idata);
+           argc >= 1 ? argv[0] : NULL, argc >= 2 ? argv[1] : NULL, &idata);
 
        /*
         * If we're using the cachefile and we failed to import, then
@@ -4070,9 +4109,8 @@ zpool_do_import(int argc, char **argv)
                pools = zpool_search_import(&lpch, &idata);
 
                err = import_pools(pools, props, mntopts, flags,
-                   argc >= 1 ? argv[0] : NULL,
-                   argc >= 2 ? argv[1] : NULL,
-                   do_destroyed, pool_specified, do_all, &idata);
+                   argc >= 1 ? argv[0] : NULL, argc >= 2 ? argv[1] : NULL,
+                   &idata);
        }
 
 error: