Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Aug 2011 19:46:13 +0000 (UTC)
From:      "Justin T. Gibbs" <gibbs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r224913 - projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201108161946.p7GJkDBu070847@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gibbs
Date: Tue Aug 16 19:46:13 2011
New Revision: 224913
URL: http://svn.freebsd.org/changeset/base/224913

Log:
  sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c:
  	When attaching to a vdev by GUIDs, verify both the pool and
  	vdev GUIDS instead of just the vdev GUID.
  
  Sponsored by:	 Spectra Logic Corporation

Modified:
  projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c

Modified: projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
==============================================================================
--- projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Tue Aug 16 14:25:41 2011	(r224912)
+++ projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Tue Aug 16 19:46:13 2011	(r224913)
@@ -170,20 +170,26 @@ vdev_geom_detach(void *arg, int flag __u
 	}
 }
 
-static uint64_t
-nvlist_get_guid(nvlist_t *list)
+static void
+nvlist_get_guids(nvlist_t *list, uint64_t *pguid, uint64_t *vguid)
 {
 	nvpair_t *elem = NULL;
-	uint64_t value;
 
+	*vguid = 0;
+	*pguid = 0;
 	while ((elem = nvlist_next_nvpair(list, elem)) != NULL) {
-		if (nvpair_type(elem) == DATA_TYPE_UINT64 &&
-		    strcmp(nvpair_name(elem), "guid") == 0) {
-			VERIFY(nvpair_value_uint64(elem, &value) == 0);
-			return (value);
+		if (nvpair_type(elem) != DATA_TYPE_UINT64)
+			continue;
+
+		if (strcmp(nvpair_name(elem), ZPOOL_CONFIG_POOL_GUID) == 0) {
+			VERIFY(nvpair_value_uint64(elem, pguid) == 0);
+		} else if (strcmp(nvpair_name(elem), ZPOOL_CONFIG_GUID) == 0) {
+			VERIFY(nvpair_value_uint64(elem, vguid) == 0);
 		}
+
+		if (*pguid != 0 && *vguid != 0)
+			break;
 	}
-	return (0);
 }
 
 static int
@@ -221,8 +227,8 @@ vdev_geom_io(struct g_consumer *cp, int 
 	return (error);
 }
 
-static uint64_t
-vdev_geom_read_guid(struct g_consumer *cp)
+static void
+vdev_geom_read_guids(struct g_consumer *cp, uint64_t *pguid, uint64_t *vguid)
 {
 	struct g_provider *pp;
 	vdev_label_t *label;
@@ -230,13 +236,14 @@ vdev_geom_read_guid(struct g_consumer *c
 	size_t buflen;
 	uint64_t psize;
 	off_t offset, size;
-	uint64_t guid;
 	int error, l, len;
 
 	g_topology_assert_not();
 
+	*pguid = 0;
+	*vguid = 0;
 	pp = cp->provider;
-	ZFS_LOG(1, "Reading guid from %s...", pp->name);
+	ZFS_LOG(1, "Reading guids from %s...", pp->name);
 
 	psize = pp->mediasize;
 	psize = P2ALIGN(psize, (uint64_t)sizeof(vdev_label_t));
@@ -244,7 +251,6 @@ vdev_geom_read_guid(struct g_consumer *c
 	size = sizeof(*label) + pp->sectorsize -
 	    ((sizeof(*label) - 1) % pp->sectorsize) - 1;
 
-	guid = 0;
 	label = kmem_alloc(size, KM_SLEEP);
 	buflen = sizeof(label->vl_vdev_phys.vp_nvlist);
 
@@ -262,16 +268,16 @@ vdev_geom_read_guid(struct g_consumer *c
 		if (nvlist_unpack(buf, buflen, &config, 0) != 0)
 			continue;
 
-		guid = nvlist_get_guid(config);
+		nvlist_get_guids(config, pguid, vguid);
 		nvlist_free(config);
-		if (guid != 0)
+		if (*pguid != 0 && *vguid != 0)
 			break;
 	}
 
 	kmem_free(label, size);
-	if (guid != 0)
-		ZFS_LOG(1, "guid for %s is %ju", pp->name, (uintmax_t)guid);
-	return (guid);
+	if (*pguid != 0 && *vguid != 0)
+		ZFS_LOG(1, "guids for %s are %ju:%ju", pp->name,
+		    (uintmax_t)*pguid, (uintmax_t)*vguid);
 }
 
 static void
@@ -283,13 +289,14 @@ vdev_geom_taste_orphan(struct g_consumer
 }
 
 static struct g_consumer *
-vdev_geom_attach_by_guid(uint64_t guid)
+vdev_geom_attach_by_guids(vdev_t *vd)
 {
 	struct g_class *mp;
 	struct g_geom *gp, *zgp;
 	struct g_provider *pp;
 	struct g_consumer *cp, *zcp;
 	uint64_t pguid;
+	uint64_t vguid;
 
 	g_topology_assert();
 
@@ -314,11 +321,12 @@ vdev_geom_attach_by_guid(uint64_t guid)
 					continue;
 				}
 				g_topology_unlock();
-				pguid = vdev_geom_read_guid(zcp);
+				vdev_geom_read_guids(zcp, &pguid, &vguid);
 				g_topology_lock();
 				g_access(zcp, -1, 0, 0);
 				g_detach(zcp);
-				if (pguid != guid)
+				if (pguid != spa_guid(vd->vdev_spa) ||
+				    vguid != vd->vdev_guid)
 					continue;
 				cp = vdev_geom_attach(pp);
 				if (cp == NULL) {
@@ -341,7 +349,7 @@ end:
 }
 
 static struct g_consumer *
-vdev_geom_open_by_guid(vdev_t *vd)
+vdev_geom_open_by_guids(vdev_t *vd)
 {
 	struct g_consumer *cp;
 	char *buf;
@@ -349,8 +357,9 @@ vdev_geom_open_by_guid(vdev_t *vd)
 
 	g_topology_assert();
 
-	ZFS_LOG(1, "Searching by guid [%ju].", (uintmax_t)vd->vdev_guid);
-	cp = vdev_geom_attach_by_guid(vd->vdev_guid);
+	ZFS_LOG(1, "Searching by guids [%ju:%ju].",
+	    (uintmax_t)spa_guid(vd->vdev_spa), (uintmax_t)vd->vdev_guid);
+	cp = vdev_geom_attach_by_guids(vd);
 	if (cp != NULL) {
 		len = strlen(cp->provider->name) + strlen("/dev/") + 1;
 		buf = kmem_alloc(len, KM_SLEEP);
@@ -359,10 +368,12 @@ vdev_geom_open_by_guid(vdev_t *vd)
 		spa_strfree(vd->vdev_path);
 		vd->vdev_path = buf;
 
-		ZFS_LOG(1, "Attach by guid [%ju] succeeded, provider %s.",
+		ZFS_LOG(1, "Attach by guids [%ju:%ju] succeeded, provider %s.",
+		    (uintmax_t)spa_guid(vd->vdev_spa),
 		    (uintmax_t)vd->vdev_guid, vd->vdev_path);
 	} else {
-		ZFS_LOG(1, "Search by guid [%ju] failed.",
+		ZFS_LOG(1, "Search by guids [%ju:%ju] failed.",
+		    (uintmax_t)spa_guid(vd->vdev_spa),
 		    (uintmax_t)vd->vdev_guid);
 	}
 
@@ -374,7 +385,8 @@ vdev_geom_open_by_path(vdev_t *vd, int c
 {
 	struct g_provider *pp;
 	struct g_consumer *cp;
-	uint64_t guid;
+	uint64_t pguid;
+	uint64_t vguid;
 
 	g_topology_assert();
 
@@ -386,16 +398,19 @@ vdev_geom_open_by_path(vdev_t *vd, int c
 		if (cp != NULL && check_guid && ISP2(pp->sectorsize) &&
 		    pp->sectorsize <= VDEV_PAD_SIZE) {
 			g_topology_unlock();
-			guid = vdev_geom_read_guid(cp);
+			vdev_geom_read_guids(cp, &pguid, &vguid);
 			g_topology_lock();
-			if (guid != vd->vdev_guid) {
+			if (pguid != spa_guid(vd->vdev_spa) ||
+			    vguid != vd->vdev_guid) {
 				vdev_geom_detach(cp, 0);
 				cp = NULL;
 				ZFS_LOG(1, "guid mismatch for provider %s: "
-				    "%ju != %ju.", vd->vdev_path,
-				    (uintmax_t)vd->vdev_guid, (uintmax_t)guid);
+				    "%ju:%ju != %ju:%ju.", vd->vdev_path,
+				    (uintmax_t)spa_guid(vd->vdev_spa),
+				    (uintmax_t)vd->vdev_guid,
+				    (uintmax_t)pguid, (uintmax_t)vguid);
 			} else {
-				ZFS_LOG(1, "guid match for provider %s.",
+				ZFS_LOG(1, "guids match for provider %s.",
 				    vd->vdev_path);
 			}
 		}
@@ -442,7 +457,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psi
 			 * moved around so try all other GEOM providers
 			 * to find one with the right guid.
 			 */
-			cp = vdev_geom_open_by_guid(vd);
+			cp = vdev_geom_open_by_guids(vd);
 		}
 	}
 



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