1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2017 Nexenta Systems, Inc. 24 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 25 * Copyright (c) 2012, 2018 by Delphix. All rights reserved. 26 * Copyright 2015 RackTop Systems. 27 * Copyright (c) 2016, Intel Corporation. 28 */ 29 30 /* 31 * Pool import support functions. 32 * 33 * Used by zpool, ztest, zdb, and zhack to locate importable configs. Since 34 * these commands are expected to run in the global zone, we can assume 35 * that the devices are all readable when called. 36 * 37 * To import a pool, we rely on reading the configuration information from the 38 * ZFS label of each device. If we successfully read the label, then we 39 * organize the configuration information in the following hierarchy: 40 * 41 * pool guid -> toplevel vdev guid -> label txg 42 * 43 * Duplicate entries matching this same tuple will be discarded. Once we have 44 * examined every device, we pick the best label txg config for each toplevel 45 * vdev. We then arrange these toplevel vdevs into a complete pool config, and 46 * update any paths that have changed. Finally, we attempt to import the pool 47 * using our derived config, and record the results. 48 */ 49 50 #include <stdio.h> 51 #include <stdarg.h> 52 #include <assert.h> 53 #include <ctype.h> 54 #include <devid.h> 55 #include <dirent.h> 56 #include <errno.h> 57 #include <libintl.h> 58 #include <stddef.h> 59 #include <stdlib.h> 60 #include <string.h> 61 #include <sys/stat.h> 62 #include <unistd.h> 63 #include <fcntl.h> 64 #include <sys/vtoc.h> 65 #include <sys/dktp/fdisk.h> 66 #include <sys/efi_partition.h> 67 #include <sys/vdev_impl.h> 68 #include <sys/fs/zfs.h> 69 70 #include <thread_pool.h> 71 #include <libzutil.h> 72 #include <libnvpair.h> 73 74 #include "zutil_import.h" 75 76 #ifdef NDEBUG 77 #define verify(EX) ((void)(EX)) 78 #else 79 #define verify(EX) assert(EX) 80 #endif 81 82 /*PRINTFLIKE2*/ 83 static void 84 zutil_error_aux(libpc_handle_t *hdl, const char *fmt, ...) 85 { 86 va_list ap; 87 88 va_start(ap, fmt); 89 90 (void) vsnprintf(hdl->lpc_desc, sizeof (hdl->lpc_desc), fmt, ap); 91 hdl->lpc_desc_active = B_TRUE; 92 93 va_end(ap); 94 } 95 96 static void 97 zutil_verror(libpc_handle_t *hdl, const char *error, const char *fmt, 98 va_list ap) 99 { 100 char action[1024]; 101 102 (void) vsnprintf(action, sizeof (action), fmt, ap); 103 104 if (hdl->lpc_desc_active) 105 hdl->lpc_desc_active = B_FALSE; 106 else 107 hdl->lpc_desc[0] = '\0'; 108 109 if (hdl->lpc_printerr) { 110 if (hdl->lpc_desc[0] != '\0') 111 error = hdl->lpc_desc; 112 113 (void) fprintf(stderr, "%s: %s\n", action, error); 114 } 115 } 116 117 /*PRINTFLIKE3*/ 118 static int 119 zutil_error_fmt(libpc_handle_t *hdl, const char *error, const char *fmt, ...) 120 { 121 va_list ap; 122 123 va_start(ap, fmt); 124 125 zutil_verror(hdl, error, fmt, ap); 126 127 va_end(ap); 128 129 return (-1); 130 } 131 132 static int 133 zutil_error(libpc_handle_t *hdl, const char *error, const char *msg) 134 { 135 return (zutil_error_fmt(hdl, error, "%s", msg)); 136 } 137 138 static int 139 zutil_no_memory(libpc_handle_t *hdl) 140 { 141 (void) zutil_error(hdl, EZFS_NOMEM, "internal error"); 142 exit(1); 143 } 144 145 void * 146 zutil_alloc(libpc_handle_t *hdl, size_t size) 147 { 148 void *data; 149 150 if ((data = calloc(1, size)) == NULL) 151 (void) zutil_no_memory(hdl); 152 153 return (data); 154 } 155 156 char * 157 zutil_strdup(libpc_handle_t *hdl, const char *str) 158 { 159 char *ret; 160 161 if ((ret = strdup(str)) == NULL) 162 (void) zutil_no_memory(hdl); 163 164 return (ret); 165 } 166 167 /* 168 * Intermediate structures used to gather configuration information. 169 */ 170 typedef struct config_entry { 171 uint64_t ce_txg; 172 nvlist_t *ce_config; 173 struct config_entry *ce_next; 174 } config_entry_t; 175 176 typedef struct vdev_entry { 177 uint64_t ve_guid; 178 config_entry_t *ve_configs; 179 struct vdev_entry *ve_next; 180 } vdev_entry_t; 181 182 typedef struct pool_entry { 183 uint64_t pe_guid; 184 vdev_entry_t *pe_vdevs; 185 struct pool_entry *pe_next; 186 } pool_entry_t; 187 188 typedef struct name_entry { 189 char *ne_name; 190 uint64_t ne_guid; 191 struct name_entry *ne_next; 192 } name_entry_t; 193 194 typedef struct pool_list { 195 pool_entry_t *pools; 196 name_entry_t *names; 197 } pool_list_t; 198 199 /* 200 * Go through and fix up any path and/or devid information for the given vdev 201 * configuration. 202 */ 203 static int 204 fix_paths(nvlist_t *nv, name_entry_t *names) 205 { 206 nvlist_t **child; 207 uint_t c, children; 208 uint64_t guid; 209 name_entry_t *ne, *best; 210 char *path, *devid; 211 int matched; 212 213 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 214 &child, &children) == 0) { 215 for (c = 0; c < children; c++) 216 if (fix_paths(child[c], names) != 0) 217 return (-1); 218 return (0); 219 } 220 221 /* 222 * This is a leaf (file or disk) vdev. In either case, go through 223 * the name list and see if we find a matching guid. If so, replace 224 * the path and see if we can calculate a new devid. 225 * 226 * There may be multiple names associated with a particular guid, in 227 * which case we have overlapping slices or multiple paths to the same 228 * disk. If this is the case, then we want to pick the path that is 229 * the most similar to the original, where "most similar" is the number 230 * of matching characters starting from the end of the path. This will 231 * preserve slice numbers even if the disks have been reorganized, and 232 * will also catch preferred disk names if multiple paths exist. 233 */ 234 verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0); 235 if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0) 236 path = NULL; 237 238 matched = 0; 239 best = NULL; 240 for (ne = names; ne != NULL; ne = ne->ne_next) { 241 if (ne->ne_guid == guid) { 242 const char *src, *dst; 243 int count; 244 245 if (path == NULL) { 246 best = ne; 247 break; 248 } 249 250 src = ne->ne_name + strlen(ne->ne_name) - 1; 251 dst = path + strlen(path) - 1; 252 for (count = 0; src >= ne->ne_name && dst >= path; 253 src--, dst--, count++) 254 if (*src != *dst) 255 break; 256 257 /* 258 * At this point, 'count' is the number of characters 259 * matched from the end. 260 */ 261 if (count > matched || best == NULL) { 262 best = ne; 263 matched = count; 264 } 265 } 266 } 267 268 if (best == NULL) 269 return (0); 270 271 if (nvlist_add_string(nv, ZPOOL_CONFIG_PATH, best->ne_name) != 0) 272 return (-1); 273 274 if ((devid = devid_str_from_path(best->ne_name)) == NULL) { 275 (void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID); 276 } else { 277 if (nvlist_add_string(nv, ZPOOL_CONFIG_DEVID, devid) != 0) { 278 devid_str_free(devid); 279 return (-1); 280 } 281 devid_str_free(devid); 282 } 283 284 return (0); 285 } 286 287 /* 288 * Add the given configuration to the list of known devices. 289 */ 290 static int 291 add_config(libpc_handle_t *hdl, pool_list_t *pl, const char *path, 292 int order, int num_labels, nvlist_t *config) 293 { 294 uint64_t pool_guid, vdev_guid, top_guid, txg, state; 295 pool_entry_t *pe; 296 vdev_entry_t *ve; 297 config_entry_t *ce; 298 name_entry_t *ne; 299 300 /* 301 * If this is a hot spare not currently in use or level 2 cache 302 * device, add it to the list of names to translate, but don't do 303 * anything else. 304 */ 305 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, 306 &state) == 0 && 307 (state == POOL_STATE_SPARE || state == POOL_STATE_L2CACHE) && 308 nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid) == 0) { 309 if ((ne = zutil_alloc(hdl, sizeof (name_entry_t))) == NULL) 310 return (-1); 311 312 if ((ne->ne_name = zutil_strdup(hdl, path)) == NULL) { 313 free(ne); 314 return (-1); 315 } 316 317 ne->ne_guid = vdev_guid; 318 ne->ne_next = pl->names; 319 pl->names = ne; 320 321 return (0); 322 } 323 324 /* 325 * If we have a valid config but cannot read any of these fields, then 326 * it means we have a half-initialized label. In vdev_label_init() 327 * we write a label with txg == 0 so that we can identify the device 328 * in case the user refers to the same disk later on. If we fail to 329 * create the pool, we'll be left with a label in this state 330 * which should not be considered part of a valid pool. 331 */ 332 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 333 &pool_guid) != 0 || 334 nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, 335 &vdev_guid) != 0 || 336 nvlist_lookup_uint64(config, ZPOOL_CONFIG_TOP_GUID, 337 &top_guid) != 0 || 338 nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, 339 &txg) != 0 || txg == 0) { 340 return (0); 341 } 342 343 /* 344 * First, see if we know about this pool. If not, then add it to the 345 * list of known pools. 346 */ 347 for (pe = pl->pools; pe != NULL; pe = pe->pe_next) { 348 if (pe->pe_guid == pool_guid) 349 break; 350 } 351 352 if (pe == NULL) { 353 if ((pe = zutil_alloc(hdl, sizeof (pool_entry_t))) == NULL) { 354 return (-1); 355 } 356 pe->pe_guid = pool_guid; 357 pe->pe_next = pl->pools; 358 pl->pools = pe; 359 } 360 361 /* 362 * Second, see if we know about this toplevel vdev. Add it if its 363 * missing. 364 */ 365 for (ve = pe->pe_vdevs; ve != NULL; ve = ve->ve_next) { 366 if (ve->ve_guid == top_guid) 367 break; 368 } 369 370 if (ve == NULL) { 371 if ((ve = zutil_alloc(hdl, sizeof (vdev_entry_t))) == NULL) { 372 return (-1); 373 } 374 ve->ve_guid = top_guid; 375 ve->ve_next = pe->pe_vdevs; 376 pe->pe_vdevs = ve; 377 } 378 379 /* 380 * Third, see if we have a config with a matching transaction group. If 381 * so, then we do nothing. Otherwise, add it to the list of known 382 * configs. 383 */ 384 for (ce = ve->ve_configs; ce != NULL; ce = ce->ce_next) { 385 if (ce->ce_txg == txg) 386 break; 387 } 388 389 if (ce == NULL) { 390 if ((ce = zutil_alloc(hdl, sizeof (config_entry_t))) == NULL) { 391 return (-1); 392 } 393 ce->ce_txg = txg; 394 ce->ce_config = fnvlist_dup(config); 395 ce->ce_next = ve->ve_configs; 396 ve->ve_configs = ce; 397 } 398 399 /* 400 * At this point we've successfully added our config to the list of 401 * known configs. The last thing to do is add the vdev guid -> path 402 * mappings so that we can fix up the configuration as necessary before 403 * doing the import. 404 */ 405 if ((ne = zutil_alloc(hdl, sizeof (name_entry_t))) == NULL) 406 return (-1); 407 408 if ((ne->ne_name = zutil_strdup(hdl, path)) == NULL) { 409 free(ne); 410 return (-1); 411 } 412 413 ne->ne_guid = vdev_guid; 414 ne->ne_next = pl->names; 415 pl->names = ne; 416 417 return (0); 418 } 419 420 /* 421 * Returns true if the named pool matches the given GUID. 422 */ 423 static int 424 zutil_pool_active(libpc_handle_t *hdl, const char *name, uint64_t guid, 425 boolean_t *isactive) 426 { 427 ASSERT(hdl->lpc_ops->pco_pool_active != NULL); 428 429 int error = hdl->lpc_ops->pco_pool_active(hdl->lpc_lib_handle, name, 430 guid, isactive); 431 432 return (error); 433 } 434 435 static nvlist_t * 436 zutil_refresh_config(libpc_handle_t *hdl, nvlist_t *tryconfig) 437 { 438 ASSERT(hdl->lpc_ops->pco_refresh_config != NULL); 439 440 return (hdl->lpc_ops->pco_refresh_config(hdl->lpc_lib_handle, 441 tryconfig)); 442 } 443 444 /* 445 * Determine if the vdev id is a hole in the namespace. 446 */ 447 static boolean_t 448 vdev_is_hole(uint64_t *hole_array, uint_t holes, uint_t id) 449 { 450 for (int c = 0; c < holes; c++) { 451 452 /* Top-level is a hole */ 453 if (hole_array[c] == id) 454 return (B_TRUE); 455 } 456 return (B_FALSE); 457 } 458 459 /* 460 * Convert our list of pools into the definitive set of configurations. We 461 * start by picking the best config for each toplevel vdev. Once that's done, 462 * we assemble the toplevel vdevs into a full config for the pool. We make a 463 * pass to fix up any incorrect paths, and then add it to the main list to 464 * return to the user. 465 */ 466 static nvlist_t * 467 get_configs(libpc_handle_t *hdl, pool_list_t *pl, boolean_t active_ok, 468 nvlist_t *policy) 469 { 470 pool_entry_t *pe; 471 vdev_entry_t *ve; 472 config_entry_t *ce; 473 nvlist_t *ret = NULL, *config = NULL, *tmp = NULL, *nvtop, *nvroot; 474 nvlist_t **spares, **l2cache; 475 uint_t i, nspares, nl2cache; 476 boolean_t config_seen; 477 uint64_t best_txg; 478 char *name, *hostname = NULL; 479 uint64_t guid; 480 uint_t children = 0; 481 nvlist_t **child = NULL; 482 uint_t holes; 483 uint64_t *hole_array, max_id; 484 uint_t c; 485 boolean_t isactive; 486 uint64_t hostid; 487 nvlist_t *nvl; 488 boolean_t found_one = B_FALSE; 489 boolean_t valid_top_config = B_FALSE; 490 491 if (nvlist_alloc(&ret, 0, 0) != 0) 492 goto nomem; 493 494 for (pe = pl->pools; pe != NULL; pe = pe->pe_next) { 495 uint64_t id, max_txg = 0; 496 497 if (nvlist_alloc(&config, NV_UNIQUE_NAME, 0) != 0) 498 goto nomem; 499 config_seen = B_FALSE; 500 501 /* 502 * Iterate over all toplevel vdevs. Grab the pool configuration 503 * from the first one we find, and then go through the rest and 504 * add them as necessary to the 'vdevs' member of the config. 505 */ 506 for (ve = pe->pe_vdevs; ve != NULL; ve = ve->ve_next) { 507 508 /* 509 * Determine the best configuration for this vdev by 510 * selecting the config with the latest transaction 511 * group. 512 */ 513 best_txg = 0; 514 for (ce = ve->ve_configs; ce != NULL; 515 ce = ce->ce_next) { 516 517 if (ce->ce_txg > best_txg) { 518 tmp = ce->ce_config; 519 best_txg = ce->ce_txg; 520 } 521 } 522 523 /* 524 * We rely on the fact that the max txg for the 525 * pool will contain the most up-to-date information 526 * about the valid top-levels in the vdev namespace. 527 */ 528 if (best_txg > max_txg) { 529 (void) nvlist_remove(config, 530 ZPOOL_CONFIG_VDEV_CHILDREN, 531 DATA_TYPE_UINT64); 532 (void) nvlist_remove(config, 533 ZPOOL_CONFIG_HOLE_ARRAY, 534 DATA_TYPE_UINT64_ARRAY); 535 536 max_txg = best_txg; 537 hole_array = NULL; 538 holes = 0; 539 max_id = 0; 540 valid_top_config = B_FALSE; 541 542 if (nvlist_lookup_uint64(tmp, 543 ZPOOL_CONFIG_VDEV_CHILDREN, &max_id) == 0) { 544 verify(nvlist_add_uint64(config, 545 ZPOOL_CONFIG_VDEV_CHILDREN, 546 max_id) == 0); 547 valid_top_config = B_TRUE; 548 } 549 550 if (nvlist_lookup_uint64_array(tmp, 551 ZPOOL_CONFIG_HOLE_ARRAY, &hole_array, 552 &holes) == 0) { 553 verify(nvlist_add_uint64_array(config, 554 ZPOOL_CONFIG_HOLE_ARRAY, 555 hole_array, holes) == 0); 556 } 557 } 558 559 if (!config_seen) { 560 /* 561 * Copy the relevant pieces of data to the pool 562 * configuration: 563 * 564 * version 565 * pool guid 566 * name 567 * comment (if available) 568 * pool state 569 * hostid (if available) 570 * hostname (if available) 571 */ 572 uint64_t state, version; 573 char *comment = NULL; 574 575 version = fnvlist_lookup_uint64(tmp, 576 ZPOOL_CONFIG_VERSION); 577 fnvlist_add_uint64(config, 578 ZPOOL_CONFIG_VERSION, version); 579 guid = fnvlist_lookup_uint64(tmp, 580 ZPOOL_CONFIG_POOL_GUID); 581 fnvlist_add_uint64(config, 582 ZPOOL_CONFIG_POOL_GUID, guid); 583 name = fnvlist_lookup_string(tmp, 584 ZPOOL_CONFIG_POOL_NAME); 585 fnvlist_add_string(config, 586 ZPOOL_CONFIG_POOL_NAME, name); 587 588 if (nvlist_lookup_string(tmp, 589 ZPOOL_CONFIG_COMMENT, &comment) == 0) 590 fnvlist_add_string(config, 591 ZPOOL_CONFIG_COMMENT, comment); 592 593 state = fnvlist_lookup_uint64(tmp, 594 ZPOOL_CONFIG_POOL_STATE); 595 fnvlist_add_uint64(config, 596 ZPOOL_CONFIG_POOL_STATE, state); 597 598 hostid = 0; 599 if (nvlist_lookup_uint64(tmp, 600 ZPOOL_CONFIG_HOSTID, &hostid) == 0) { 601 fnvlist_add_uint64(config, 602 ZPOOL_CONFIG_HOSTID, hostid); 603 hostname = fnvlist_lookup_string(tmp, 604 ZPOOL_CONFIG_HOSTNAME); 605 fnvlist_add_string(config, 606 ZPOOL_CONFIG_HOSTNAME, hostname); 607 } 608 609 config_seen = B_TRUE; 610 } 611 612 /* 613 * Add this top-level vdev to the child array. 614 */ 615 verify(nvlist_lookup_nvlist(tmp, 616 ZPOOL_CONFIG_VDEV_TREE, &nvtop) == 0); 617 verify(nvlist_lookup_uint64(nvtop, ZPOOL_CONFIG_ID, 618 &id) == 0); 619 620 if (id >= children) { 621 nvlist_t **newchild; 622 623 newchild = zutil_alloc(hdl, (id + 1) * 624 sizeof (nvlist_t *)); 625 if (newchild == NULL) 626 goto nomem; 627 628 for (c = 0; c < children; c++) 629 newchild[c] = child[c]; 630 631 free(child); 632 child = newchild; 633 children = id + 1; 634 } 635 if (nvlist_dup(nvtop, &child[id], 0) != 0) 636 goto nomem; 637 638 } 639 640 /* 641 * If we have information about all the top-levels then 642 * clean up the nvlist which we've constructed. This 643 * means removing any extraneous devices that are 644 * beyond the valid range or adding devices to the end 645 * of our array which appear to be missing. 646 */ 647 if (valid_top_config) { 648 if (max_id < children) { 649 for (c = max_id; c < children; c++) 650 nvlist_free(child[c]); 651 children = max_id; 652 } else if (max_id > children) { 653 nvlist_t **newchild; 654 655 newchild = zutil_alloc(hdl, (max_id) * 656 sizeof (nvlist_t *)); 657 if (newchild == NULL) 658 goto nomem; 659 660 for (c = 0; c < children; c++) 661 newchild[c] = child[c]; 662 663 free(child); 664 child = newchild; 665 children = max_id; 666 } 667 } 668 669 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 670 &guid) == 0); 671 672 /* 673 * The vdev namespace may contain holes as a result of 674 * device removal. We must add them back into the vdev 675 * tree before we process any missing devices. 676 */ 677 if (holes > 0) { 678 ASSERT(valid_top_config); 679 680 for (c = 0; c < children; c++) { 681 nvlist_t *holey; 682 683 if (child[c] != NULL || 684 !vdev_is_hole(hole_array, holes, c)) 685 continue; 686 687 if (nvlist_alloc(&holey, NV_UNIQUE_NAME, 688 0) != 0) 689 goto nomem; 690 691 /* 692 * Holes in the namespace are treated as 693 * "hole" top-level vdevs and have a 694 * special flag set on them. 695 */ 696 if (nvlist_add_string(holey, 697 ZPOOL_CONFIG_TYPE, 698 VDEV_TYPE_HOLE) != 0 || 699 nvlist_add_uint64(holey, 700 ZPOOL_CONFIG_ID, c) != 0 || 701 nvlist_add_uint64(holey, 702 ZPOOL_CONFIG_GUID, 0ULL) != 0) { 703 nvlist_free(holey); 704 goto nomem; 705 } 706 child[c] = holey; 707 } 708 } 709 710 /* 711 * Look for any missing top-level vdevs. If this is the case, 712 * create a faked up 'missing' vdev as a placeholder. We cannot 713 * simply compress the child array, because the kernel performs 714 * certain checks to make sure the vdev IDs match their location 715 * in the configuration. 716 */ 717 for (c = 0; c < children; c++) { 718 if (child[c] == NULL) { 719 nvlist_t *missing; 720 if (nvlist_alloc(&missing, NV_UNIQUE_NAME, 721 0) != 0) 722 goto nomem; 723 if (nvlist_add_string(missing, 724 ZPOOL_CONFIG_TYPE, 725 VDEV_TYPE_MISSING) != 0 || 726 nvlist_add_uint64(missing, 727 ZPOOL_CONFIG_ID, c) != 0 || 728 nvlist_add_uint64(missing, 729 ZPOOL_CONFIG_GUID, 0ULL) != 0) { 730 nvlist_free(missing); 731 goto nomem; 732 } 733 child[c] = missing; 734 } 735 } 736 737 /* 738 * Put all of this pool's top-level vdevs into a root vdev. 739 */ 740 if (nvlist_alloc(&nvroot, NV_UNIQUE_NAME, 0) != 0) 741 goto nomem; 742 if (nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE, 743 VDEV_TYPE_ROOT) != 0 || 744 nvlist_add_uint64(nvroot, ZPOOL_CONFIG_ID, 0ULL) != 0 || 745 nvlist_add_uint64(nvroot, ZPOOL_CONFIG_GUID, guid) != 0 || 746 nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, 747 child, children) != 0) { 748 nvlist_free(nvroot); 749 goto nomem; 750 } 751 752 for (c = 0; c < children; c++) 753 nvlist_free(child[c]); 754 free(child); 755 children = 0; 756 child = NULL; 757 758 /* 759 * Go through and fix up any paths and/or devids based on our 760 * known list of vdev GUID -> path mappings. 761 */ 762 if (fix_paths(nvroot, pl->names) != 0) { 763 nvlist_free(nvroot); 764 goto nomem; 765 } 766 767 /* 768 * Add the root vdev to this pool's configuration. 769 */ 770 if (nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 771 nvroot) != 0) { 772 nvlist_free(nvroot); 773 goto nomem; 774 } 775 nvlist_free(nvroot); 776 777 /* 778 * zdb uses this path to report on active pools that were 779 * imported or created using -R. 780 */ 781 if (active_ok) 782 goto add_pool; 783 784 /* 785 * Determine if this pool is currently active, in which case we 786 * can't actually import it. 787 */ 788 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 789 &name) == 0); 790 verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, 791 &guid) == 0); 792 793 if (zutil_pool_active(hdl, name, guid, &isactive) != 0) 794 goto error; 795 796 if (isactive) { 797 nvlist_free(config); 798 config = NULL; 799 continue; 800 } 801 802 if (policy != NULL) { 803 if (nvlist_add_nvlist(config, ZPOOL_LOAD_POLICY, 804 policy) != 0) 805 goto nomem; 806 } 807 808 if ((nvl = zutil_refresh_config(hdl, config)) == NULL) { 809 nvlist_free(config); 810 config = NULL; 811 continue; 812 } 813 814 nvlist_free(config); 815 config = nvl; 816 817 /* 818 * Go through and update the paths for spares, now that we have 819 * them. 820 */ 821 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, 822 &nvroot) == 0); 823 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, 824 &spares, &nspares) == 0) { 825 for (i = 0; i < nspares; i++) { 826 if (fix_paths(spares[i], pl->names) != 0) 827 goto nomem; 828 } 829 } 830 831 /* 832 * Update the paths for l2cache devices. 833 */ 834 if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE, 835 &l2cache, &nl2cache) == 0) { 836 for (i = 0; i < nl2cache; i++) { 837 if (fix_paths(l2cache[i], pl->names) != 0) 838 goto nomem; 839 } 840 } 841 842 /* 843 * Restore the original information read from the actual label. 844 */ 845 (void) nvlist_remove(config, ZPOOL_CONFIG_HOSTID, 846 DATA_TYPE_UINT64); 847 (void) nvlist_remove(config, ZPOOL_CONFIG_HOSTNAME, 848 DATA_TYPE_STRING); 849 if (hostid != 0) { 850 verify(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID, 851 hostid) == 0); 852 verify(nvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME, 853 hostname) == 0); 854 } 855 856 add_pool: 857 /* 858 * Add this pool to the list of configs. 859 */ 860 verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, 861 &name) == 0); 862 if (nvlist_add_nvlist(ret, name, config) != 0) 863 goto nomem; 864 865 found_one = B_TRUE; 866 nvlist_free(config); 867 config = NULL; 868 } 869 870 if (!found_one) { 871 nvlist_free(ret); 872 ret = NULL; 873 } 874 875 return (ret); 876 877 nomem: 878 (void) zutil_no_memory(hdl); 879 error: 880 nvlist_free(config); 881 nvlist_free(ret); 882 for (c = 0; c < children; c++) 883 nvlist_free(child[c]); 884 free(child); 885 886 return (NULL); 887 } 888 889 /* 890 * Return the offset of the given label. 891 */ 892 static uint64_t 893 label_offset(uint64_t size, int l) 894 { 895 ASSERT(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t) == 0); 896 return (l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ? 897 0 : size - VDEV_LABELS * sizeof (vdev_label_t))); 898 } 899 900 /* 901 * Given a file descriptor, read the label information and return an nvlist 902 * describing the configuration, if there is one. The number of valid 903 * labels found will be returned in num_labels when non-NULL. 904 */ 905 int 906 zpool_read_label(int fd, nvlist_t **config, int *num_labels) 907 { 908 struct stat64 statbuf; 909 int l, count = 0; 910 vdev_label_t *label; 911 nvlist_t *expected_config = NULL; 912 uint64_t expected_guid = 0, size; 913 914 *config = NULL; 915 916 if (fstat64(fd, &statbuf) == -1) 917 return (-1); 918 size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t); 919 920 if ((label = malloc(sizeof (vdev_label_t))) == NULL) 921 return (-1); 922 923 for (l = 0; l < VDEV_LABELS; l++) { 924 uint64_t state, guid, txg; 925 926 if (pread64(fd, label, sizeof (vdev_label_t), 927 label_offset(size, l)) != sizeof (vdev_label_t)) 928 continue; 929 930 if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist, 931 sizeof (label->vl_vdev_phys.vp_nvlist), config, 0) != 0) 932 continue; 933 934 if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_GUID, 935 &guid) != 0 || guid == 0) { 936 nvlist_free(*config); 937 continue; 938 } 939 940 if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE, 941 &state) != 0 || state > POOL_STATE_L2CACHE) { 942 nvlist_free(*config); 943 continue; 944 } 945 946 if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE && 947 (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG, 948 &txg) != 0 || txg == 0)) { 949 nvlist_free(*config); 950 continue; 951 } 952 953 if (expected_guid) { 954 if (expected_guid == guid) 955 count++; 956 957 nvlist_free(*config); 958 } else { 959 expected_config = *config; 960 expected_guid = guid; 961 count++; 962 } 963 } 964 965 if (num_labels != NULL) 966 *num_labels = count; 967 968 free(label); 969 *config = expected_config; 970 971 if (count == 0) { 972 errno = ENOENT; 973 return (-1); 974 } 975 976 return (0); 977 } 978 979 static int 980 slice_cache_compare(const void *arg1, const void *arg2) 981 { 982 const char *nm1 = ((rdsk_node_t *)arg1)->rn_name; 983 const char *nm2 = ((rdsk_node_t *)arg2)->rn_name; 984 char *nm1slice, *nm2slice; 985 int rv; 986 987 /* 988 * slices zero and two are the most likely to provide results, 989 * so put those first 990 */ 991 nm1slice = strstr(nm1, "s0"); 992 nm2slice = strstr(nm2, "s0"); 993 if (nm1slice && !nm2slice) { 994 return (-1); 995 } 996 if (!nm1slice && nm2slice) { 997 return (1); 998 } 999 nm1slice = strstr(nm1, "s2"); 1000 nm2slice = strstr(nm2, "s2"); 1001 if (nm1slice && !nm2slice) { 1002 return (-1); 1003 } 1004 if (!nm1slice && nm2slice) { 1005 return (1); 1006 } 1007 1008 rv = strcmp(nm1, nm2); 1009 if (rv == 0) 1010 return (0); 1011 return (rv > 0 ? 1 : -1); 1012 } 1013 1014 static void 1015 check_one_slice(avl_tree_t *r, char *diskname, uint_t partno, 1016 diskaddr_t size, uint_t blksz) 1017 { 1018 rdsk_node_t tmpnode; 1019 rdsk_node_t *node; 1020 char sname[MAXNAMELEN]; 1021 1022 tmpnode.rn_name = &sname[0]; 1023 (void) snprintf(tmpnode.rn_name, MAXNAMELEN, "%s%u", 1024 diskname, partno); 1025 /* 1026 * protect against division by zero for disk labels that 1027 * contain a bogus sector size 1028 */ 1029 if (blksz == 0) 1030 blksz = DEV_BSIZE; 1031 /* too small to contain a zpool? */ 1032 if ((size < (SPA_MINDEVSIZE / blksz)) && 1033 (node = avl_find(r, &tmpnode, NULL))) 1034 node->rn_nozpool = B_TRUE; 1035 } 1036 1037 static void 1038 nozpool_all_slices(avl_tree_t *r, const char *sname) 1039 { 1040 char diskname[MAXNAMELEN]; 1041 char *ptr; 1042 int i; 1043 1044 (void) strncpy(diskname, sname, MAXNAMELEN); 1045 if (((ptr = strrchr(diskname, 's')) == NULL) && 1046 ((ptr = strrchr(diskname, 'p')) == NULL)) 1047 return; 1048 ptr[0] = 's'; 1049 ptr[1] = '\0'; 1050 for (i = 0; i < NDKMAP; i++) 1051 check_one_slice(r, diskname, i, 0, 1); 1052 ptr[0] = 'p'; 1053 for (i = 0; i <= FD_NUMPART; i++) 1054 check_one_slice(r, diskname, i, 0, 1); 1055 } 1056 1057 static void 1058 check_slices(avl_tree_t *r, int fd, const char *sname) 1059 { 1060 struct extvtoc vtoc; 1061 struct dk_gpt *gpt; 1062 char diskname[MAXNAMELEN]; 1063 char *ptr; 1064 int i; 1065 1066 (void) strncpy(diskname, sname, MAXNAMELEN); 1067 if ((ptr = strrchr(diskname, 's')) == NULL || !isdigit(ptr[1])) 1068 return; 1069 ptr[1] = '\0'; 1070 1071 if (read_extvtoc(fd, &vtoc) >= 0) { 1072 for (i = 0; i < NDKMAP; i++) 1073 check_one_slice(r, diskname, i, 1074 vtoc.v_part[i].p_size, vtoc.v_sectorsz); 1075 } else if (efi_alloc_and_read(fd, &gpt) >= 0) { 1076 /* 1077 * on x86 we'll still have leftover links that point 1078 * to slices s[9-15], so use NDKMAP instead 1079 */ 1080 for (i = 0; i < NDKMAP; i++) 1081 check_one_slice(r, diskname, i, 1082 gpt->efi_parts[i].p_size, gpt->efi_lbasize); 1083 /* nodes p[1-4] are never used with EFI labels */ 1084 ptr[0] = 'p'; 1085 for (i = 1; i <= FD_NUMPART; i++) 1086 check_one_slice(r, diskname, i, 0, 1); 1087 efi_free(gpt); 1088 } 1089 } 1090 1091 void 1092 zpool_open_func(void *arg) 1093 { 1094 rdsk_node_t *rn = arg; 1095 struct stat64 statbuf; 1096 nvlist_t *config; 1097 int error; 1098 int num_labels = 0; 1099 int fd; 1100 1101 if (rn->rn_nozpool) 1102 return; 1103 if ((fd = openat64(rn->rn_dfd, rn->rn_name, O_RDONLY)) < 0) { 1104 /* symlink to a device that's no longer there */ 1105 if (errno == ENOENT) 1106 nozpool_all_slices(rn->rn_avl, rn->rn_name); 1107 return; 1108 } 1109 /* 1110 * Ignore failed stats. We only want regular 1111 * files, character devs and block devs. 1112 */ 1113 if (fstat64(fd, &statbuf) != 0 || 1114 (!S_ISREG(statbuf.st_mode) && 1115 !S_ISCHR(statbuf.st_mode) && 1116 !S_ISBLK(statbuf.st_mode))) { 1117 (void) close(fd); 1118 return; 1119 } 1120 /* this file is too small to hold a zpool */ 1121 if (S_ISREG(statbuf.st_mode) && 1122 statbuf.st_size < SPA_MINDEVSIZE) { 1123 (void) close(fd); 1124 return; 1125 } else if (!S_ISREG(statbuf.st_mode)) { 1126 /* 1127 * Try to read the disk label first so we don't have to 1128 * open a bunch of minor nodes that can't have a zpool. 1129 */ 1130 check_slices(rn->rn_avl, fd, rn->rn_name); 1131 } 1132 1133 error = zpool_read_label(fd, &config, &num_labels); 1134 if (error != 0) { 1135 (void) close(fd); 1136 return; 1137 } 1138 1139 if (num_labels == 0) { 1140 (void) close(fd); 1141 nvlist_free(config); 1142 return; 1143 } 1144 1145 (void) close(fd); 1146 1147 rn->rn_config = config; 1148 rn->rn_num_labels = num_labels; 1149 } 1150 1151 /* 1152 * Given a list of directories to search, find all pools stored on disk. This 1153 * includes partial pools which are not available to import. If no args are 1154 * given (argc is 0), then the default directory (/dev/dsk) is searched. 1155 * poolname or guid (but not both) are provided by the caller when trying 1156 * to import a specific pool. 1157 */ 1158 static nvlist_t * 1159 zpool_find_import_impl(libpc_handle_t *hdl, importargs_t *iarg) 1160 { 1161 int i, dirs = iarg->paths; 1162 struct dirent64 *dp; 1163 char path[MAXPATHLEN]; 1164 char *end, **dir = iarg->path; 1165 size_t pathleft; 1166 nvlist_t *ret = NULL; 1167 static char *default_dir = ZFS_DISK_ROOT; 1168 pool_list_t pools = { 0 }; 1169 pool_entry_t *pe, *penext; 1170 vdev_entry_t *ve, *venext; 1171 config_entry_t *ce, *cenext; 1172 name_entry_t *ne, *nenext; 1173 avl_tree_t slice_cache; 1174 rdsk_node_t *slice; 1175 void *cookie; 1176 1177 if (dirs == 0) { 1178 dirs = 1; 1179 dir = &default_dir; 1180 } 1181 1182 /* 1183 * Go through and read the label configuration information from every 1184 * possible device, organizing the information according to pool GUID 1185 * and toplevel GUID. 1186 */ 1187 for (i = 0; i < dirs; i++) { 1188 tpool_t *t; 1189 char rdsk[MAXPATHLEN]; 1190 int dfd; 1191 boolean_t config_failed = B_FALSE; 1192 DIR *dirp; 1193 1194 /* use realpath to normalize the path */ 1195 if (realpath(dir[i], path) == 0) { 1196 (void) zutil_error_fmt(hdl, EZFS_BADPATH, 1197 dgettext(TEXT_DOMAIN, "cannot open '%s'"), dir[i]); 1198 goto error; 1199 } 1200 end = &path[strlen(path)]; 1201 *end++ = '/'; 1202 *end = 0; 1203 pathleft = &path[sizeof (path)] - end; 1204 1205 /* 1206 * Using raw devices instead of block devices when we're 1207 * reading the labels skips a bunch of slow operations during 1208 * close(2) processing, so we replace /dev/dsk with /dev/rdsk. 1209 */ 1210 if (strcmp(path, ZFS_DISK_ROOTD) == 0) 1211 (void) strlcpy(rdsk, ZFS_RDISK_ROOTD, sizeof (rdsk)); 1212 else 1213 (void) strlcpy(rdsk, path, sizeof (rdsk)); 1214 1215 if ((dfd = open64(rdsk, O_RDONLY)) < 0 || 1216 (dirp = fdopendir(dfd)) == NULL) { 1217 if (dfd >= 0) 1218 (void) close(dfd); 1219 zutil_error_aux(hdl, strerror(errno)); 1220 (void) zutil_error_fmt(hdl, EZFS_BADPATH, 1221 dgettext(TEXT_DOMAIN, "cannot open '%s'"), 1222 rdsk); 1223 goto error; 1224 } 1225 1226 avl_create(&slice_cache, slice_cache_compare, 1227 sizeof (rdsk_node_t), offsetof(rdsk_node_t, rn_node)); 1228 /* 1229 * This is not MT-safe, but we have no MT consumers of libzutil 1230 */ 1231 while ((dp = readdir64(dirp)) != NULL) { 1232 const char *name = dp->d_name; 1233 if (name[0] == '.' && 1234 (name[1] == 0 || (name[1] == '.' && name[2] == 0))) 1235 continue; 1236 1237 slice = zutil_alloc(hdl, sizeof (rdsk_node_t)); 1238 slice->rn_name = zutil_strdup(hdl, name); 1239 slice->rn_avl = &slice_cache; 1240 slice->rn_dfd = dfd; 1241 slice->rn_hdl = hdl; 1242 slice->rn_nozpool = B_FALSE; 1243 avl_add(&slice_cache, slice); 1244 } 1245 /* 1246 * create a thread pool to do all of this in parallel; 1247 * rn_nozpool is not protected, so this is racy in that 1248 * multiple tasks could decide that the same slice can 1249 * not hold a zpool, which is benign. Also choose 1250 * double the number of processors; we hold a lot of 1251 * locks in the kernel, so going beyond this doesn't 1252 * buy us much. 1253 */ 1254 t = tpool_create(1, 2 * sysconf(_SC_NPROCESSORS_ONLN), 1255 0, NULL); 1256 for (slice = avl_first(&slice_cache); slice; 1257 (slice = avl_walk(&slice_cache, slice, 1258 AVL_AFTER))) 1259 (void) tpool_dispatch(t, zpool_open_func, slice); 1260 tpool_wait(t); 1261 tpool_destroy(t); 1262 1263 cookie = NULL; 1264 while ((slice = avl_destroy_nodes(&slice_cache, 1265 &cookie)) != NULL) { 1266 if (slice->rn_config != NULL && !config_failed) { 1267 nvlist_t *config = slice->rn_config; 1268 boolean_t matched = B_TRUE; 1269 1270 if (iarg->poolname != NULL) { 1271 char *pname; 1272 1273 matched = nvlist_lookup_string(config, 1274 ZPOOL_CONFIG_POOL_NAME, 1275 &pname) == 0 && 1276 strcmp(iarg->poolname, pname) == 0; 1277 } else if (iarg->guid != 0) { 1278 uint64_t this_guid; 1279 1280 matched = nvlist_lookup_uint64(config, 1281 ZPOOL_CONFIG_POOL_GUID, 1282 &this_guid) == 0 && 1283 iarg->guid == this_guid; 1284 } 1285 if (matched) { 1286 /* 1287 * use the non-raw path for the config 1288 */ 1289 (void) strlcpy(end, slice->rn_name, 1290 pathleft); 1291 (void) add_config(hdl, &pools, 1292 path, slice->rn_order, 1293 slice->rn_num_labels, config); 1294 } 1295 nvlist_free(config); 1296 } 1297 free(slice->rn_name); 1298 free(slice); 1299 } 1300 avl_destroy(&slice_cache); 1301 1302 (void) closedir(dirp); 1303 1304 if (config_failed) 1305 goto error; 1306 } 1307 1308 ret = get_configs(hdl, &pools, iarg->can_be_active, iarg->policy); 1309 1310 error: 1311 for (pe = pools.pools; pe != NULL; pe = penext) { 1312 penext = pe->pe_next; 1313 for (ve = pe->pe_vdevs; ve != NULL; ve = venext) { 1314 venext = ve->ve_next; 1315 for (ce = ve->ve_configs; ce != NULL; ce = cenext) { 1316 cenext = ce->ce_next; 1317 nvlist_free(ce->ce_config); 1318 free(ce); 1319 } 1320 free(ve); 1321 } 1322 free(pe); 1323 } 1324 1325 for (ne = pools.names; ne != NULL; ne = nenext) { 1326 nenext = ne->ne_next; 1327 free(ne->ne_name); 1328 free(ne); 1329 } 1330 1331 return (ret); 1332 } 1333 1334 /* 1335 * Given a cache file, return the contents as a list of importable pools. 1336 * poolname or guid (but not both) are provided by the caller when trying 1337 * to import a specific pool. 1338 */ 1339 static nvlist_t * 1340 zpool_find_import_cached(libpc_handle_t *hdl, const char *cachefile, 1341 const char *poolname, uint64_t guid) 1342 { 1343 char *buf; 1344 int fd; 1345 struct stat64 statbuf; 1346 nvlist_t *raw, *src, *dst; 1347 nvlist_t *pools; 1348 nvpair_t *elem; 1349 char *name; 1350 uint64_t this_guid; 1351 boolean_t active; 1352 1353 verify(poolname == NULL || guid == 0); 1354 1355 if ((fd = open(cachefile, O_RDONLY)) < 0) { 1356 zutil_error_aux(hdl, "%s", strerror(errno)); 1357 (void) zutil_error(hdl, EZFS_BADCACHE, 1358 dgettext(TEXT_DOMAIN, "failed to open cache file")); 1359 return (NULL); 1360 } 1361 1362 if (fstat64(fd, &statbuf) != 0) { 1363 zutil_error_aux(hdl, "%s", strerror(errno)); 1364 (void) close(fd); 1365 (void) zutil_error(hdl, EZFS_BADCACHE, 1366 dgettext(TEXT_DOMAIN, "failed to get size of cache file")); 1367 return (NULL); 1368 } 1369 1370 if ((buf = zutil_alloc(hdl, statbuf.st_size)) == NULL) { 1371 (void) close(fd); 1372 return (NULL); 1373 } 1374 1375 if (read(fd, buf, statbuf.st_size) != statbuf.st_size) { 1376 (void) close(fd); 1377 free(buf); 1378 (void) zutil_error(hdl, EZFS_BADCACHE, 1379 dgettext(TEXT_DOMAIN, 1380 "failed to read cache file contents")); 1381 return (NULL); 1382 } 1383 1384 (void) close(fd); 1385 1386 if (nvlist_unpack(buf, statbuf.st_size, &raw, 0) != 0) { 1387 free(buf); 1388 (void) zutil_error(hdl, EZFS_BADCACHE, 1389 dgettext(TEXT_DOMAIN, 1390 "invalid or corrupt cache file contents")); 1391 return (NULL); 1392 } 1393 1394 free(buf); 1395 1396 /* 1397 * Go through and get the current state of the pools and refresh their 1398 * state. 1399 */ 1400 if (nvlist_alloc(&pools, 0, 0) != 0) { 1401 (void) zutil_no_memory(hdl); 1402 nvlist_free(raw); 1403 return (NULL); 1404 } 1405 1406 elem = NULL; 1407 while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) { 1408 src = fnvpair_value_nvlist(elem); 1409 1410 name = fnvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME); 1411 if (poolname != NULL && strcmp(poolname, name) != 0) 1412 continue; 1413 1414 this_guid = fnvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID); 1415 if (guid != 0 && guid != this_guid) 1416 continue; 1417 1418 if (zutil_pool_active(hdl, name, this_guid, &active) != 0) { 1419 nvlist_free(raw); 1420 nvlist_free(pools); 1421 return (NULL); 1422 } 1423 1424 if (active) 1425 continue; 1426 1427 if (nvlist_add_string(src, ZPOOL_CONFIG_CACHEFILE, 1428 cachefile) != 0) { 1429 (void) zutil_no_memory(hdl); 1430 nvlist_free(raw); 1431 nvlist_free(pools); 1432 return (NULL); 1433 } 1434 1435 if ((dst = zutil_refresh_config(hdl, src)) == NULL) { 1436 nvlist_free(raw); 1437 nvlist_free(pools); 1438 return (NULL); 1439 } 1440 1441 if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) { 1442 (void) zutil_no_memory(hdl); 1443 nvlist_free(dst); 1444 nvlist_free(raw); 1445 nvlist_free(pools); 1446 return (NULL); 1447 } 1448 nvlist_free(dst); 1449 } 1450 1451 nvlist_free(raw); 1452 return (pools); 1453 } 1454 1455 nvlist_t * 1456 zpool_search_import(void *hdl, importargs_t *import, 1457 const pool_config_ops_t *pco) 1458 { 1459 libpc_handle_t handle = { 0 }; 1460 nvlist_t *pools = NULL; 1461 1462 handle.lpc_lib_handle = hdl; 1463 handle.lpc_ops = pco; 1464 handle.lpc_printerr = B_TRUE; 1465 1466 verify(import->poolname == NULL || import->guid == 0); 1467 1468 if (import->cachefile != NULL) 1469 pools = zpool_find_import_cached(&handle, import->cachefile, 1470 import->poolname, import->guid); 1471 else 1472 pools = zpool_find_import_impl(&handle, import); 1473 1474 if ((pools == NULL || nvlist_empty(pools)) && 1475 handle.lpc_open_access_error && geteuid() != 0) { 1476 (void) zutil_error(&handle, EZFS_EACESS, dgettext(TEXT_DOMAIN, 1477 "no pools found")); 1478 } 1479 1480 return (pools); 1481 } 1482 1483 static boolean_t 1484 pool_match(nvlist_t *cfg, char *tgt) 1485 { 1486 uint64_t v, guid = strtoull(tgt, NULL, 0); 1487 char *s; 1488 1489 if (guid != 0) { 1490 if (nvlist_lookup_uint64(cfg, ZPOOL_CONFIG_POOL_GUID, &v) == 0) 1491 return (v == guid); 1492 } else { 1493 if (nvlist_lookup_string(cfg, ZPOOL_CONFIG_POOL_NAME, &s) == 0) 1494 return (strcmp(s, tgt) == 0); 1495 } 1496 return (B_FALSE); 1497 } 1498 1499 int 1500 zpool_find_config(void *hdl, const char *target, nvlist_t **configp, 1501 importargs_t *args, const pool_config_ops_t *pco) 1502 { 1503 nvlist_t *pools; 1504 nvlist_t *match = NULL; 1505 nvlist_t *config = NULL; 1506 char *sepp = NULL; 1507 int count = 0; 1508 char *targetdup = strdup(target); 1509 1510 *configp = NULL; 1511 1512 if ((sepp = strpbrk(targetdup, "/@")) != NULL) { 1513 *sepp = '\0'; 1514 } 1515 1516 pools = zpool_search_import(hdl, args, pco); 1517 1518 if (pools != NULL) { 1519 nvpair_t *elem = NULL; 1520 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 1521 VERIFY0(nvpair_value_nvlist(elem, &config)); 1522 if (pool_match(config, targetdup)) { 1523 count++; 1524 if (match != NULL) { 1525 /* multiple matches found */ 1526 continue; 1527 } else { 1528 match = config; 1529 } 1530 } 1531 } 1532 } 1533 1534 if (count == 0) { 1535 free(targetdup); 1536 return (ENOENT); 1537 } 1538 1539 if (count > 1) { 1540 free(targetdup); 1541 return (EINVAL); 1542 } 1543 1544 *configp = match; 1545 free(targetdup); 1546 1547 return (0); 1548 } 1549