6433717 offline devices should not be marked persistently unavailble
authoreschrock
Mon, 12 Jun 2006 08:20:57 -0700
changeset 2174 73de7a781492
parent 2173 ea3cd1374075
child 2175 b0b2f052a486
6433717 offline devices should not be marked persistently unavailble 6436524 importing a bogus pool config can panic system 6436800 ztest failure: spa_vdev_attach() returns EBUSY instead of ENOTSUP
usr/src/cmd/ztest/ztest.c
usr/src/lib/libzfs/common/libzfs_pool.c
usr/src/uts/common/fs/zfs/spa.c
usr/src/uts/common/fs/zfs/spa_misc.c
usr/src/uts/common/fs/zfs/sys/spa_impl.h
usr/src/uts/common/fs/zfs/vdev.c
--- a/usr/src/cmd/ztest/ztest.c	Mon Jun 12 07:52:21 2006 -0700
+++ b/usr/src/cmd/ztest/ztest.c	Mon Jun 12 08:20:57 2006 -0700
@@ -936,12 +936,12 @@
 	 *
 	 * If newvd is too small, it should fail with EOVERFLOW.
 	 */
-	if (pvd->vdev_ops != &vdev_mirror_ops &&
+	if (newvd != NULL)
+		expected_error = EBUSY;
+	else if (pvd->vdev_ops != &vdev_mirror_ops &&
 	    pvd->vdev_ops != &vdev_root_ops &&
 	    (!replacing || pvd->vdev_ops == &vdev_replacing_ops))
 		expected_error = ENOTSUP;
-	else if (newvd != NULL)
-		expected_error = EBUSY;
 	else if (newsize < oldsize)
 		expected_error = EOVERFLOW;
 	else if (ashift > oldvd->vdev_top->vdev_ashift)
--- a/usr/src/lib/libzfs/common/libzfs_pool.c	Mon Jun 12 07:52:21 2006 -0700
+++ b/usr/src/lib/libzfs/common/libzfs_pool.c	Mon Jun 12 08:20:57 2006 -0700
@@ -700,6 +700,10 @@
 			(void) zfs_error(hdl, EZFS_BADVERSION, desc);
 			break;
 
+		case EINVAL:
+			(void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
+			break;
+
 		default:
 			(void) zpool_standard_error(hdl, errno, desc);
 		}
--- a/usr/src/uts/common/fs/zfs/spa.c	Mon Jun 12 07:52:21 2006 -0700
+++ b/usr/src/uts/common/fs/zfs/spa.c	Mon Jun 12 08:20:57 2006 -0700
@@ -414,6 +414,8 @@
 		goto out;
 	}
 
+	spa->spa_load_guid = pool_guid;
+
 	/*
 	 * Parse the configuration into a vdev tree.  We explicitly set the
 	 * value that will be returned by spa_version() since parsing the
--- a/usr/src/uts/common/fs/zfs/spa_misc.c	Mon Jun 12 07:52:21 2006 -0700
+++ b/usr/src/uts/common/fs/zfs/spa_misc.c	Mon Jun 12 08:20:57 2006 -0700
@@ -837,7 +837,16 @@
 uint64_t
 spa_guid(spa_t *spa)
 {
-	return (spa->spa_root_vdev->vdev_guid);
+	/*
+	 * If we fail to parse the config during spa_load(), we can go through
+	 * the error path (which posts an ereport) and end up here with no root
+	 * vdev.  We stash the original pool guid in 'spa_load_guid' to handle
+	 * this case.
+	 */
+	if (spa->spa_root_vdev != NULL)
+		return (spa->spa_root_vdev->vdev_guid);
+	else
+		return (spa->spa_load_guid);
 }
 
 uint64_t
--- a/usr/src/uts/common/fs/zfs/sys/spa_impl.h	Mon Jun 12 07:52:21 2006 -0700
+++ b/usr/src/uts/common/fs/zfs/sys/spa_impl.h	Mon Jun 12 08:20:57 2006 -0700
@@ -82,6 +82,7 @@
 	objset_t	*spa_meta_objset;	/* copy of dp->dp_meta_objset */
 	txg_list_t	spa_vdev_txg_list;	/* per-txg dirty vdev list */
 	vdev_t		*spa_root_vdev;		/* top-level vdev container */
+	uint64_t	spa_load_guid;		/* initial guid for spa_load */
 	list_t		spa_dirty_list;		/* vdevs with dirty labels */
 	uint64_t	spa_spares_object;	/* MOS object for spare list */
 	nvlist_t	*spa_sparelist;		/* cached spare config */
--- a/usr/src/uts/common/fs/zfs/vdev.c	Mon Jun 12 07:52:21 2006 -0700
+++ b/usr/src/uts/common/fs/zfs/vdev.c	Mon Jun 12 08:20:57 2006 -0700
@@ -933,7 +933,12 @@
 		if (vdev_validate(vd->vdev_child[c]) != 0)
 			return (-1);
 
-	if (vd->vdev_ops->vdev_op_leaf) {
+	/*
+	 * If the device has already failed, or was marked offline, don't do
+	 * any further validation.  Otherwise, label I/O will fail and we will
+	 * overwrite the previous state.
+	 */
+	if (vd->vdev_ops->vdev_op_leaf && !vdev_is_dead(vd)) {
 
 		if ((label = vdev_label_read_config(vd)) == NULL) {
 			vdev_set_state(vd, B_TRUE, VDEV_STATE_CANT_OPEN,