usr/src/lib/libzfs/common/libzfs_import.c
author Rich Morris <Richard.Morris@Sun.COM>
Wed, 10 Sep 2008 10:59:12 -0400
changeset 7538 18c2451107fd
parent 7043 22affca31e0f
child 10594 986cb68d2347
permissions -rw-r--r--
PSARC 2008/469 Excluding snapshot info from 'zfs list' 6734916 zfs list should omit snapshots by default 6734907 zfs list -t all would be useful once snapshots are omitted by default
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 1354
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
5994
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
    22
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
 * Pool import support functions.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
 * To import a pool, we rely on reading the configuration information from the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
 * ZFS label of each device.  If we successfully read the label, then we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
 * organize the configuration information in the following hierarchy:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
 * 	pool guid -> toplevel vdev guid -> label txg
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
 * Duplicate entries matching this same tuple will be discarded.  Once we have
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
 * examined every device, we pick the best label txg config for each toplevel
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
 * vdev.  We then arrange these toplevel vdevs into a complete pool config, and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
 * update any paths that have changed.  Finally, we attempt to import the pool
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
 * using our derived config, and record the results.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
#include <devid.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
#include <dirent.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
#include <errno.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
#include <libintl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
#include <stdlib.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
#include <string.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
#include <sys/stat.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
#include <unistd.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
#include <fcntl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
#include <sys/vdev_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
#include "libzfs.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
#include "libzfs_impl.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
 * Intermediate structures used to gather configuration information.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
typedef struct config_entry {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
	uint64_t		ce_txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
	nvlist_t		*ce_config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
	struct config_entry	*ce_next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
} config_entry_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
typedef struct vdev_entry {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
	uint64_t		ve_guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
	config_entry_t		*ve_configs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
	struct vdev_entry	*ve_next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
} vdev_entry_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
typedef struct pool_entry {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
	uint64_t		pe_guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
	vdev_entry_t		*pe_vdevs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
	struct pool_entry	*pe_next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
} pool_entry_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
typedef struct name_entry {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
    81
	char			*ne_name;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
	uint64_t		ne_guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
	struct name_entry	*ne_next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
} name_entry_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
typedef struct pool_list {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
	pool_entry_t		*pools;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
	name_entry_t		*names;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
} pool_list_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
static char *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
get_devid(const char *path)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
	int fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
	ddi_devid_t devid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
	char *minor, *ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
	if ((fd = open(path, O_RDONLY)) < 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
	minor = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
	ret = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
	if (devid_get(fd, &devid) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
		if (devid_get_minor_name(fd, &minor) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
			ret = devid_str_encode(devid, minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
		if (minor != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
			devid_str_free(minor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
		devid_free(devid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
	}
1354
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   110
	(void) close(fd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
 * Go through and fix up any path and/or devid information for the given vdev
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
 * configuration.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   120
static int
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
fix_paths(nvlist_t *nv, name_entry_t *names)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
	nvlist_t **child;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
	uint_t c, children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
	uint64_t guid;
1354
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   126
	name_entry_t *ne, *best;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   127
	char *path, *devid;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   128
	int matched;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
	    &child, &children) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
		for (c = 0; c < children; c++)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   133
			if (fix_paths(child[c], names) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   134
				return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   135
		return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	 * This is a leaf (file or disk) vdev.  In either case, go through
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	 * the name list and see if we find a matching guid.  If so, replace
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
	 * the path and see if we can calculate a new devid.
1354
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   142
	 *
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   143
	 * There may be multiple names associated with a particular guid, in
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   144
	 * which case we have overlapping slices or multiple paths to the same
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   145
	 * disk.  If this is the case, then we want to pick the path that is
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   146
	 * the most similar to the original, where "most similar" is the number
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   147
	 * of matching characters starting from the end of the path.  This will
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   148
	 * preserve slice numbers even if the disks have been reorganized, and
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   149
	 * will also catch preferred disk names if multiple paths exist.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
	verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid) == 0);
1354
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   152
	if (nvlist_lookup_string(nv, ZPOOL_CONFIG_PATH, &path) != 0)
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   153
		path = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
1354
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   155
	matched = 0;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   156
	best = NULL;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   157
	for (ne = names; ne != NULL; ne = ne->ne_next) {
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   158
		if (ne->ne_guid == guid) {
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   159
			const char *src, *dst;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   160
			int count;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   161
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   162
			if (path == NULL) {
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   163
				best = ne;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   164
				break;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   165
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
1354
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   167
			src = ne->ne_name + strlen(ne->ne_name) - 1;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   168
			dst = path + strlen(path) - 1;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   169
			for (count = 0; src >= ne->ne_name && dst >= path;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   170
			    src--, dst--, count++)
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   171
				if (*src != *dst)
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   172
					break;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   173
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   174
			/*
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   175
			 * At this point, 'count' is the number of characters
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   176
			 * matched from the end.
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   177
			 */
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   178
			if (count > matched || best == NULL) {
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   179
				best = ne;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   180
				matched = count;
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   181
			}
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   182
		}
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   183
	}
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   184
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   185
	if (best == NULL)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   186
		return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   188
	if (nvlist_add_string(nv, ZPOOL_CONFIG_PATH, best->ne_name) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   189
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
1354
81359ee1ee63 6362672 import gets confused about overlapping slices
eschrock
parents: 1352
diff changeset
   191
	if ((devid = get_devid(best->ne_name)) == NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
		(void) nvlist_remove_all(nv, ZPOOL_CONFIG_DEVID);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
	} else {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   194
		if (nvlist_add_string(nv, ZPOOL_CONFIG_DEVID, devid) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   195
			return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
		devid_str_free(devid);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
	}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   198
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   199
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
 * Add the given configuration to the list of known devices.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   205
static int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   206
add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   207
    nvlist_t *config)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
{
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   209
	uint64_t pool_guid, vdev_guid, top_guid, txg, state;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
	pool_entry_t *pe;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
	vdev_entry_t *ve;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
	config_entry_t *ce;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
	name_entry_t *ne;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
	/*
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   216
	 * If this is a hot spare not currently in use or level 2 cache
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   217
	 * device, add it to the list of names to translate, but don't do
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   218
	 * anything else.
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   219
	 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   220
	if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   221
	    &state) == 0 &&
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   222
	    (state == POOL_STATE_SPARE || state == POOL_STATE_L2CACHE) &&
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   223
	    nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid) == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   224
		if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL)
4055
9b8dd5af941d 6536445 want ::zio to show zio tree
eschrock
parents: 3975
diff changeset
   225
			return (-1);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   226
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   227
		if ((ne->ne_name = zfs_strdup(hdl, path)) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   228
			free(ne);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   229
			return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   230
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   231
		ne->ne_guid = vdev_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   232
		ne->ne_next = pl->names;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   233
		pl->names = ne;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   234
		return (0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   235
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   236
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   237
	/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
	 * If we have a valid config but cannot read any of these fields, then
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
	 * it means we have a half-initialized label.  In vdev_label_init()
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
	 * we write a label with txg == 0 so that we can identify the device
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
	 * in case the user refers to the same disk later on.  If we fail to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
	 * create the pool, we'll be left with a label in this state
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
	 * which should not be considered part of a valid pool.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
	if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
	    &pool_guid) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
	    nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
	    &vdev_guid) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
	    nvlist_lookup_uint64(config, ZPOOL_CONFIG_TOP_GUID,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
	    &top_guid) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
	    nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	    &txg) != 0 || txg == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
		nvlist_free(config);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   254
		return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
	 * First, see if we know about this pool.  If not, then add it to the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
	 * list of known pools.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
	for (pe = pl->pools; pe != NULL; pe = pe->pe_next) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
		if (pe->pe_guid == pool_guid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
	if (pe == NULL) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   267
		if ((pe = zfs_alloc(hdl, sizeof (pool_entry_t))) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   268
			nvlist_free(config);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   269
			return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   270
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
		pe->pe_guid = pool_guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
		pe->pe_next = pl->pools;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
		pl->pools = pe;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
	 * Second, see if we know about this toplevel vdev.  Add it if its
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
	 * missing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
	for (ve = pe->pe_vdevs; ve != NULL; ve = ve->ve_next) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
		if (ve->ve_guid == top_guid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
	if (ve == NULL) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   286
		if ((ve = zfs_alloc(hdl, sizeof (vdev_entry_t))) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   287
			nvlist_free(config);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   288
			return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   289
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
		ve->ve_guid = top_guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
		ve->ve_next = pe->pe_vdevs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
		pe->pe_vdevs = ve;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
	 * Third, see if we have a config with a matching transaction group.  If
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	 * so, then we do nothing.  Otherwise, add it to the list of known
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
	 * configs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
	for (ce = ve->ve_configs; ce != NULL; ce = ce->ce_next) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
		if (ce->ce_txg == txg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
	if (ce == NULL) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   306
		if ((ce = zfs_alloc(hdl, sizeof (config_entry_t))) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   307
			nvlist_free(config);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   308
			return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   309
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
		ce->ce_txg = txg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
		ce->ce_config = config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
		ce->ce_next = ve->ve_configs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
		ve->ve_configs = ce;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
		nvlist_free(config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	 * At this point we've successfully added our config to the list of
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
	 * known configs.  The last thing to do is add the vdev guid -> path
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	 * mappings so that we can fix up the configuration as necessary before
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
	 * doing the import.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   324
	if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   325
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   327
	if ((ne->ne_name = zfs_strdup(hdl, path)) == NULL) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   328
		free(ne);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   329
		return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   330
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   331
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
	ne->ne_guid = vdev_guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	ne->ne_next = pl->names;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
	pl->names = ne;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   335
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   336
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
/*
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   340
 * Returns true if the named pool matches the given GUID.
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   341
 */
2142
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   342
static int
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   343
pool_active(libzfs_handle_t *hdl, const char *name, uint64_t guid,
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   344
    boolean_t *isactive)
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   345
{
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   346
	zpool_handle_t *zhp;
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   347
	uint64_t theguid;
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   348
2142
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   349
	if (zpool_open_silent(hdl, name, &zhp) != 0)
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   350
		return (-1);
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   351
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   352
	if (zhp == NULL) {
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   353
		*isactive = B_FALSE;
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   354
		return (0);
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   355
	}
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   356
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   357
	verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_POOL_GUID,
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   358
	    &theguid) == 0);
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   359
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   360
	zpool_close(zhp);
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   361
2142
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   362
	*isactive = (theguid == guid);
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   363
	return (0);
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   364
}
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   365
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   366
static nvlist_t *
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   367
refresh_config(libzfs_handle_t *hdl, nvlist_t *config)
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   368
{
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   369
	nvlist_t *nvl;
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   370
	zfs_cmd_t zc = { 0 };
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   371
	int err;
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   372
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   373
	if (zcmd_write_conf_nvlist(hdl, &zc, config) != 0)
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   374
		return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   375
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   376
	if (zcmd_alloc_dst_nvlist(hdl, &zc,
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   377
	    zc.zc_nvlist_conf_size * 2) != 0) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   378
		zcmd_free_nvlists(&zc);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   379
		return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   380
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   381
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   382
	while ((err = ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_TRYIMPORT,
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   383
	    &zc)) != 0 && errno == ENOMEM) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   384
		if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   385
			zcmd_free_nvlists(&zc);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   386
			return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   387
		}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   388
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   389
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   390
	if (err) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   391
		(void) zpool_standard_error(hdl, errno,
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   392
		    dgettext(TEXT_DOMAIN, "cannot discover pools"));
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   393
		zcmd_free_nvlists(&zc);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   394
		return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   395
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   396
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   397
	if (zcmd_read_dst_nvlist(hdl, &zc, &nvl) != 0) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   398
		zcmd_free_nvlists(&zc);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   399
		return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   400
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   401
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   402
	zcmd_free_nvlists(&zc);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   403
	return (nvl);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   404
}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   405
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
   406
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
 * Convert our list of pools into the definitive set of configurations.  We
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
 * start by picking the best config for each toplevel vdev.  Once that's done,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   409
 * we assemble the toplevel vdevs into a full config for the pool.  We make a
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
 * pass to fix up any incorrect paths, and then add it to the main list to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
 * return to the user.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
static nvlist_t *
5994
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   414
get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
{
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   416
	pool_entry_t *pe;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   417
	vdev_entry_t *ve;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   418
	config_entry_t *ce;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   419
	nvlist_t *ret = NULL, *config = NULL, *tmp, *nvtop, *nvroot;
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   420
	nvlist_t **spares, **l2cache;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   421
	uint_t i, nspares, nl2cache;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   422
	boolean_t config_seen;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
	uint64_t best_txg;
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   424
	char *name, *hostname;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   425
	uint64_t version, guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   426
	uint_t children = 0;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   427
	nvlist_t **child = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   428
	uint_t c;
2142
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   429
	boolean_t isactive;
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   430
	uint64_t hostid;
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   431
	nvlist_t *nvl;
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   432
	boolean_t found_one = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   434
	if (nvlist_alloc(&ret, 0, 0) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   435
		goto nomem;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   436
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   437
	for (pe = pl->pools; pe != NULL; pe = pe->pe_next) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
		uint64_t id;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   440
		if (nvlist_alloc(&config, NV_UNIQUE_NAME, 0) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   441
			goto nomem;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   442
		config_seen = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   443
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   444
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
		 * Iterate over all toplevel vdevs.  Grab the pool configuration
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   446
		 * from the first one we find, and then go through the rest and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
		 * add them as necessary to the 'vdevs' member of the config.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   449
		for (ve = pe->pe_vdevs; ve != NULL; ve = ve->ve_next) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
			 * Determine the best configuration for this vdev by
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
			 * selecting the config with the latest transaction
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
			 * group.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
			best_txg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
			for (ce = ve->ve_configs; ce != NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
			    ce = ce->ce_next) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   460
				if (ce->ce_txg > best_txg) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
					tmp = ce->ce_config;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   462
					best_txg = ce->ce_txg;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   463
				}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
			if (!config_seen) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
				 * Copy the relevant pieces of data to the pool
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
				 * configuration:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
				 *
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   471
				 *	version
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
				 * 	pool guid
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
				 * 	name
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
				 * 	pool state
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   475
				 *	hostid (if available)
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   476
				 *	hostname (if available)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
				uint64_t state;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
				verify(nvlist_lookup_uint64(tmp,
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   481
				    ZPOOL_CONFIG_VERSION, &version) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   482
				if (nvlist_add_uint64(config,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   483
				    ZPOOL_CONFIG_VERSION, version) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   484
					goto nomem;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   485
				verify(nvlist_lookup_uint64(tmp,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
				    ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   487
				if (nvlist_add_uint64(config,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   488
				    ZPOOL_CONFIG_POOL_GUID, guid) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   489
					goto nomem;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
				verify(nvlist_lookup_string(tmp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
				    ZPOOL_CONFIG_POOL_NAME, &name) == 0);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   492
				if (nvlist_add_string(config,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   493
				    ZPOOL_CONFIG_POOL_NAME, name) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   494
					goto nomem;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
				verify(nvlist_lookup_uint64(tmp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
				    ZPOOL_CONFIG_POOL_STATE, &state) == 0);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   497
				if (nvlist_add_uint64(config,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   498
				    ZPOOL_CONFIG_POOL_STATE, state) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   499
					goto nomem;
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   500
				hostid = 0;
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   501
				if (nvlist_lookup_uint64(tmp,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   502
				    ZPOOL_CONFIG_HOSTID, &hostid) == 0) {
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   503
					if (nvlist_add_uint64(config,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   504
					    ZPOOL_CONFIG_HOSTID, hostid) != 0)
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   505
						goto nomem;
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   506
					verify(nvlist_lookup_string(tmp,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   507
					    ZPOOL_CONFIG_HOSTNAME,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   508
					    &hostname) == 0);
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   509
					if (nvlist_add_string(config,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   510
					    ZPOOL_CONFIG_HOSTNAME,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   511
					    hostname) != 0)
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   512
						goto nomem;
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   513
				}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   515
				config_seen = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
			 * Add this top-level vdev to the child array.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
			verify(nvlist_lookup_nvlist(tmp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
			    ZPOOL_CONFIG_VDEV_TREE, &nvtop) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
			verify(nvlist_lookup_uint64(nvtop, ZPOOL_CONFIG_ID,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
			    &id) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
			if (id >= children) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   526
				nvlist_t **newchild;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   527
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   528
				newchild = zfs_alloc(hdl, (id + 1) *
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
				    sizeof (nvlist_t *));
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   530
				if (newchild == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   531
					goto nomem;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
				for (c = 0; c < children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
					newchild[c] = child[c];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
				free(child);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
				child = newchild;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
				children = id + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
			}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   540
			if (nvlist_dup(nvtop, &child[id], 0) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   541
				goto nomem;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
		    &guid) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
		 * Look for any missing top-level vdevs.  If this is the case,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
		 * create a faked up 'missing' vdev as a placeholder.  We cannot
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
		 * simply compress the child array, because the kernel performs
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
		 * certain checks to make sure the vdev IDs match their location
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
		 * in the configuration.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
		for (c = 0; c < children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
			if (child[c] == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
				nvlist_t *missing;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   558
				if (nvlist_alloc(&missing, NV_UNIQUE_NAME,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   559
				    0) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   560
					goto nomem;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   561
				if (nvlist_add_string(missing,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   562
				    ZPOOL_CONFIG_TYPE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   563
				    VDEV_TYPE_MISSING) != 0 ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   564
				    nvlist_add_uint64(missing,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   565
				    ZPOOL_CONFIG_ID, c) != 0 ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   566
				    nvlist_add_uint64(missing,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   567
				    ZPOOL_CONFIG_GUID, 0ULL) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   568
					nvlist_free(missing);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   569
					goto nomem;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   570
				}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
				child[c] = missing;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
		 * Put all of this pool's top-level vdevs into a root vdev.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   577
		if (nvlist_alloc(&nvroot, NV_UNIQUE_NAME, 0) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   578
			goto nomem;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   579
		if (nvlist_add_string(nvroot, ZPOOL_CONFIG_TYPE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   580
		    VDEV_TYPE_ROOT) != 0 ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   581
		    nvlist_add_uint64(nvroot, ZPOOL_CONFIG_ID, 0ULL) != 0 ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   582
		    nvlist_add_uint64(nvroot, ZPOOL_CONFIG_GUID, guid) != 0 ||
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   583
		    nvlist_add_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   584
		    child, children) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   585
			nvlist_free(nvroot);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   586
			goto nomem;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   587
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
		for (c = 0; c < children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
			nvlist_free(child[c]);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
		free(child);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   592
		children = 0;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   593
		child = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
		 * Go through and fix up any paths and/or devids based on our
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
		 * known list of vdev GUID -> path mappings.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   599
		if (fix_paths(nvroot, pl->names) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   600
			nvlist_free(nvroot);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   601
			goto nomem;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   602
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
		 * Add the root vdev to this pool's configuration.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
		 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   607
		if (nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   608
		    nvroot) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   609
			nvlist_free(nvroot);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   610
			goto nomem;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   611
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
		nvlist_free(nvroot);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
		/*
5994
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   615
		 * zdb uses this path to report on active pools that were
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   616
		 * imported or created using -R.
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   617
		 */
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   618
		if (active_ok)
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   619
			goto add_pool;
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   620
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   621
		/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
		 * Determine if this pool is currently active, in which case we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
		 * can't actually import it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   625
		verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
		    &name) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
		    &guid) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
2142
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   630
		if (pool_active(hdl, name, guid, &isactive) != 0)
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   631
			goto error;
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   632
2144
2c87e20b9112 6435779 6433679 broke zpool import
eschrock
parents: 2142
diff changeset
   633
		if (isactive) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
			nvlist_free(config);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   635
			config = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   638
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   639
		if ((nvl = refresh_config(hdl, config)) == NULL)
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2474
diff changeset
   640
			goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   641
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   642
		nvlist_free(config);
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   643
		config = nvl;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   644
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   645
		/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   646
		 * Go through and update the paths for spares, now that we have
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   647
		 * them.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   648
		 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   649
		verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   650
		    &nvroot) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   651
		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   652
		    &spares, &nspares) == 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   653
			for (i = 0; i < nspares; i++) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   654
				if (fix_paths(spares[i], pl->names) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   655
					goto nomem;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   656
			}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   657
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   658
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   659
		/*
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   660
		 * Update the paths for l2cache devices.
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   661
		 */
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   662
		if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_L2CACHE,
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   663
		    &l2cache, &nl2cache) == 0) {
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   664
			for (i = 0; i < nl2cache; i++) {
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   665
				if (fix_paths(l2cache[i], pl->names) != 0)
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   666
					goto nomem;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   667
			}
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   668
		}
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   669
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   670
		/*
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   671
		 * Restore the original information read from the actual label.
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   672
		 */
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   673
		(void) nvlist_remove(config, ZPOOL_CONFIG_HOSTID,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   674
		    DATA_TYPE_UINT64);
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   675
		(void) nvlist_remove(config, ZPOOL_CONFIG_HOSTNAME,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   676
		    DATA_TYPE_STRING);
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   677
		if (hostid != 0) {
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   678
			verify(nvlist_add_uint64(config, ZPOOL_CONFIG_HOSTID,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   679
			    hostid) == 0);
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   680
			verify(nvlist_add_string(config, ZPOOL_CONFIG_HOSTNAME,
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   681
			    hostname) == 0);
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   682
		}
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   683
5994
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   684
add_pool:
3975
6674f5d79069 6282725 hostname/hostid should be stored in the label
ek110237
parents: 3741
diff changeset
   685
		/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   686
		 * Add this pool to the list of configs.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
		 */
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2474
diff changeset
   688
		verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2474
diff changeset
   689
		    &name) == 0);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   690
		if (nvlist_add_nvlist(ret, name, config) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   691
			goto nomem;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   692
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   693
		found_one = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
		nvlist_free(config);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   695
		config = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   696
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   698
	if (!found_one) {
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   699
		nvlist_free(ret);
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   700
		ret = NULL;
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   701
	}
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   702
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
	return (ret);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   704
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   705
nomem:
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   706
	(void) no_memory(hdl);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   707
error:
2142
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   708
	nvlist_free(config);
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   709
	nvlist_free(ret);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   710
	for (c = 0; c < children; c++)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   711
		nvlist_free(child[c]);
2142
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
   712
	free(child);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   713
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   714
	return (NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   715
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   716
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   717
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   718
 * Return the offset of the given label.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   719
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
static uint64_t
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4055
diff changeset
   721
label_offset(uint64_t size, int l)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   722
{
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4055
diff changeset
   723
	ASSERT(P2PHASE_TYPED(size, sizeof (vdev_label_t), uint64_t) == 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   724
	return (l * sizeof (vdev_label_t) + (l < VDEV_LABELS / 2 ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   725
	    0 : size - VDEV_LABELS * sizeof (vdev_label_t)));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
 * Given a file descriptor, read the label information and return an nvlist
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
 * describing the configuration, if there is one.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   732
int
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   733
zpool_read_label(int fd, nvlist_t **config)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   734
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
	struct stat64 statbuf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   736
	int l;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   737
	vdev_label_t *label;
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4055
diff changeset
   738
	uint64_t state, txg, size;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   740
	*config = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   741
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   742
	if (fstat64(fd, &statbuf) == -1)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   743
		return (0);
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4055
diff changeset
   744
	size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   745
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   746
	if ((label = malloc(sizeof (vdev_label_t))) == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   747
		return (-1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   748
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   749
	for (l = 0; l < VDEV_LABELS; l++) {
6643
3a34b0dbb107 6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents: 6376
diff changeset
   750
		if (pread64(fd, label, sizeof (vdev_label_t),
4577
ed36b0e652bc PSARC/2007/328 zfs upgrade
ahrens
parents: 4055
diff changeset
   751
		    label_offset(size, l)) != sizeof (vdev_label_t))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   752
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   753
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   754
		if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   755
		    sizeof (label->vl_vdev_phys.vp_nvlist), config, 0) != 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   756
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   757
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   758
		if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   759
		    &state) != 0 || state > POOL_STATE_L2CACHE) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   760
			nvlist_free(*config);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
   764
		if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   765
		    (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   766
		    &txg) != 0 || txg == 0)) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   767
			nvlist_free(*config);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
			continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   769
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   770
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
		free(label);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   772
		return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   773
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   774
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   775
	free(label);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   776
	*config = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   777
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   778
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   779
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   780
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   781
 * Given a list of directories to search, find all pools stored on disk.  This
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   782
 * includes partial pools which are not available to import.  If no args are
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   783
 * given (argc is 0), then the default directory (/dev/dsk) is searched.
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   784
 * poolname or guid (but not both) are provided by the caller when trying
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   785
 * to import a specific pool.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   786
 */
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   787
static nvlist_t *
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   788
zpool_find_import_impl(libzfs_handle_t *hdl, int argc, char **argv,
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   789
    boolean_t active_ok, char *poolname, uint64_t guid)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   790
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   791
	int i;
4055
9b8dd5af941d 6536445 want ::zio to show zio tree
eschrock
parents: 3975
diff changeset
   792
	DIR *dirp = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   793
	struct dirent64 *dp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   794
	char path[MAXPATHLEN];
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   795
	char *end;
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   796
	size_t pathleft;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   797
	struct stat64 statbuf;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   798
	nvlist_t *ret = NULL, *config;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   799
	static char *default_dir = "/dev/dsk";
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   800
	int fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   801
	pool_list_t pools = { 0 };
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   802
	pool_entry_t *pe, *penext;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   803
	vdev_entry_t *ve, *venext;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   804
	config_entry_t *ce, *cenext;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   805
	name_entry_t *ne, *nenext;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   806
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   807
	verify(poolname == NULL || guid == 0);
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   808
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   809
	if (argc == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   810
		argc = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   811
		argv = &default_dir;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   812
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   813
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   814
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   815
	 * Go through and read the label configuration information from every
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   816
	 * possible device, organizing the information according to pool GUID
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   817
	 * and toplevel GUID.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   818
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   819
	for (i = 0; i < argc; i++) {
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   820
		char *rdsk;
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   821
		int dfd;
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   822
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   823
		/* use realpath to normalize the path */
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   824
		if (realpath(argv[i], path) == 0) {
3237
98d0c28f2f5e 6480245 renaming a dataset to something with '%s' will cause segfault
lling
parents: 2676
diff changeset
   825
			(void) zfs_error_fmt(hdl, EZFS_BADPATH,
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   826
			    dgettext(TEXT_DOMAIN, "cannot open '%s'"),
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   827
			    argv[i]);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   828
			goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   829
		}
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   830
		end = &path[strlen(path)];
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   831
		*end++ = '/';
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   832
		*end = 0;
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   833
		pathleft = &path[sizeof (path)] - end;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   834
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   835
		/*
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   836
		 * Using raw devices instead of block devices when we're
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   837
		 * reading the labels skips a bunch of slow operations during
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   838
		 * close(2) processing, so we replace /dev/dsk with /dev/rdsk.
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   839
		 */
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   840
		if (strcmp(path, "/dev/dsk/") == 0)
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   841
			rdsk = "/dev/rdsk/";
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   842
		else
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   843
			rdsk = path;
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   844
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   845
		if ((dfd = open64(rdsk, O_RDONLY)) < 0 ||
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   846
		    (dirp = fdopendir(dfd)) == NULL) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   847
			zfs_error_aux(hdl, strerror(errno));
3237
98d0c28f2f5e 6480245 renaming a dataset to something with '%s' will cause segfault
lling
parents: 2676
diff changeset
   848
			(void) zfs_error_fmt(hdl, EZFS_BADPATH,
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   849
			    dgettext(TEXT_DOMAIN, "cannot open '%s'"),
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   850
			    rdsk);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   851
			goto error;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   852
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   853
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   854
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   855
		 * This is not MT-safe, but we have no MT consumers of libzfs
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   856
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   857
		while ((dp = readdir64(dirp)) != NULL) {
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   858
			const char *name = dp->d_name;
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   859
			if (name[0] == '.' &&
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   860
			    (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   861
				continue;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   862
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   863
			if ((fd = openat64(dfd, name, O_RDONLY)) < 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   864
				continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   865
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   866
			/*
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   867
			 * Ignore failed stats.  We only want regular
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   868
			 * files, character devs and block devs.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   869
			 */
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   870
			if (fstat64(fd, &statbuf) != 0 ||
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   871
			    (!S_ISREG(statbuf.st_mode) &&
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   872
			    !S_ISCHR(statbuf.st_mode) &&
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   873
			    !S_ISBLK(statbuf.st_mode))) {
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   874
				(void) close(fd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   875
				continue;
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   876
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   877
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   878
			if ((zpool_read_label(fd, &config)) != 0) {
4055
9b8dd5af941d 6536445 want ::zio to show zio tree
eschrock
parents: 3975
diff changeset
   879
				(void) close(fd);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   880
				(void) no_memory(hdl);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   881
				goto error;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   882
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   883
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   884
			(void) close(fd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   885
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   886
			if (config != NULL) {
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   887
				boolean_t matched = B_TRUE;
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   888
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   889
				if (poolname != NULL) {
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   890
					char *pname;
6895
cbb17a22c911 6712841 nvlist_lookup_string(config, "name", &pname) == 0, file ../com mon/libzfs_import.c, line 893, functi
ck153898
parents: 6807
diff changeset
   891
cbb17a22c911 6712841 nvlist_lookup_string(config, "name", &pname) == 0, file ../com mon/libzfs_import.c, line 893, functi
ck153898
parents: 6807
diff changeset
   892
					matched = nvlist_lookup_string(config,
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   893
					    ZPOOL_CONFIG_POOL_NAME,
6895
cbb17a22c911 6712841 nvlist_lookup_string(config, "name", &pname) == 0, file ../com mon/libzfs_import.c, line 893, functi
ck153898
parents: 6807
diff changeset
   894
					    &pname) == 0 &&
cbb17a22c911 6712841 nvlist_lookup_string(config, "name", &pname) == 0, file ../com mon/libzfs_import.c, line 893, functi
ck153898
parents: 6807
diff changeset
   895
					    strcmp(poolname, pname) == 0;
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   896
				} else if (guid != 0) {
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   897
					uint64_t this_guid;
7043
22affca31e0f 6719384 nvlist_lookup_uint64(config, "pool_guid", &this_guid) == 0, file ../common/libzfs_import.c,
ck153898
parents: 6957
diff changeset
   898
22affca31e0f 6719384 nvlist_lookup_uint64(config, "pool_guid", &this_guid) == 0, file ../common/libzfs_import.c,
ck153898
parents: 6957
diff changeset
   899
					matched = nvlist_lookup_uint64(config,
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   900
					    ZPOOL_CONFIG_POOL_GUID,
7043
22affca31e0f 6719384 nvlist_lookup_uint64(config, "pool_guid", &this_guid) == 0, file ../common/libzfs_import.c,
ck153898
parents: 6957
diff changeset
   901
					    &this_guid) == 0 &&
22affca31e0f 6719384 nvlist_lookup_uint64(config, "pool_guid", &this_guid) == 0, file ../common/libzfs_import.c,
ck153898
parents: 6957
diff changeset
   902
					    guid == this_guid;
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   903
				}
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   904
				if (!matched) {
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   905
					nvlist_free(config);
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   906
					config = NULL;
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   907
					continue;
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   908
				}
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   909
				/* use the non-raw path for the config */
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   910
				(void) strlcpy(end, name, pathleft);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   911
				if (add_config(hdl, &pools, path, config) != 0)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   912
					goto error;
6376
f31a8151596a 6682366 zpool_find_import() is inefficient.
jwadams
parents: 5994
diff changeset
   913
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   914
		}
4055
9b8dd5af941d 6536445 want ::zio to show zio tree
eschrock
parents: 3975
diff changeset
   915
9b8dd5af941d 6536445 want ::zio to show zio tree
eschrock
parents: 3975
diff changeset
   916
		(void) closedir(dirp);
9b8dd5af941d 6536445 want ::zio to show zio tree
eschrock
parents: 3975
diff changeset
   917
		dirp = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   918
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   919
5994
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   920
	ret = get_configs(hdl, &pools, active_ok);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   921
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   922
error:
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   923
	for (pe = pools.pools; pe != NULL; pe = penext) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   924
		penext = pe->pe_next;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   925
		for (ve = pe->pe_vdevs; ve != NULL; ve = venext) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   926
			venext = ve->ve_next;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   927
			for (ce = ve->ve_configs; ce != NULL; ce = cenext) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   928
				cenext = ce->ce_next;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   929
				if (ce->ce_config)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   930
					nvlist_free(ce->ce_config);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   931
				free(ce);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   932
			}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   933
			free(ve);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   934
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   935
		free(pe);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   936
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   937
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   938
	for (ne = pools.names; ne != NULL; ne = nenext) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   939
		nenext = ne->ne_next;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   940
		if (ne->ne_name)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   941
			free(ne->ne_name);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   942
		free(ne);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   943
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
   944
4055
9b8dd5af941d 6536445 want ::zio to show zio tree
eschrock
parents: 3975
diff changeset
   945
	if (dirp)
9b8dd5af941d 6536445 want ::zio to show zio tree
eschrock
parents: 3975
diff changeset
   946
		(void) closedir(dirp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   947
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   948
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   949
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   950
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   951
nvlist_t *
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   952
zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv)
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   953
{
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   954
	return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, 0));
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   955
}
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   956
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   957
nvlist_t *
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   958
zpool_find_import_byname(libzfs_handle_t *hdl, int argc, char **argv,
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   959
    char *pool)
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   960
{
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   961
	return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, pool, 0));
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   962
}
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   963
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   964
nvlist_t *
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   965
zpool_find_import_byguid(libzfs_handle_t *hdl, int argc, char **argv,
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   966
    uint64_t guid)
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   967
{
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   968
	return (zpool_find_import_impl(hdl, argc, argv, B_FALSE, NULL, guid));
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   969
}
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   970
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   971
nvlist_t *
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   972
zpool_find_import_activeok(libzfs_handle_t *hdl, int argc, char **argv)
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   973
{
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   974
	return (zpool_find_import_impl(hdl, argc, argv, B_TRUE, NULL, 0));
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   975
}
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   976
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   977
/*
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   978
 * Given a cache file, return the contents as a list of importable pools.
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   979
 * poolname or guid (but not both) are provided by the caller when trying
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   980
 * to import a specific pool.
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   981
 */
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   982
nvlist_t *
5994
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
   983
zpool_find_import_cached(libzfs_handle_t *hdl, const char *cachefile,
6957
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
   984
    char *poolname, uint64_t guid)
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   985
{
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   986
	char *buf;
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   987
	int fd;
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   988
	struct stat64 statbuf;
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   989
	nvlist_t *raw, *src, *dst;
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   990
	nvlist_t *pools;
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   991
	nvpair_t *elem;
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   992
	char *name;
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   993
	uint64_t this_guid;
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   994
	boolean_t active;
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   995
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   996
	verify(poolname == NULL || guid == 0);
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
   997
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   998
	if ((fd = open(cachefile, O_RDONLY)) < 0) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
   999
		zfs_error_aux(hdl, "%s", strerror(errno));
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1000
		(void) zfs_error(hdl, EZFS_BADCACHE,
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1001
		    dgettext(TEXT_DOMAIN, "failed to open cache file"));
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1002
		return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1003
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1004
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1005
	if (fstat64(fd, &statbuf) != 0) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1006
		zfs_error_aux(hdl, "%s", strerror(errno));
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1007
		(void) close(fd);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1008
		(void) zfs_error(hdl, EZFS_BADCACHE,
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1009
		    dgettext(TEXT_DOMAIN, "failed to get size of cache file"));
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1010
		return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1011
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1012
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1013
	if ((buf = zfs_alloc(hdl, statbuf.st_size)) == NULL) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1014
		(void) close(fd);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1015
		return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1016
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1017
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1018
	if (read(fd, buf, statbuf.st_size) != statbuf.st_size) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1019
		(void) close(fd);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1020
		free(buf);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1021
		(void) zfs_error(hdl, EZFS_BADCACHE,
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1022
		    dgettext(TEXT_DOMAIN,
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1023
		    "failed to read cache file contents"));
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1024
		return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1025
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1026
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1027
	(void) close(fd);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1028
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1029
	if (nvlist_unpack(buf, statbuf.st_size, &raw, 0) != 0) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1030
		free(buf);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1031
		(void) zfs_error(hdl, EZFS_BADCACHE,
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1032
		    dgettext(TEXT_DOMAIN,
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1033
		    "invalid or corrupt cache file contents"));
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1034
		return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1035
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1036
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1037
	free(buf);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1038
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1039
	/*
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1040
	 * Go through and get the current state of the pools and refresh their
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1041
	 * state.
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1042
	 */
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1043
	if (nvlist_alloc(&pools, 0, 0) != 0) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1044
		(void) no_memory(hdl);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1045
		nvlist_free(raw);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1046
		return (NULL);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1047
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1048
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1049
	elem = NULL;
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1050
	while ((elem = nvlist_next_nvpair(raw, elem)) != NULL) {
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1051
		verify(nvpair_value_nvlist(elem, &src) == 0);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1052
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1053
		verify(nvlist_lookup_string(src, ZPOOL_CONFIG_POOL_NAME,
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1054
		    &name) == 0);
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
  1055
		if (poolname != NULL && strcmp(poolname, name) != 0)
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
  1056
			continue;
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
  1057
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1058
		verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
6807
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
  1059
		    &this_guid) == 0);
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
  1060
		if (guid != 0) {
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
  1061
			verify(nvlist_lookup_uint64(src, ZPOOL_CONFIG_POOL_GUID,
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
  1062
			    &this_guid) == 0);
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
  1063
			if (guid != this_guid)
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
  1064
				continue;
1564ba2e93f5 6689452 zfs often fails to import a zpool if several zfs import commands are running at the same time.
ck153898
parents: 6643
diff changeset
  1065
		}
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1066
6957
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1067
		if (pool_active(hdl, name, this_guid, &active) != 0) {
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1068
			nvlist_free(raw);
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1069
			nvlist_free(pools);
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1070
			return (NULL);
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1071
		}
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1072
6957
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1073
		if (active)
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1074
			continue;
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1075
6957
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1076
		if ((dst = refresh_config(hdl, src)) == NULL) {
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1077
			nvlist_free(raw);
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1078
			nvlist_free(pools);
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1079
			return (NULL);
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1080
		}
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1081
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1082
		if (nvlist_add_nvlist(pools, nvpair_name(elem), dst) != 0) {
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1083
			(void) no_memory(hdl);
5994
bedab011a2e5 6580270 'zdb [-C|-L] <pool'> can't open alternate root pools
ck153898
parents: 5501
diff changeset
  1084
			nvlist_free(dst);
6957
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1085
			nvlist_free(raw);
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1086
			nvlist_free(pools);
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1087
			return (NULL);
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1088
		}
6957
ad855bd47277 6689844 ztest fails with "zdb: can't open ztest: No such device or address"
ck153898
parents: 6895
diff changeset
  1089
		nvlist_free(dst);
5363
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1090
	}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1091
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1092
	nvlist_free(raw);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1093
	return (pools);
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1094
}
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1095
36eeffc5336d PSARC 2007/607 ZFS cachefile property
eschrock
parents: 5094
diff changeset
  1096
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1097
boolean_t
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1098
find_guid(nvlist_t *nv, uint64_t guid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1099
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1100
	uint64_t tmp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1101
	nvlist_t **child;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1102
	uint_t c, children;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1103
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1104
	verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &tmp) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1105
	if (tmp == guid)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1106
		return (B_TRUE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1107
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1108
	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1109
	    &child, &children) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1110
		for (c = 0; c < children; c++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1111
			if (find_guid(child[c], guid))
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1112
				return (B_TRUE);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1113
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1114
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1115
	return (B_FALSE);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1116
}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1117
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1118
typedef struct aux_cbdata {
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1119
	const char	*cb_type;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1120
	uint64_t	cb_guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1121
	zpool_handle_t	*cb_zhp;
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1122
} aux_cbdata_t;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1123
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1124
static int
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1125
find_aux(zpool_handle_t *zhp, void *data)
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1126
{
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1127
	aux_cbdata_t *cbp = data;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1128
	nvlist_t **list;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1129
	uint_t i, count;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1130
	uint64_t guid;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1131
	nvlist_t *nvroot;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1132
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1133
	verify(nvlist_lookup_nvlist(zhp->zpool_config, ZPOOL_CONFIG_VDEV_TREE,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1134
	    &nvroot) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1135
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1136
	if (nvlist_lookup_nvlist_array(nvroot, cbp->cb_type,
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1137
	    &list, &count) == 0) {
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1138
		for (i = 0; i < count; i++) {
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1139
			verify(nvlist_lookup_uint64(list[i],
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1140
			    ZPOOL_CONFIG_GUID, &guid) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1141
			if (guid == cbp->cb_guid) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1142
				cbp->cb_zhp = zhp;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1143
				return (1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1144
			}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1145
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1146
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1147
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1148
	zpool_close(zhp);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1149
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1150
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1151
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1152
/*
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1153
 * Determines if the pool is in use.  If so, it returns true and the state of
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1154
 * the pool as well as the name of the pool.  Both strings are allocated and
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1155
 * must be freed by the caller.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1156
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1157
int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1158
zpool_in_use(libzfs_handle_t *hdl, int fd, pool_state_t *state, char **namestr,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1159
    boolean_t *inuse)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1160
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1161
	nvlist_t *config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1162
	char *name;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1163
	boolean_t ret;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1164
	uint64_t guid, vdev_guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1165
	zpool_handle_t *zhp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1166
	nvlist_t *pool_config;
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1167
	uint64_t stateval, isspare;
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1168
	aux_cbdata_t cb = { 0 };
2142
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
  1169
	boolean_t isactive;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1170
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1171
	*inuse = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1172
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1173
	if (zpool_read_label(fd, &config) != 0) {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1174
		(void) no_memory(hdl);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1175
		return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1176
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1177
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1178
	if (config == NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1179
		return (0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1180
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1181
	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
1352
b7039548de2f 6343802 zpool(1M) should make better use of libdiskmgt
eschrock
parents: 952
diff changeset
  1182
	    &stateval) == 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1183
	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1184
	    &vdev_guid) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1185
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1186
	if (stateval != POOL_STATE_SPARE && stateval != POOL_STATE_L2CACHE) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1187
		verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1188
		    &name) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1189
		verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1190
		    &guid) == 0);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1191
	}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1192
1352
b7039548de2f 6343802 zpool(1M) should make better use of libdiskmgt
eschrock
parents: 952
diff changeset
  1193
	switch (stateval) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1194
	case POOL_STATE_EXPORTED:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1195
		ret = B_TRUE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1196
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1197
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1198
	case POOL_STATE_ACTIVE:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1199
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1200
		 * For an active pool, we have to determine if it's really part
1760
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
  1201
		 * of a currently active pool (in which case the pool will exist
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
  1202
		 * and the guid will be the same), or whether it's part of an
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
  1203
		 * active pool that was disconnected without being explicitly
e1ad2821c30d PSARC 2006/206 zpool upgrade
eschrock
parents: 1631
diff changeset
  1204
		 * exported.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1205
		 */
2142
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
  1206
		if (pool_active(hdl, name, guid, &isactive) != 0) {
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
  1207
			nvlist_free(config);
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
  1208
			return (-1);
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
  1209
		}
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
  1210
f6e0487aa9a3 6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents: 2082
diff changeset
  1211
		if (isactive) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1212
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1213
			 * Because the device may have been removed while
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1214
			 * offlined, we only report it as active if the vdev is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1215
			 * still present in the config.  Otherwise, pretend like
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1216
			 * it's not in use.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1217
			 */
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1218
			if ((zhp = zpool_open_canfail(hdl, name)) != NULL &&
952
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
  1219
			    (pool_config = zpool_get_config(zhp, NULL))
12ec54aa046e 6344502 placeholder bug for the remaining Makefile cleanup work for ZFS
eschrock
parents: 789
diff changeset
  1220
			    != NULL) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1221
				nvlist_t *nvroot;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1222
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1223
				verify(nvlist_lookup_nvlist(pool_config,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1224
				    ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
1352
b7039548de2f 6343802 zpool(1M) should make better use of libdiskmgt
eschrock
parents: 952
diff changeset
  1225
				ret = find_guid(nvroot, vdev_guid);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1226
			} else {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1227
				ret = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1228
			}
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1229
3377
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1230
			/*
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1231
			 * If this is an active spare within another pool, we
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1232
			 * treat it like an unused hot spare.  This allows the
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1233
			 * user to create a pool with a hot spare that currently
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1234
			 * in use within another pool.  Since we return B_TRUE,
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1235
			 * libdiskmgt will continue to prevent generic consumers
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1236
			 * from using the device.
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1237
			 */
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1238
			if (ret && nvlist_lookup_uint64(config,
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1239
			    ZPOOL_CONFIG_IS_SPARE, &isspare) == 0 && isspare)
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1240
				stateval = POOL_STATE_SPARE;
a2fa338530c1 6393525 vdev_reopen() should verify that it's still the same device
eschrock
parents: 3237
diff changeset
  1241
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1242
			if (zhp != NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1243
				zpool_close(zhp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1244
		} else {
1352
b7039548de2f 6343802 zpool(1M) should make better use of libdiskmgt
eschrock
parents: 952
diff changeset
  1245
			stateval = POOL_STATE_POTENTIALLY_ACTIVE;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1246
			ret = B_TRUE;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1247
		}
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1248
		break;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1249
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1250
	case POOL_STATE_SPARE:
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1251
		/*
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1252
		 * For a hot spare, it can be either definitively in use, or
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1253
		 * potentially active.  To determine if it's in use, we iterate
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1254
		 * over all pools in the system and search for one with a spare
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1255
		 * with a matching guid.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1256
		 *
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1257
		 * Due to the shared nature of spares, we don't actually report
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1258
		 * the potentially active case as in use.  This means the user
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1259
		 * can freely create pools on the hot spares of exported pools,
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1260
		 * but to do otherwise makes the resulting code complicated, and
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1261
		 * we end up having to deal with this case anyway.
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1262
		 */
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1263
		cb.cb_zhp = NULL;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1264
		cb.cb_guid = vdev_guid;
5450
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1265
		cb.cb_type = ZPOOL_CONFIG_SPARES;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1266
		if (zpool_iter(hdl, find_aux, &cb) == 1) {
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1267
			name = (char *)zpool_get_name(cb.cb_zhp);
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1268
			ret = TRUE;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1269
		} else {
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1270
			ret = FALSE;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1271
		}
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1272
		break;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1273
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1274
	case POOL_STATE_L2CACHE:
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1275
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1276
		/*
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1277
		 * Check if any pool is currently using this l2cache device.
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1278
		 */
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1279
		cb.cb_zhp = NULL;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1280
		cb.cb_guid = vdev_guid;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1281
		cb.cb_type = ZPOOL_CONFIG_L2CACHE;
b25030891c44 PSARC 2007/618 ZFS L2ARC
brendan
parents: 5363
diff changeset
  1282
		if (zpool_iter(hdl, find_aux, &cb) == 1) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1283
			name = (char *)zpool_get_name(cb.cb_zhp);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1284
			ret = TRUE;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1285
		} else {
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1286
			ret = FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1287
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1288
		break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1289
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1290
	default:
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1291
		ret = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1292
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1293
1352
b7039548de2f 6343802 zpool(1M) should make better use of libdiskmgt
eschrock
parents: 952
diff changeset
  1294
b7039548de2f 6343802 zpool(1M) should make better use of libdiskmgt
eschrock
parents: 952
diff changeset
  1295
	if (ret) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1296
		if ((*namestr = zfs_strdup(hdl, name)) == NULL) {
5501
cca063572f37 6625091 zpool cachefile property has incorrect value help message
eschrock
parents: 5450
diff changeset
  1297
			if (cb.cb_zhp)
cca063572f37 6625091 zpool cachefile property has incorrect value help message
eschrock
parents: 5450
diff changeset
  1298
				zpool_close(cb.cb_zhp);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1299
			nvlist_free(config);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1300
			return (-1);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1301
		}
1352
b7039548de2f 6343802 zpool(1M) should make better use of libdiskmgt
eschrock
parents: 952
diff changeset
  1302
		*state = (pool_state_t)stateval;
b7039548de2f 6343802 zpool(1M) should make better use of libdiskmgt
eschrock
parents: 952
diff changeset
  1303
	}
b7039548de2f 6343802 zpool(1M) should make better use of libdiskmgt
eschrock
parents: 952
diff changeset
  1304
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1305
	if (cb.cb_zhp)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1306
		zpool_close(cb.cb_zhp);
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1307
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1308
	nvlist_free(config);
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1309
	*inuse = ret;
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1760
diff changeset
  1310
	return (0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
  1311
}