static int add_pool_to_xml(nvlist_t *config, void *data) { char *c; char *name; uint64_t guid; uint64_t version; uint64_t state; nvlist_t *devices; uint_t n; vdev_stat_t *vs; xmlNodePtr pool; xmlNodePtr importable = *((xmlNodePtr *)data); if (nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &name) || nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) || nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) || nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, &state) || nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &devices) || nvlist_lookup_uint64_array( devices, ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &n)) { return (-1); } pool = xmlNewChild(importable, NULL, (xmlChar *)ELEMENT_POOL, NULL); (void) xmlSetProp(pool, (xmlChar *)ATTR_POOL_NAME, (xmlChar *)name); set_uint64_prop(pool, ATTR_POOL_ID, guid); set_uint64_prop(pool, ATTR_POOL_VERSION, version); set_uint64_prop(pool, ATTR_POOL_USED, vs->vs_alloc); set_uint64_prop(pool, ATTR_POOL_SIZE, vs->vs_space); set_uint64_prop(pool, ATTR_POOL_REPLACEMENT_SIZE, vs->vs_rsize); set_uint64_prop(pool, ATTR_POOL_READ_BYTES, vs->vs_bytes[ZIO_TYPE_READ]); set_uint64_prop(pool, ATTR_POOL_WRITE_BYTES, vs->vs_bytes[ZIO_TYPE_WRITE]); set_uint64_prop(pool, ATTR_POOL_READ_OPERATIONS, vs->vs_ops[ZIO_TYPE_READ]); set_uint64_prop(pool, ATTR_POOL_WRITE_OPERATIONS, vs->vs_ops[ZIO_TYPE_WRITE]); set_uint64_prop(pool, ATTR_POOL_READ_ERRORS, vs->vs_read_errors); set_uint64_prop(pool, ATTR_POOL_WRITE_ERRORS, vs->vs_write_errors); set_uint64_prop(pool, ATTR_POOL_CHECKSUM_ERRORS, vs->vs_checksum_errors); (void) xmlSetProp(pool, (xmlChar *)ATTR_DEVICE_STATE, (xmlChar *)zjni_vdev_state_to_str(vs->vs_state)); (void) xmlSetProp(pool, (xmlChar *)ATTR_DEVICE_STATUS, (xmlChar *)zjni_vdev_aux_to_str(vs->vs_aux)); (void) xmlSetProp(pool, (xmlChar *)ATTR_POOL_STATE, (xmlChar *)zjni_pool_state_to_str(state)); (void) xmlSetProp(pool, (xmlChar *)ATTR_POOL_STATUS, (xmlChar *) zjni_pool_status_to_str(zpool_import_status(config, &c))); return (0); }
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); }