Protect against recursive slices creation in simlar way as it is done

in BSD class, ie. if provider below us uses the same metadata, don't
create slices based on the metadata.
This allows to create slices on geoms with rank != 1 without hacks.

Discussed with:	phk
Approved by:	phk
MFC after:	2 weeks
This commit is contained in:
Pawel Jakub Dawidek 2005-01-20 22:14:05 +00:00
parent ca44231197
commit 857d14cbc9

View File

@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bio.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/md5.h>
#include <sys/diskmbr.h>
#include <sys/sbuf.h>
@ -82,6 +83,7 @@ struct g_mbr_softc {
int type [NDOSPART];
u_int sectorsize;
u_char sec0[512];
u_char slicesum[16];
};
static int
@ -90,6 +92,7 @@ g_mbr_modify(struct g_geom *gp, struct g_mbr_softc *ms, u_char *sec0)
int i, error;
off_t l[NDOSPART];
struct dos_partition ndp[NDOSPART], *dp;
MD5_CTX md5sum;
g_topology_assert();
@ -150,6 +153,15 @@ g_mbr_modify(struct g_geom *gp, struct g_mbr_softc *ms, u_char *sec0)
ms->sectorsize, "%ss%d", gp->name, 1 + i);
}
bcopy(sec0, ms->sec0, 512);
/*
* Calculate MD5 from the first sector and use it for avoiding
* recursive slices creation.
*/
MD5Init(&md5sum);
MD5Update(&md5sum, ms->sec0, sizeof(ms->sec0));
MD5Final(ms->slicesum, &md5sum);
return (0);
}
@ -215,6 +227,9 @@ g_mbr_start(struct bio *bp)
if (g_handleattr_off_t(bp, "MBR::offset",
gsp->slices[idx].offset))
return (1);
if (g_handleattr(bp, "MBR::slicesum", mp->slicesum,
sizeof(mp->slicesum)))
return (1);
}
return (0);
@ -247,6 +262,8 @@ g_mbr_taste(struct g_class *mp, struct g_provider *pp, int insist)
struct g_mbr_softc *ms;
u_int fwsectors, sectorsize;
u_char *buf;
u_char hash[16];
MD5_CTX md5sum;
g_trace(G_T_TOPOLOGY, "mbr_taste(%s,%s)", mp->name, pp->name);
g_topology_assert();
@ -255,13 +272,6 @@ g_mbr_taste(struct g_class *mp, struct g_provider *pp, int insist)
return (NULL);
g_topology_unlock();
do {
/* XXX: phk think about this! */
if (gp->rank != 2 &&
strcmp(pp->geom->class->name, "LABEL") != 0 &&
strcmp(pp->geom->class->name, "MIRROR") != 0 &&
strcmp(pp->geom->class->name, "NOP") != 0) {
break;
}
error = g_getattr("GEOM::fwsectors", cp, &fwsectors);
if (error)
fwsectors = 17;
@ -272,6 +282,22 @@ g_mbr_taste(struct g_class *mp, struct g_provider *pp, int insist)
buf = g_read_data(cp, 0, sectorsize, &error);
if (buf == NULL || error != 0)
break;
/*
* Calculate MD5 from the first sector and use it for avoiding
* recursive slices creation.
*/
bcopy(buf, ms->sec0, 512);
MD5Init(&md5sum);
MD5Update(&md5sum, ms->sec0, sizeof(ms->sec0));
MD5Final(ms->slicesum, &md5sum);
error = g_getattr("MBR::slicesum", cp, &hash);
if (!error && !bcmp(ms->slicesum, hash, sizeof(hash))) {
g_free(buf);
break;
}
g_topology_lock();
g_mbr_modify(gp, ms, buf);
g_topology_unlock();