Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Oct 2010 09:26:39 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r214014 - stable/8/sys/boot/zfs
Message-ID:  <201010180926.o9I9QdMm054048@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Mon Oct 18 09:26:39 2010
New Revision: 214014
URL: http://svn.freebsd.org/changeset/base/214014

Log:
  MFC r212382,r212383,r212384,r212387:
  
  r212382:
  
  Remove duplicated code.
  
  r212383:
  
  Allow to boot from a pool within which replacing is in progress.
  Before the change it wasn't possible and the following error was printed:
  
  	ZFS: can only boot from disk, mirror or raidz vdevs
  
  Now if the original vdev (the one we are replacing) is still present we will
  read from it, but if it is not present we won't read from the new vdev, as it
  might not have enough valid data yet.
  
  r212384:
  
  Ignore log vdevs.
  
  r212387:
  
  Remove empty lines committed by accident.

Modified:
  stable/8/sys/boot/zfs/zfsimpl.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/boot/zfs/zfsimpl.c
==============================================================================
--- stable/8/sys/boot/zfs/zfsimpl.c	Mon Oct 18 08:54:33 2010	(r214013)
+++ stable/8/sys/boot/zfs/zfsimpl.c	Mon Oct 18 09:26:39 2010	(r214014)
@@ -376,6 +376,27 @@ vdev_mirror_read(vdev_t *vdev, const blk
 	return (rc);
 }
 
+static int
+vdev_replacing_read(vdev_t *vdev, const blkptr_t *bp, void *buf,
+    off_t offset, size_t bytes)
+{
+	vdev_t *kid;
+
+	/*
+	 * Here we should have two kids:
+	 * First one which is the one we are replacing and we can trust
+	 * only this one to have valid data, but it might not be present.
+	 * Second one is that one we are replacing with. It is most likely
+	 * healthy, but we can't trust it has needed data, so we won't use it.
+	 */
+	kid = STAILQ_FIRST(&vdev->v_children);
+	if (kid == NULL)
+		return (EIO);
+	if (kid->v_state != VDEV_STATE_HEALTHY)
+		return (EIO);
+	return (kid->v_read(kid, bp, buf, offset, bytes));
+}
+
 static vdev_t *
 vdev_find(uint64_t guid)
 {
@@ -416,7 +437,7 @@ vdev_init_from_nvlist(const unsigned cha
 	vdev_t *vdev, *kid;
 	const unsigned char *kids;
 	int nkids, i, is_new;
-	uint64_t is_offline, is_faulted, is_degraded, is_removed;
+	uint64_t is_offline, is_faulted, is_degraded, is_removed, isnt_present;
 
 	if (nvlist_find(nvlist, ZPOOL_CONFIG_GUID,
 			DATA_TYPE_UINT64, 0, &guid)
@@ -430,12 +451,13 @@ vdev_init_from_nvlist(const unsigned cha
 
 	if (strcmp(type, VDEV_TYPE_MIRROR)
 	    && strcmp(type, VDEV_TYPE_DISK)
-	    && strcmp(type, VDEV_TYPE_RAIDZ)) {
+	    && strcmp(type, VDEV_TYPE_RAIDZ)
+	    && strcmp(type, VDEV_TYPE_REPLACING)) {
 		printf("ZFS: can only boot from disk, mirror or raidz vdevs\n");
 		return (EIO);
 	}
 
-	is_offline = is_removed = is_faulted = is_degraded = 0;
+	is_offline = is_removed = is_faulted = is_degraded = isnt_present = 0;
 
 	nvlist_find(nvlist, ZPOOL_CONFIG_OFFLINE, DATA_TYPE_UINT64, 0,
 			&is_offline);
@@ -445,6 +467,8 @@ vdev_init_from_nvlist(const unsigned cha
 			&is_faulted);
 	nvlist_find(nvlist, ZPOOL_CONFIG_DEGRADED, DATA_TYPE_UINT64, 0,
 			&is_degraded);
+	nvlist_find(nvlist, ZPOOL_CONFIG_NOT_PRESENT, DATA_TYPE_UINT64, 0,
+			&isnt_present);
 
 	vdev = vdev_find(guid);
 	if (!vdev) {
@@ -454,6 +478,8 @@ vdev_init_from_nvlist(const unsigned cha
 			vdev = vdev_create(guid, vdev_mirror_read);
 		else if (!strcmp(type, VDEV_TYPE_RAIDZ))
 			vdev = vdev_create(guid, vdev_raidz_read);
+		else if (!strcmp(type, VDEV_TYPE_REPLACING))
+			vdev = vdev_create(guid, vdev_replacing_read);
 		else
 			vdev = vdev_create(guid, vdev_disk_read);
 
@@ -483,7 +509,16 @@ vdev_init_from_nvlist(const unsigned cha
 				vdev->v_name = strdup(type);
 			}
 		}
+	} else {
+		is_new = 0;
+	}
 
+	if (is_new || is_newer) {
+		/*
+		 * This is either new vdev or we've already seen this vdev,
+		 * but from an older vdev label, so let's refresh its state
+		 * from the newer label.
+		 */
 		if (is_offline)
 			vdev->v_state = VDEV_STATE_OFFLINE;
 		else if (is_removed)
@@ -492,28 +527,10 @@ vdev_init_from_nvlist(const unsigned cha
 			vdev->v_state = VDEV_STATE_FAULTED;
 		else if (is_degraded)
 			vdev->v_state = VDEV_STATE_DEGRADED;
+		else if (isnt_present)
+			vdev->v_state = VDEV_STATE_CANT_OPEN;
 		else
 			vdev->v_state = VDEV_STATE_HEALTHY;
-	} else {
-		is_new = 0;
-
-		if (is_newer) {
-			/*
-			 * We've already seen this vdev, but from an older
-			 * vdev label, so let's refresh its state from the
-			 * newer label.
-			 */
-			if (is_offline)
-				vdev->v_state = VDEV_STATE_OFFLINE;
-			else if (is_removed)
-				vdev->v_state = VDEV_STATE_REMOVED;
-			else if (is_faulted)
-				vdev->v_state = VDEV_STATE_FAULTED;
-			else if (is_degraded)
-				vdev->v_state = VDEV_STATE_DEGRADED;
-			else
-				vdev->v_state = VDEV_STATE_HEALTHY;
-		}
 	}
 
 	rc = nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN,
@@ -749,6 +766,7 @@ vdev_probe(vdev_phys_read_t *read, void 
 	uint64_t val;
 	uint64_t guid;
 	uint64_t pool_txg, pool_guid;
+	uint64_t is_log;
 	const char *pool_name;
 	const unsigned char *vdevs;
 	int i, rc, is_newer;
@@ -825,6 +843,12 @@ vdev_probe(vdev_phys_read_t *read, void 
 		return (EIO);
 	}
 
+	is_log = 0;
+	(void) nvlist_find(nvlist, ZPOOL_CONFIG_IS_LOG, DATA_TYPE_UINT64, 0,
+	    &is_log);
+	if (is_log)
+		return (EIO);
+
 	/*
 	 * Create the pool if this is the first time we've seen it.
 	 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201010180926.o9I9QdMm054048>