svn commit: r224913 -
projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Justin T. Gibbs
gibbs at FreeBSD.org
Tue Aug 16 19:46:13 UTC 2011
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);
}
}
More information about the svn-src-projects
mailing list