summaryrefslogtreecommitdiffstats
path: root/sys/geom/vinum
diff options
context:
space:
mode:
authorle <le@FreeBSD.org>2005-11-24 15:11:41 +0000
committerle <le@FreeBSD.org>2005-11-24 15:11:41 +0000
commitde257b1b7afafb048a91581cf9ab5afcb9df7886 (patch)
tree2d46cba540adc78be7ef6af27da578c08b78d195 /sys/geom/vinum
parent7e502ce9b38dde38572399757657ecc978992aaa (diff)
downloadFreeBSD-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.
Diffstat (limited to 'sys/geom/vinum')
-rw-r--r--sys/geom/vinum/geom_vinum.c149
-rw-r--r--sys/geom/vinum/geom_vinum_drive.c14
2 files changed, 27 insertions, 136 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);
OpenPOWER on IntegriCloud