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  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*
  26  * Pool import support functions.
  27  *
  28  * To import a pool, we rely on reading the configuration information from the
  29  * ZFS label of each device.  If we successfully read the label, then we
  30  * organize the configuration information in the following hierarchy:
  31  *
  32  *      pool guid -> toplevel vdev guid -> label txg
  33  *
  34  * Duplicate entries matching this same tuple will be discarded.  Once we have
  35  * examined every device, we pick the best label txg config for each toplevel
  36  * vdev.  We then arrange these toplevel vdevs into a complete pool config, and
  37  * update any paths that have changed.  Finally, we attempt to import the pool
  38  * using our derived config, and record the results.
  39  */
  40 
  41 #include <ctype.h>
  42 #include <devid.h>
 
 
 420 }
 421 
 422 /*
 423  * Convert our list of pools into the definitive set of configurations.  We
 424  * start by picking the best config for each toplevel vdev.  Once that's done,
 425  * we assemble the toplevel vdevs into a full config for the pool.  We make a
 426  * pass to fix up any incorrect paths, and then add it to the main list to
 427  * return to the user.
 428  */
 429 static nvlist_t *
 430 get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
 431 {
 432         pool_entry_t *pe;
 433         vdev_entry_t *ve;
 434         config_entry_t *ce;
 435         nvlist_t *ret = NULL, *config = NULL, *tmp, *nvtop, *nvroot;
 436         nvlist_t **spares, **l2cache;
 437         uint_t i, nspares, nl2cache;
 438         boolean_t config_seen;
 439         uint64_t best_txg;
 440         char *name, *hostname;
 441         uint64_t version, guid;
 442         uint_t children = 0;
 443         nvlist_t **child = NULL;
 444         uint_t holes;
 445         uint64_t *hole_array, max_id;
 446         uint_t c;
 447         boolean_t isactive;
 448         uint64_t hostid;
 449         nvlist_t *nvl;
 450         boolean_t found_one = B_FALSE;
 451         boolean_t valid_top_config = B_FALSE;
 452 
 453         if (nvlist_alloc(&ret, 0, 0) != 0)
 454                 goto nomem;
 455 
 456         for (pe = pl->pools; pe != NULL; pe = pe->pe_next) {
 457                 uint64_t id, max_txg = 0;
 458 
 459                 if (nvlist_alloc(&config, NV_UNIQUE_NAME, 0) != 0)
 460                         goto nomem;
 
 509                                         valid_top_config = B_TRUE;
 510                                 }
 511 
 512                                 if (nvlist_lookup_uint64_array(tmp,
 513                                     ZPOOL_CONFIG_HOLE_ARRAY, &hole_array,
 514                                     &holes) == 0) {
 515                                         verify(nvlist_add_uint64_array(config,
 516                                             ZPOOL_CONFIG_HOLE_ARRAY,
 517                                             hole_array, holes) == 0);
 518                                 }
 519                         }
 520 
 521                         if (!config_seen) {
 522                                 /*
 523                                  * Copy the relevant pieces of data to the pool
 524                                  * configuration:
 525                                  *
 526                                  *      version
 527                                  *      pool guid
 528                                  *      name
 529                                  *      pool state
 530                                  *      hostid (if available)
 531                                  *      hostname (if available)
 532                                  */
 533                                 uint64_t state;
 534 
 535                                 verify(nvlist_lookup_uint64(tmp,
 536                                     ZPOOL_CONFIG_VERSION, &version) == 0);
 537                                 if (nvlist_add_uint64(config,
 538                                     ZPOOL_CONFIG_VERSION, version) != 0)
 539                                         goto nomem;
 540                                 verify(nvlist_lookup_uint64(tmp,
 541                                     ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
 542                                 if (nvlist_add_uint64(config,
 543                                     ZPOOL_CONFIG_POOL_GUID, guid) != 0)
 544                                         goto nomem;
 545                                 verify(nvlist_lookup_string(tmp,
 546                                     ZPOOL_CONFIG_POOL_NAME, &name) == 0);
 547                                 if (nvlist_add_string(config,
 548                                     ZPOOL_CONFIG_POOL_NAME, name) != 0)
 549                                         goto nomem;
 550                                 verify(nvlist_lookup_uint64(tmp,
 551                                     ZPOOL_CONFIG_POOL_STATE, &state) == 0);
 552                                 if (nvlist_add_uint64(config,
 553                                     ZPOOL_CONFIG_POOL_STATE, state) != 0)
 554                                         goto nomem;
 555                                 hostid = 0;
 556                                 if (nvlist_lookup_uint64(tmp,
 557                                     ZPOOL_CONFIG_HOSTID, &hostid) == 0) {
 558                                         if (nvlist_add_uint64(config,
 559                                             ZPOOL_CONFIG_HOSTID, hostid) != 0)
 560                                                 goto nomem;
 561                                         verify(nvlist_lookup_string(tmp,
 562                                             ZPOOL_CONFIG_HOSTNAME,
 563                                             &hostname) == 0);
 564                                         if (nvlist_add_string(config,
 565                                             ZPOOL_CONFIG_HOSTNAME,
 566                                             hostname) != 0)
 567                                                 goto nomem;
 568                                 }
 569 
 570                                 config_seen = B_TRUE;
 571                         }
 572 
 573                         /*
 574                          * Add this top-level vdev to the child array.
 
 | 
 
 
   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  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  24  * Copyright (c) 2011 by Delphix. All rights reserved.
  25  */
  26 
  27 /*
  28  * Pool import support functions.
  29  *
  30  * To import a pool, we rely on reading the configuration information from the
  31  * ZFS label of each device.  If we successfully read the label, then we
  32  * organize the configuration information in the following hierarchy:
  33  *
  34  *      pool guid -> toplevel vdev guid -> label txg
  35  *
  36  * Duplicate entries matching this same tuple will be discarded.  Once we have
  37  * examined every device, we pick the best label txg config for each toplevel
  38  * vdev.  We then arrange these toplevel vdevs into a complete pool config, and
  39  * update any paths that have changed.  Finally, we attempt to import the pool
  40  * using our derived config, and record the results.
  41  */
  42 
  43 #include <ctype.h>
  44 #include <devid.h>
 
 
 422 }
 423 
 424 /*
 425  * Convert our list of pools into the definitive set of configurations.  We
 426  * start by picking the best config for each toplevel vdev.  Once that's done,
 427  * we assemble the toplevel vdevs into a full config for the pool.  We make a
 428  * pass to fix up any incorrect paths, and then add it to the main list to
 429  * return to the user.
 430  */
 431 static nvlist_t *
 432 get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
 433 {
 434         pool_entry_t *pe;
 435         vdev_entry_t *ve;
 436         config_entry_t *ce;
 437         nvlist_t *ret = NULL, *config = NULL, *tmp, *nvtop, *nvroot;
 438         nvlist_t **spares, **l2cache;
 439         uint_t i, nspares, nl2cache;
 440         boolean_t config_seen;
 441         uint64_t best_txg;
 442         char *name, *hostname, *comment;
 443         uint64_t version, guid;
 444         uint_t children = 0;
 445         nvlist_t **child = NULL;
 446         uint_t holes;
 447         uint64_t *hole_array, max_id;
 448         uint_t c;
 449         boolean_t isactive;
 450         uint64_t hostid;
 451         nvlist_t *nvl;
 452         boolean_t found_one = B_FALSE;
 453         boolean_t valid_top_config = B_FALSE;
 454 
 455         if (nvlist_alloc(&ret, 0, 0) != 0)
 456                 goto nomem;
 457 
 458         for (pe = pl->pools; pe != NULL; pe = pe->pe_next) {
 459                 uint64_t id, max_txg = 0;
 460 
 461                 if (nvlist_alloc(&config, NV_UNIQUE_NAME, 0) != 0)
 462                         goto nomem;
 
 511                                         valid_top_config = B_TRUE;
 512                                 }
 513 
 514                                 if (nvlist_lookup_uint64_array(tmp,
 515                                     ZPOOL_CONFIG_HOLE_ARRAY, &hole_array,
 516                                     &holes) == 0) {
 517                                         verify(nvlist_add_uint64_array(config,
 518                                             ZPOOL_CONFIG_HOLE_ARRAY,
 519                                             hole_array, holes) == 0);
 520                                 }
 521                         }
 522 
 523                         if (!config_seen) {
 524                                 /*
 525                                  * Copy the relevant pieces of data to the pool
 526                                  * configuration:
 527                                  *
 528                                  *      version
 529                                  *      pool guid
 530                                  *      name
 531                                  *      comment (if available)
 532                                  *      pool state
 533                                  *      hostid (if available)
 534                                  *      hostname (if available)
 535                                  */
 536                                 uint64_t state;
 537 
 538                                 verify(nvlist_lookup_uint64(tmp,
 539                                     ZPOOL_CONFIG_VERSION, &version) == 0);
 540                                 if (nvlist_add_uint64(config,
 541                                     ZPOOL_CONFIG_VERSION, version) != 0)
 542                                         goto nomem;
 543                                 verify(nvlist_lookup_uint64(tmp,
 544                                     ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
 545                                 if (nvlist_add_uint64(config,
 546                                     ZPOOL_CONFIG_POOL_GUID, guid) != 0)
 547                                         goto nomem;
 548                                 verify(nvlist_lookup_string(tmp,
 549                                     ZPOOL_CONFIG_POOL_NAME, &name) == 0);
 550                                 if (nvlist_add_string(config,
 551                                     ZPOOL_CONFIG_POOL_NAME, name) != 0)
 552                                         goto nomem;
 553 
 554                                 /*
 555                                  * COMMENT is optional, don't bail if it's not
 556                                  * there, instead, set it to NULL.
 557                                  */
 558                                 if (nvlist_lookup_string(tmp,
 559                                     ZPOOL_CONFIG_COMMENT, &comment) != 0)
 560                                         comment = NULL;
 561                                 else if (nvlist_add_string(config,
 562                                     ZPOOL_CONFIG_COMMENT, comment) != 0)
 563                                         goto nomem;
 564 
 565                                 verify(nvlist_lookup_uint64(tmp,
 566                                     ZPOOL_CONFIG_POOL_STATE, &state) == 0);
 567                                 if (nvlist_add_uint64(config,
 568                                     ZPOOL_CONFIG_POOL_STATE, state) != 0)
 569                                         goto nomem;
 570 
 571                                 hostid = 0;
 572                                 if (nvlist_lookup_uint64(tmp,
 573                                     ZPOOL_CONFIG_HOSTID, &hostid) == 0) {
 574                                         if (nvlist_add_uint64(config,
 575                                             ZPOOL_CONFIG_HOSTID, hostid) != 0)
 576                                                 goto nomem;
 577                                         verify(nvlist_lookup_string(tmp,
 578                                             ZPOOL_CONFIG_HOSTNAME,
 579                                             &hostname) == 0);
 580                                         if (nvlist_add_string(config,
 581                                             ZPOOL_CONFIG_HOSTNAME,
 582                                             hostname) != 0)
 583                                                 goto nomem;
 584                                 }
 585 
 586                                 config_seen = B_TRUE;
 587                         }
 588 
 589                         /*
 590                          * Add this top-level vdev to the child array.
 
 |