From owner-svn-src-projects@FreeBSD.ORG Tue Aug 16 19:46:13 2011 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 746AC106564A; Tue, 16 Aug 2011 19:46:13 +0000 (UTC) (envelope-from gibbs@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 62DFB8FC14; Tue, 16 Aug 2011 19:46:13 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p7GJkDLo070849; Tue, 16 Aug 2011 19:46:13 GMT (envelope-from gibbs@svn.freebsd.org) Received: (from gibbs@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p7GJkDBu070847; Tue, 16 Aug 2011 19:46:13 GMT (envelope-from gibbs@svn.freebsd.org) Message-Id: <201108161946.p7GJkDBu070847@svn.freebsd.org> From: "Justin T. Gibbs" Date: Tue, 16 Aug 2011 19:46:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r224913 - projects/zfsd/head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Aug 2011 19:46:13 -0000 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); } }