diff options
author | le <le@FreeBSD.org> | 2005-11-24 15:11:41 +0000 |
---|---|---|
committer | le <le@FreeBSD.org> | 2005-11-24 15:11:41 +0000 |
commit | de257b1b7afafb048a91581cf9ab5afcb9df7886 (patch) | |
tree | 2d46cba540adc78be7ef6af27da578c08b78d195 | |
parent | 7e502ce9b38dde38572399757657ecc978992aaa (diff) | |
download | FreeBSD-src-de257b1b7afafb048a91581cf9ab5afcb9df7886.zip FreeBSD-src-de257b1b7afafb048a91581cf9ab5afcb9df7886.tar.gz |
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.
-rw-r--r-- | sys/geom/vinum/geom_vinum.c | 149 | ||||
-rw-r--r-- | sys/geom/vinum/geom_vinum_drive.c | 14 | ||||
-rw-r--r-- | sys/modules/geom/geom_vinum/Makefile | 2 |
3 files changed, 28 insertions, 137 deletions
diff --git a/sys/geom/vinum/geom_vinum.c b/sys/geom/vinum/geom_vinum.c index 5f115e4..dfb0452 100644 --- a/sys/geom/vinum/geom_vinum.c +++ b/sys/geom/vinum/geom_vinum.c @@ -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_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); + g_trace(G_T_TOPOLOGY, "gv_init(%p)", mp); - /* - * 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, }; diff --git a/sys/geom/vinum/geom_vinum_drive.c b/sys/geom/vinum/geom_vinum_drive.c index 9554a7f..2cdeb08 100644 --- a/sys/geom/vinum/geom_vinum_drive.c +++ b/sys/geom/vinum/geom_vinum_drive.c @@ -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); diff --git a/sys/modules/geom/geom_vinum/Makefile b/sys/modules/geom/geom_vinum/Makefile index 190ba55..fe14515 100644 --- a/sys/modules/geom/geom_vinum/Makefile +++ b/sys/modules/geom/geom_vinum/Makefile @@ -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 \ |