summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2005-04-12 08:14:15 +0000
committerpjd <pjd@FreeBSD.org>2005-04-12 08:14:15 +0000
commitc3333321cc1408dc01b34bbe5e4e00a958bbb90f (patch)
treecf787aa779e121f745f54932f5e942e9c525a2c9
parent8d4424715df1d7399125ea9cbeccfb715f2ab731 (diff)
downloadFreeBSD-src-c3333321cc1408dc01b34bbe5e4e00a958bbb90f.zip
FreeBSD-src-c3333321cc1408dc01b34bbe5e4e00a958bbb90f.tar.gz
Protect against recursive labels creation in simlar way as it is done
in BSD and MBR classes, ie. if provider below us uses the same metadata, don't create labels based on the metadata. This allows to create labels on geoms with rank != 1 without hacks. Tested by: Chris Elsworth <chris@shagged.org> on sparc64 OK'ed by: phk MFC after: 2 weeks
-rw-r--r--sys/geom/geom_sunlabel.c52
1 files changed, 46 insertions, 6 deletions
diff --git a/sys/geom/geom_sunlabel.c b/sys/geom/geom_sunlabel.c
index ece8e1e..4c453cd 100644
--- a/sys/geom/geom_sunlabel.c
+++ b/sys/geom/geom_sunlabel.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/md5.h>
#include <sys/sun_disklabel.h>
#include <geom/geom.h>
#include <geom/geom_slice.h>
@@ -57,6 +58,7 @@ struct g_sunlabel_softc {
int nheads;
int nsects;
int nalt;
+ u_char labelsum[16];
};
static int
@@ -65,6 +67,7 @@ g_sunlabel_modify(struct g_geom *gp, struct g_sunlabel_softc *ms, u_char *sec0)
int i, error;
u_int u, v, csize;
struct sun_disklabel sl;
+ MD5_CTX md5sum;
error = sunlabel_dec(sec0, &sl);
if (error)
@@ -96,6 +99,14 @@ g_sunlabel_modify(struct g_geom *gp, struct g_sunlabel_softc *ms, u_char *sec0)
ms->nheads = sl.sl_ntracks;
ms->nsects = sl.sl_nsectors;
+ /*
+ * Calculate MD5 from the first sector and use it for avoiding
+ * recursive labels creation.
+ */
+ MD5Init(&md5sum);
+ MD5Update(&md5sum, sec0, ms->sectorsize);
+ MD5Final(ms->labelsum, &md5sum);
+
return (0);
}
@@ -224,28 +235,43 @@ g_sunlabel_config(struct gctl_req *req, struct g_class *mp, const char *verb)
}
}
+static int
+g_sunlabel_start(struct bio *bp)
+{
+ struct g_sunlabel_softc *mp;
+ struct g_slicer *gsp;
+
+ gsp = bp->bio_to->geom->softc;
+ mp = gsp->softc;
+ if (bp->bio_cmd == BIO_GETATTR) {
+ if (g_handleattr(bp, "SUN::labelsum", mp->labelsum,
+ sizeof(mp->labelsum)))
+ return (1);
+ }
+ return (0);
+}
+
static struct g_geom *
g_sunlabel_taste(struct g_class *mp, struct g_provider *pp, int flags)
{
struct g_geom *gp;
struct g_consumer *cp;
- int error;
- u_char *buf;
struct g_sunlabel_softc *ms;
struct g_slicer *gsp;
+ u_char *buf, hash[16];
+ MD5_CTX md5sum;
+ int error;
g_trace(G_T_TOPOLOGY, "g_sunlabel_taste(%s,%s)", mp->name, pp->name);
g_topology_assert();
if (flags == G_TF_NORMAL &&
!strcmp(pp->geom->class->name, SUNLABEL_CLASS_NAME))
return (NULL);
- gp = g_slice_new(mp, 8, pp, &cp, &ms, sizeof *ms, NULL);
+ gp = g_slice_new(mp, 8, pp, &cp, &ms, sizeof *ms, g_sunlabel_start);
if (gp == NULL)
return (NULL);
gsp = gp->softc;
do {
- if (gp->rank != 2 && flags == G_TF_NORMAL)
- break;
ms->sectorsize = cp->provider->sectorsize;
if (ms->sectorsize < 512)
break;
@@ -254,7 +280,21 @@ g_sunlabel_taste(struct g_class *mp, struct g_provider *pp, int flags)
g_topology_lock();
if (buf == NULL || error != 0)
break;
-
+
+ /*
+ * Calculate MD5 from the first sector and use it for avoiding
+ * recursive labels creation.
+ */
+ MD5Init(&md5sum);
+ MD5Update(&md5sum, buf, ms->sectorsize);
+ MD5Final(ms->labelsum, &md5sum);
+
+ error = g_getattr("SUN::labelsum", cp, &hash);
+ if (!error && !bcmp(ms->labelsum, hash, sizeof(hash))) {
+ g_free(buf);
+ break;
+ }
+
g_sunlabel_modify(gp, ms, buf);
g_free(buf);
OpenPOWER on IntegriCloud