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.
|