Since we want a vinum geom created anytime the module loads, move

the geom creation to a seperate init function and ignore the tasting.

The config is now parsed only in the vinumdrive geom, which hopefully
fixes the problem, that the drive class tasted before the vinum class
had a chance, for good.

Also restore the behaviour that the module can be loaded at boot time
and on a running system.
This commit is contained in:
Lukas Ertl 2005-11-24 15:11:41 +00:00
parent 4294a24e1b
commit e30534d50b
3 changed files with 28 additions and 137 deletions

View File

@ -119,143 +119,26 @@ gv_access(struct g_provider *pp, int dr, int dw, int de)
return (error);
}
static struct g_geom *
gv_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
static void
gv_init(struct g_class *mp)
{
struct g_geom *gp;
struct g_consumer *cp;
struct gv_softc *sc;
struct gv_hdr *vhdr;
int error, first;
char *buf;
vhdr = NULL;
buf = NULL;
first = 0;
g_trace(G_T_TOPOLOGY, "gv_init(%p)", mp);
g_trace(G_T_TOPOLOGY, "gv_taste(%s, %s)", mp->name, pp->name);
g_topology_assert();
/* Check if we already have a VINUM geom, or create a new one. */
if (LIST_EMPTY(&mp->geom)) {
gp = g_new_geomf(mp, "VINUM");
gp->spoiled = gv_orphan;
gp->orphan = gv_orphan;
gp->access = gv_access;
gp->start = gv_start;
gp->softc = g_malloc(sizeof(struct gv_softc),
M_WAITOK | M_ZERO);
sc = gp->softc;
sc->geom = gp;
LIST_INIT(&sc->drives);
LIST_INIT(&sc->subdisks);
LIST_INIT(&sc->plexes);
LIST_INIT(&sc->volumes);
first++;
} else {
gp = LIST_FIRST(&mp->geom);
sc = gp->softc;
}
/* We need a temporary consumer to read the config from. */
cp = g_new_consumer(gp);
error = g_attach(cp, pp);
if (error) {
g_destroy_consumer(cp);
if (first) {
g_free(sc);
g_destroy_geom(gp);
}
return (NULL);
}
error = g_access(cp, 1, 0, 0);
if (error) {
g_detach(cp);
g_destroy_consumer(cp);
if (first) {
g_free(gp->softc);
g_destroy_geom(gp);
}
return (NULL);
}
g_topology_unlock();
/* Check if the provided slice is a valid vinum drive. */
vhdr = g_read_data(cp, GV_HDR_OFFSET, pp->sectorsize, &error);
if (vhdr == NULL || error != 0) {
g_topology_lock();
g_access(cp, -1, 0, 0);
g_detach(cp);
g_destroy_consumer(cp);
if (first) {
g_free(sc);
g_destroy_geom(gp);
}
return (NULL);
}
/* This provider has no vinum magic on board. */
if (vhdr->magic != GV_MAGIC) {
/* Release the temporary consumer, we don't need it anymore. */
g_topology_lock();
g_access(cp, -1, 0, 0);
g_detach(cp);
g_destroy_consumer(cp);
g_free(vhdr);
/*
* If there is no other VINUM geom yet just take this one; the
* configuration is still empty, but it can be filled by other
* valid vinum drives later.
*/
if (first)
return (gp);
else
return (NULL);
/*
* We have found a valid vinum drive, now read the on-disk
* configuration.
*/
} else {
g_free(vhdr);
buf = g_read_data(cp, GV_CFG_OFFSET, GV_CFG_LEN,
&error);
if (buf == NULL || error != 0) {
g_topology_lock();
g_access(cp, -1, 0, 0);
g_detach(cp);
g_destroy_consumer(cp);
if (first) {
g_free(sc);
g_destroy_geom(gp);
}
return (NULL);
}
/* Release the temporary consumer, we don't need it anymore. */
g_topology_lock();
g_access(cp, -1, 0, 0);
g_detach(cp);
g_destroy_consumer(cp);
/* We are the first VINUM geom. */
if (first) {
gv_parse_config(sc, buf, 0);
g_free(buf);
return (gp);
/* Just merge the configs. */
} else {
gv_parse_config(sc, buf, 1);
g_free(buf);
return (NULL);
}
}
gp = g_new_geomf(mp, "VINUM");
gp->spoiled = gv_orphan;
gp->orphan = gv_orphan;
gp->access = gv_access;
gp->start = gv_start;
gp->softc = g_malloc(sizeof(struct gv_softc), M_WAITOK | M_ZERO);
sc = gp->softc;
sc->geom = gp;
LIST_INIT(&sc->drives);
LIST_INIT(&sc->subdisks);
LIST_INIT(&sc->plexes);
LIST_INIT(&sc->volumes);
}
/* Handle userland requests for creating new objects. */
@ -612,7 +495,7 @@ gv_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp)
static struct g_class g_vinum_class = {
.name = VINUM_CLASS_NAME,
.version = G_VERSION,
.taste = gv_taste,
.init = gv_init,
/*.destroy_geom = gv_destroy_geom,*/
.ctlreq = gv_config,
};

View File

@ -418,7 +418,7 @@ gv_drive_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
struct gv_freelist *fl;
struct gv_hdr *vhdr;
int error;
char errstr[ERRBUFSIZ];
char *buf, errstr[ERRBUFSIZ];
vhdr = NULL;
d = NULL;
@ -460,11 +460,19 @@ gv_drive_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
break;
}
/* A valid vinum drive, let's parse the on-disk information. */
buf = g_read_data(cp, GV_CFG_OFFSET, GV_CFG_LEN, &error);
if (buf == NULL || error != 0) {
g_free(vhdr);
break;
}
g_topology_lock();
gv_parse_config(sc, buf, 1);
g_free(buf);
/*
* We have found a valid vinum drive. Let's see if it is
* already known in the configuration.
* Let's see if this drive is already known in the
* configuration.
*/
d = gv_find_drive(sc, vhdr->label.name);

View File

@ -3,7 +3,7 @@
.PATH: ${.CURDIR}/../../../geom/vinum
KMOD= geom_vinum
SRCS= geom_vinum_drive.c geom_vinum.c geom_vinum_plex.c \
SRCS= geom_vinum.c geom_vinum_drive.c geom_vinum_plex.c \
geom_vinum_volume.c geom_vinum_subr.c geom_vinum_raid5.c \
geom_vinum_share.c geom_vinum_list.c geom_vinum_rm.c \
geom_vinum_init.c geom_vinum_state.c geom_vinum_rename.c \