395 boolean_t
396 vdev_is_hole(uint64_t *hole_array, uint_t holes, uint_t id)
397 {
398 for (int c = 0; c < holes; c++) {
399
400 /* Top-level is a hole */
401 if (hole_array[c] == id)
402 return (B_TRUE);
403 }
404 return (B_FALSE);
405 }
406
407 /*
408 * Convert our list of pools into the definitive set of configurations. We
409 * start by picking the best config for each toplevel vdev. Once that's done,
410 * we assemble the toplevel vdevs into a full config for the pool. We make a
411 * pass to fix up any incorrect paths, and then add it to the main list to
412 * return to the user.
413 */
414 static nvlist_t *
415 get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok,
416 nvlist_t *policy)
417 {
418 pool_entry_t *pe;
419 vdev_entry_t *ve;
420 config_entry_t *ce;
421 nvlist_t *ret = NULL, *config = NULL, *tmp = NULL, *nvtop, *nvroot;
422 nvlist_t **spares, **l2cache;
423 uint_t i, nspares, nl2cache;
424 boolean_t config_seen;
425 uint64_t best_txg;
426 char *name, *hostname = NULL;
427 uint64_t guid;
428 uint_t children = 0;
429 nvlist_t **child = NULL;
430 uint_t holes;
431 uint64_t *hole_array, max_id;
432 uint_t c;
433 boolean_t isactive;
434 uint64_t hostid;
435 nvlist_t *nvl;
436 boolean_t found_one = B_FALSE;
730 goto add_pool;
731
732 /*
733 * Determine if this pool is currently active, in which case we
734 * can't actually import it.
735 */
736 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
737 &name) == 0);
738 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
739 &guid) == 0);
740
741 if (pool_active(hdl, name, guid, &isactive) != 0)
742 goto error;
743
744 if (isactive) {
745 nvlist_free(config);
746 config = NULL;
747 continue;
748 }
749
750 if (policy != NULL) {
751 if (nvlist_add_nvlist(config, ZPOOL_REWIND_POLICY,
752 policy) != 0)
753 goto nomem;
754 }
755
756 if ((nvl = refresh_config(hdl, config)) == NULL) {
757 nvlist_free(config);
758 config = NULL;
759 continue;
760 }
761
762 nvlist_free(config);
763 config = nvl;
764
765 /*
766 * Go through and update the paths for spares, now that we have
767 * them.
768 */
769 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
770 &nvroot) == 0);
771 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
772 &spares, &nspares) == 0) {
773 for (i = 0; i < nspares; i++) {
774 if (fix_paths(spares[i], pl->names) != 0)
775 goto nomem;
847
848 /*
849 * Given a file descriptor, read the label information and return an nvlist
850 * describing the configuration, if there is one.
851 * Return 0 on success, or -1 on failure
852 */
853 int
854 zpool_read_label(int fd, nvlist_t **config)
855 {
856 struct stat64 statbuf;
857 int l;
858 vdev_label_t *label;
859 uint64_t state, txg, size;
860
861 *config = NULL;
862
863 if (fstat64(fd, &statbuf) == -1)
864 return (-1);
865 size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
866
867 if ((label = malloc(sizeof (vdev_label_t))) == NULL)
868 return (-1);
869
870 for (l = 0; l < VDEV_LABELS; l++) {
871 if (pread64(fd, label, sizeof (vdev_label_t),
872 label_offset(size, l)) != sizeof (vdev_label_t))
873 continue;
874
875 if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
876 sizeof (label->vl_vdev_phys.vp_nvlist), config, 0) != 0)
877 continue;
878
879 if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
880 &state) != 0 || state > POOL_STATE_L2CACHE) {
881 nvlist_free(*config);
882 continue;
883 }
884
885 if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
886 (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
887 &txg) != 0 || txg == 0)) {
1241 * use the non-raw path for the config
1242 */
1243 (void) strlcpy(end, slice->rn_name,
1244 pathleft);
1245 if (add_config(hdl, &pools, path,
1246 config) != 0)
1247 config_failed = B_TRUE;
1248 }
1249 }
1250 free(slice->rn_name);
1251 free(slice);
1252 }
1253 avl_destroy(&slice_cache);
1254
1255 (void) closedir(dirp);
1256
1257 if (config_failed)
1258 goto error;
1259 }
1260
1261 ret = get_configs(hdl, &pools, iarg->can_be_active, iarg->policy);
1262
1263 error:
1264 for (pe = pools.pools; pe != NULL; pe = penext) {
1265 penext = pe->pe_next;
1266 for (ve = pe->pe_vdevs; ve != NULL; ve = venext) {
1267 venext = ve->ve_next;
1268 for (ce = ve->ve_configs; ce != NULL; ce = cenext) {
1269 cenext = ce->ce_next;
1270 nvlist_free(ce->ce_config);
1271 free(ce);
1272 }
1273 free(ve);
1274 }
1275 free(pe);
1276 }
1277
1278 for (ne = pools.names; ne != NULL; ne = nenext) {
1279 nenext = ne->ne_next;
1280 free(ne->ne_name);
1281 free(ne);
1371 while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) {
1372 src = fnvpair_value_nvlist(elem);
1373
1374 name = fnvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME);
1375 if (poolname != NULL && strcmp(poolname, name) != 0)
1376 continue;
1377
1378 this_guid = fnvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID);
1379 if (guid != 0 && guid != this_guid)
1380 continue;
1381
1382 if (pool_active(hdl, name, this_guid, &active) != 0) {
1383 nvlist_free(raw);
1384 nvlist_free(pools);
1385 return (NULL);
1386 }
1387
1388 if (active)
1389 continue;
1390
1391 if (nvlist_add_string(src, ZPOOL_CONFIG_CACHEFILE,
1392 cachefile) != 0) {
1393 (void) no_memory(hdl);
1394 nvlist_free(raw);
1395 nvlist_free(pools);
1396 return (NULL);
1397 }
1398
1399 if ((dst = refresh_config(hdl, src)) == NULL) {
1400 nvlist_free(raw);
1401 nvlist_free(pools);
1402 return (NULL);
1403 }
1404
1405 if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) {
1406 (void) no_memory(hdl);
1407 nvlist_free(dst);
1408 nvlist_free(raw);
1409 nvlist_free(pools);
1410 return (NULL);
1411 }
1412 nvlist_free(dst);
1413 }
1414
1415 nvlist_free(raw);
1416 return (pools);
1417 }
1418
|
395 boolean_t
396 vdev_is_hole(uint64_t *hole_array, uint_t holes, uint_t id)
397 {
398 for (int c = 0; c < holes; c++) {
399
400 /* Top-level is a hole */
401 if (hole_array[c] == id)
402 return (B_TRUE);
403 }
404 return (B_FALSE);
405 }
406
407 /*
408 * Convert our list of pools into the definitive set of configurations. We
409 * start by picking the best config for each toplevel vdev. Once that's done,
410 * we assemble the toplevel vdevs into a full config for the pool. We make a
411 * pass to fix up any incorrect paths, and then add it to the main list to
412 * return to the user.
413 */
414 static nvlist_t *
415 get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
416 {
417 pool_entry_t *pe;
418 vdev_entry_t *ve;
419 config_entry_t *ce;
420 nvlist_t *ret = NULL, *config = NULL, *tmp = NULL, *nvtop, *nvroot;
421 nvlist_t **spares, **l2cache;
422 uint_t i, nspares, nl2cache;
423 boolean_t config_seen;
424 uint64_t best_txg;
425 char *name, *hostname = NULL;
426 uint64_t guid;
427 uint_t children = 0;
428 nvlist_t **child = NULL;
429 uint_t holes;
430 uint64_t *hole_array, max_id;
431 uint_t c;
432 boolean_t isactive;
433 uint64_t hostid;
434 nvlist_t *nvl;
435 boolean_t found_one = B_FALSE;
729 goto add_pool;
730
731 /*
732 * Determine if this pool is currently active, in which case we
733 * can't actually import it.
734 */
735 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
736 &name) == 0);
737 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
738 &guid) == 0);
739
740 if (pool_active(hdl, name, guid, &isactive) != 0)
741 goto error;
742
743 if (isactive) {
744 nvlist_free(config);
745 config = NULL;
746 continue;
747 }
748
749 if ((nvl = refresh_config(hdl, config)) == NULL) {
750 nvlist_free(config);
751 config = NULL;
752 continue;
753 }
754
755 nvlist_free(config);
756 config = nvl;
757
758 /*
759 * Go through and update the paths for spares, now that we have
760 * them.
761 */
762 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
763 &nvroot) == 0);
764 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
765 &spares, &nspares) == 0) {
766 for (i = 0; i < nspares; i++) {
767 if (fix_paths(spares[i], pl->names) != 0)
768 goto nomem;
840
841 /*
842 * Given a file descriptor, read the label information and return an nvlist
843 * describing the configuration, if there is one.
844 * Return 0 on success, or -1 on failure
845 */
846 int
847 zpool_read_label(int fd, nvlist_t **config)
848 {
849 struct stat64 statbuf;
850 int l;
851 vdev_label_t *label;
852 uint64_t state, txg, size;
853
854 *config = NULL;
855
856 if (fstat64(fd, &statbuf) == -1)
857 return (-1);
858 size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
859
860 if ((label = calloc(sizeof (vdev_label_t), 1)) == NULL)
861 return (-1);
862
863 for (l = 0; l < VDEV_LABELS; l++) {
864 if (pread64(fd, label, sizeof (vdev_label_t),
865 label_offset(size, l)) != sizeof (vdev_label_t))
866 continue;
867
868 if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
869 sizeof (label->vl_vdev_phys.vp_nvlist), config, 0) != 0)
870 continue;
871
872 if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
873 &state) != 0 || state > POOL_STATE_L2CACHE) {
874 nvlist_free(*config);
875 continue;
876 }
877
878 if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
879 (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
880 &txg) != 0 || txg == 0)) {
1234 * use the non-raw path for the config
1235 */
1236 (void) strlcpy(end, slice->rn_name,
1237 pathleft);
1238 if (add_config(hdl, &pools, path,
1239 config) != 0)
1240 config_failed = B_TRUE;
1241 }
1242 }
1243 free(slice->rn_name);
1244 free(slice);
1245 }
1246 avl_destroy(&slice_cache);
1247
1248 (void) closedir(dirp);
1249
1250 if (config_failed)
1251 goto error;
1252 }
1253
1254 ret = get_configs(hdl, &pools, iarg->can_be_active);
1255
1256 error:
1257 for (pe = pools.pools; pe != NULL; pe = penext) {
1258 penext = pe->pe_next;
1259 for (ve = pe->pe_vdevs; ve != NULL; ve = venext) {
1260 venext = ve->ve_next;
1261 for (ce = ve->ve_configs; ce != NULL; ce = cenext) {
1262 cenext = ce->ce_next;
1263 nvlist_free(ce->ce_config);
1264 free(ce);
1265 }
1266 free(ve);
1267 }
1268 free(pe);
1269 }
1270
1271 for (ne = pools.names; ne != NULL; ne = nenext) {
1272 nenext = ne->ne_next;
1273 free(ne->ne_name);
1274 free(ne);
1364 while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) {
1365 src = fnvpair_value_nvlist(elem);
1366
1367 name = fnvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME);
1368 if (poolname != NULL && strcmp(poolname, name) != 0)
1369 continue;
1370
1371 this_guid = fnvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID);
1372 if (guid != 0 && guid != this_guid)
1373 continue;
1374
1375 if (pool_active(hdl, name, this_guid, &active) != 0) {
1376 nvlist_free(raw);
1377 nvlist_free(pools);
1378 return (NULL);
1379 }
1380
1381 if (active)
1382 continue;
1383
1384 if ((dst = refresh_config(hdl, src)) == NULL) {
1385 nvlist_free(raw);
1386 nvlist_free(pools);
1387 return (NULL);
1388 }
1389
1390 if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) {
1391 (void) no_memory(hdl);
1392 nvlist_free(dst);
1393 nvlist_free(raw);
1394 nvlist_free(pools);
1395 return (NULL);
1396 }
1397 nvlist_free(dst);
1398 }
1399
1400 nvlist_free(raw);
1401 return (pools);
1402 }
1403
|