static int zpool_import_by_guid(uint64_t searchguid) { int err = 0; nvlist_t *pools = NULL; nvpair_t *elem; nvlist_t *config; nvlist_t *found_config = NULL; nvlist_t *policy = NULL; boolean_t first; int flags = ZFS_IMPORT_NORMAL; uint32_t rewind_policy = ZPOOL_NO_REWIND; uint64_t pool_state, txg = -1ULL; importargs_t idata = { 0 }; #ifdef ZFS_AUTOIMPORT_ZPOOL_STATUS_OK_ONLY char *msgid; zpool_status_t reason; zpool_errata_t errata; #endif if ((g_zfs = libzfs_init()) == NULL) return (1); idata.unique = B_TRUE; /* In the future, we can capture further policy and include it here */ if (nvlist_alloc(&policy, NV_UNIQUE_NAME, 0) != 0 || nvlist_add_uint64(policy, ZPOOL_REWIND_REQUEST_TXG, txg) != 0 || nvlist_add_uint32(policy, ZPOOL_REWIND_REQUEST, rewind_policy) != 0) goto error; if (!priv_ineffect(PRIV_SYS_CONFIG)) { printf("cannot discover pools: permission denied\n"); nvlist_free(policy); return (1); } idata.guid = searchguid; pools = zpool_search_import(g_zfs, &idata); if (pools == NULL && idata.exists) { printf("cannot import '%llu': a pool with that guid is already " "created/imported\n", searchguid); err = 1; } else if (pools == NULL) { printf("cannot import '%llu': no such pool available\n", searchguid); err = 1; } if (err == 1) { nvlist_free(policy); return (1); } /* * At this point we have a list of import candidate configs. Even though * we were searching by guid, we still need to post-process the list to * deal with pool state. */ err = 0; elem = NULL; first = B_TRUE; while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { verify(nvpair_value_nvlist(elem, &config) == 0); verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, &pool_state) == 0); if (pool_state == POOL_STATE_DESTROYED) continue; verify(nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY, policy) == 0); uint64_t guid; /* * Search for a pool by guid. */ verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) == 0); if (guid == searchguid) found_config = config; } /* * If we were searching for a specific pool, verify that we found a * pool, and then do the import. */ if (err == 0) { if (found_config == NULL) { printf("cannot import '%llu': no such pool available\n", searchguid); err = B_TRUE; } else { #ifdef ZFS_AUTOIMPORT_ZPOOL_STATUS_OK_ONLY reason = zpool_import_status(config, &msgid, &errata); if (reason == ZPOOL_STATUS_OK) err |= do_import(found_config, NULL, NULL, NULL, flags); else err = 1; #else err |= do_import(found_config, NULL, NULL, NULL, flags); #endif } } error: nvlist_free(pools); nvlist_free(policy); libzfs_fini(g_zfs); return (err ? 1 : 0); }
/* * Target is the dataset whose pool we want to open. */ static void import_pool(const char *target, boolean_t readonly) { nvlist_t *config; nvlist_t *pools; int error; char *sepp; spa_t *spa; nvpair_t *elem; nvlist_t *props; char *name; kernel_init(readonly ? FREAD : (FREAD | FWRITE)); g_zfs = libzfs_init(); ASSERT(g_zfs != NULL); dmu_objset_register_type(DMU_OST_ZFS, space_delta_cb); g_readonly = readonly; /* * If we only want readonly access, it's OK if we find * a potentially-active (ie, imported into the kernel) pool from the * default cachefile. */ if (readonly && spa_open(target, &spa, FTAG) == 0) { spa_close(spa, FTAG); return; } g_importargs.unique = B_TRUE; g_importargs.can_be_active = readonly; g_pool = strdup(target); if ((sepp = strpbrk(g_pool, "/@")) != NULL) *sepp = '\0'; g_importargs.poolname = g_pool; pools = zpool_search_import(g_zfs, &g_importargs); if (nvlist_empty(pools)) { if (!g_importargs.can_be_active) { g_importargs.can_be_active = B_TRUE; if (zpool_search_import(g_zfs, &g_importargs) != NULL || spa_open(target, &spa, FTAG) == 0) { fatal(spa, FTAG, "cannot import '%s': pool is " "active; run " "\"zpool export %s\" " "first\n", g_pool, g_pool); } } fatal(NULL, FTAG, "cannot import '%s': no such pool " "available\n", g_pool); } elem = nvlist_next_nvpair(pools, NULL); name = nvpair_name(elem); VERIFY(nvpair_value_nvlist(elem, &config) == 0); props = NULL; if (readonly) { VERIFY(nvlist_alloc(&props, NV_UNIQUE_NAME, 0) == 0); VERIFY(nvlist_add_uint64(props, zpool_prop_to_name(ZPOOL_PROP_READONLY), 1) == 0); } zfeature_checks_disable = B_TRUE; error = spa_import(name, config, props, ZFS_IMPORT_NORMAL); zfeature_checks_disable = B_FALSE; if (error == EEXIST) error = 0; if (error) fatal(NULL, FTAG, "can't import '%s': %s", name, strerror(error)); }