changeset 13992:313c3db67359

3639 zpool.cache should skip over readonly pools 3640 want automatic devid updates Reviewed by: Eric Schrock <eric.schrock@delphix.com> Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: Basil Crow <basil.crow@delphix.com> Approved by: Gordon Ross <gwr@nexenta.com>
author George Wilson <george.wilson@delphix.com>
date Sun, 24 Mar 2013 15:59:22 -0800
parents 53e4f9da98a1
children 6d652ac77401
files usr/src/uts/common/fs/zfs/spa_config.c usr/src/uts/common/fs/zfs/vdev_disk.c
diffstat 2 files changed, 35 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/spa_config.c	Sun Mar 24 13:24:51 2013 -0800
+++ b/usr/src/uts/common/fs/zfs/spa_config.c	Sun Mar 24 15:59:22 2013 -0800
@@ -222,7 +222,15 @@
 		 */
 		nvl = NULL;
 		while ((spa = spa_next(spa)) != NULL) {
-			if (spa == target && removing)
+			/*
+			 * Skip over our own pool if we're about to remove
+			 * ourselves from the spa namespace or any pool that
+			 * is readonly. Since we cannot guarantee that a
+			 * readonly pool would successfully import upon reboot,
+			 * we don't allow them to be written to the cache file.
+			 */
+			if ((spa == target && removing) ||
+			    !spa_writeable(spa))
 				continue;
 
 			mutex_enter(&spa->spa_props_lock);
--- a/usr/src/uts/common/fs/zfs/vdev_disk.c	Sun Mar 24 13:24:51 2013 -0800
+++ b/usr/src/uts/common/fs/zfs/vdev_disk.c	Sun Mar 24 15:59:22 2013 -0800
@@ -139,6 +139,8 @@
 	int error;
 	dev_t dev;
 	int otyp;
+	boolean_t validate_devid = B_FALSE;
+	ddi_devid_t devid;
 
 	/*
 	 * We must have a pathname, and it must be absolute.
@@ -187,7 +189,6 @@
 	error = EINVAL;		/* presume failure */
 
 	if (vd->vdev_path != NULL) {
-		ddi_devid_t devid;
 
 		if (vd->vdev_wholedisk == -1ULL) {
 			size_t len = strlen(vd->vdev_path) + 3;
@@ -236,9 +237,10 @@
 	 * If we were unable to open by path, or the devid check fails, open by
 	 * devid instead.
 	 */
-	if (error != 0 && vd->vdev_devid != NULL)
+	if (error != 0 && vd->vdev_devid != NULL) {
 		error = ldi_open_by_devid(dvd->vd_devid, dvd->vd_minor,
 		    spa_mode(spa), kcred, &dvd->vd_lh, zfs_li);
+	}
 
 	/*
 	 * If all else fails, then try opening by physical path (if available)
@@ -247,6 +249,9 @@
 	 * level vdev validation will prevent us from opening the wrong device.
 	 */
 	if (error) {
+		if (vd->vdev_devid != NULL)
+			validate_devid = B_TRUE;
+
 		if (vd->vdev_physpath != NULL &&
 		    (dev = ddi_pathname_to_dev_t(vd->vdev_physpath)) != NODEV)
 			error = ldi_open_by_dev(&dev, OTYP_BLK, spa_mode(spa),
@@ -268,6 +273,25 @@
 	}
 
 	/*
+	 * Now that the device has been successfully opened, update the devid
+	 * if necessary.
+	 */
+	if (validate_devid && spa_writeable(spa) &&
+	    ldi_get_devid(dvd->vd_lh, &devid) == 0) {
+		if (ddi_devid_compare(devid, dvd->vd_devid) != 0) {
+			char *vd_devid;
+
+			vd_devid = ddi_devid_str_encode(devid, dvd->vd_minor);
+			zfs_dbgmsg("vdev %s: update devid from %s, "
+			    "to %s", vd->vdev_path, vd->vdev_devid, vd_devid);
+			spa_strfree(vd->vdev_devid);
+			vd->vdev_devid = spa_strdup(vd_devid);
+			ddi_devid_str_free(vd_devid);
+		}
+		ddi_devid_free(devid);
+	}
+
+	/*
 	 * Once a device is opened, verify that the physical device path (if
 	 * available) is up to date.
 	 */