3090 vdev_reopen() during reguid causes vdev to be treated as corrupt
3102 vdev_uberblock_load() and vdev_validate() may read the wrong label

Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Christopher Siden <chris.siden@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Eric Schrock <Eric.Schrock@delphix.com>

References:
  illumos/illumos-gate@dfbb943217
  illumos changeset: 13777:b1e53580146d
  https://www.illumos.org/issues/3090
  https://www.illumos.org/issues/3102

Ported-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #939
This commit is contained in:
George Wilson
2012-12-14 12:38:04 -08:00
committed by Brian Behlendorf
parent 5ac0c30a94
commit 3bc7e0fb0f
9 changed files with 188 additions and 100 deletions
+39 -46
View File
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
/*
@@ -434,8 +434,8 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
uint_t i, nspares, nl2cache;
boolean_t config_seen;
uint64_t best_txg;
char *name, *hostname, *comment;
uint64_t version, guid;
char *name, *hostname = NULL;
uint64_t guid;
uint_t children = 0;
nvlist_t **child = NULL;
uint_t holes;
@@ -521,61 +521,54 @@ get_configs(libzfs_handle_t *hdl, pool_list_t *pl, boolean_t active_ok)
* configuration:
*
* version
* pool guid
* name
* pool guid
* name
* pool txg (if available)
* comment (if available)
* pool state
* pool state
* hostid (if available)
* hostname (if available)
*/
uint64_t state;
uint64_t state, version, pool_txg;
char *comment = NULL;
verify(nvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_VERSION, &version) == 0);
if (nvlist_add_uint64(config,
ZPOOL_CONFIG_VERSION, version) != 0)
goto nomem;
verify(nvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_POOL_GUID, &guid) == 0);
if (nvlist_add_uint64(config,
ZPOOL_CONFIG_POOL_GUID, guid) != 0)
goto nomem;
verify(nvlist_lookup_string(tmp,
ZPOOL_CONFIG_POOL_NAME, &name) == 0);
if (nvlist_add_string(config,
ZPOOL_CONFIG_POOL_NAME, name) != 0)
goto nomem;
version = fnvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_VERSION);
fnvlist_add_uint64(config,
ZPOOL_CONFIG_VERSION, version);
guid = fnvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_POOL_GUID);
fnvlist_add_uint64(config,
ZPOOL_CONFIG_POOL_GUID, guid);
name = fnvlist_lookup_string(tmp,
ZPOOL_CONFIG_POOL_NAME);
fnvlist_add_string(config,
ZPOOL_CONFIG_POOL_NAME, name);
if (nvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_POOL_TXG, &pool_txg) == 0)
fnvlist_add_uint64(config,
ZPOOL_CONFIG_POOL_TXG, pool_txg);
/*
* COMMENT is optional, don't bail if it's not
* there, instead, set it to NULL.
*/
if (nvlist_lookup_string(tmp,
ZPOOL_CONFIG_COMMENT, &comment) != 0)
comment = NULL;
else if (nvlist_add_string(config,
ZPOOL_CONFIG_COMMENT, comment) != 0)
goto nomem;
ZPOOL_CONFIG_COMMENT, &comment) == 0)
fnvlist_add_string(config,
ZPOOL_CONFIG_COMMENT, comment);
verify(nvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_POOL_STATE, &state) == 0);
if (nvlist_add_uint64(config,
ZPOOL_CONFIG_POOL_STATE, state) != 0)
goto nomem;
state = fnvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_POOL_STATE);
fnvlist_add_uint64(config,
ZPOOL_CONFIG_POOL_STATE, state);
hostid = 0;
if (nvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_HOSTID, &hostid) == 0) {
if (nvlist_add_uint64(config,
ZPOOL_CONFIG_HOSTID, hostid) != 0)
goto nomem;
verify(nvlist_lookup_string(tmp,
ZPOOL_CONFIG_HOSTNAME,
&hostname) == 0);
if (nvlist_add_string(config,
ZPOOL_CONFIG_HOSTNAME,
hostname) != 0)
goto nomem;
fnvlist_add_uint64(config,
ZPOOL_CONFIG_HOSTID, hostid);
hostname = fnvlist_lookup_string(tmp,
ZPOOL_CONFIG_HOSTNAME);
fnvlist_add_string(config,
ZPOOL_CONFIG_HOSTNAME, hostname);
}
config_seen = B_TRUE;