Index: geom_vinum.c =================================================================== RCS file: /home/ncvs/src/sys/geom/vinum/geom_vinum.c,v retrieving revision 1.21 diff -u -r1.21 geom_vinum.c --- geom_vinum.c 30 Mar 2006 14:01:25 -0000 1.21 +++ geom_vinum.c 24 May 2006 15:08:43 -0000 @@ -411,6 +411,9 @@ gctl_set_param(req, "config", sbuf_data(sb), sbuf_len(sb) + 1); sbuf_delete(sb); + } else if (!strcmp(verb, "dumpconfig")) { + gv_dump_config(sc, req); + } else if (!strcmp(verb, "create")) { gv_create(gp, req); Index: geom_vinum_drive.c =================================================================== RCS file: /home/ncvs/src/sys/geom/vinum/geom_vinum_drive.c,v retrieving revision 1.25 diff -u -r1.25 geom_vinum_drive.c --- geom_vinum_drive.c 6 Jan 2006 18:03:17 -0000 1.25 +++ geom_vinum_drive.c 24 May 2006 15:08:43 -0000 @@ -98,6 +98,48 @@ } } +/* Read the vinum configuration from disk */ +void +gv_read_config(struct gv_drive *d, struct sbuf *sb) +{ + struct gv_plex *p; + struct gv_sd *s; + struct gv_volume *v; + struct gv_softc *vinumconf; + + KASSERT(d != NULL, ("gv_read_config: null d")); + vinumconf = d->vinumconf; + sbuf_printf(sb, "Drive %s:\tDevice /dev/%s\n", d->name, d->device); + label = &d->hdr->label; + sbuf_printf(sb, "\t\t\tCreated on %d\n", label.date_of_birth.tv_sec); + sbuf_printf(sb, "\t\t\tSize:\t %jd bytes (%jd MB)\n", (intmax_t)d->size, + (intmax_t)d->size / MEGABYTE); + LIST_FOREACH(v, &vinumconf->volumes, volume) + sbuf_printf(sb, "volume %s state %s\n", v->name, + gv_volstate(v->state)); + LIST_FOREACH(p, &vinumconf->plexes, plex) { + sbuf_printf(sb, "plex %s org %s ", p->name, + gv_plexorg(p->org)); + if (gv_is_striped(p)) + sbuf_printf(sb, "%ds", p->stripesize / 512); + if (p->vol_sc != NULL) + sbuf_printf(sb, " vol %s", p->volume); + sbuf_printf(sb, " state %s\n", gv_plexstate(p->state)); + } + LIST_FOREACH(s, &vinumconf->subdisks, sd) { + sbuf_printf(sb, "sd name %s drive %s len %jds " + "driveoffset %jds state %s", s->name, s->drive, + s->size / 512, s->drive_offset / 512, + gv_sdstate(s->state)); + if (s->plex_sc != NULL) + sbuf_printf(sb, " plex %s plexoffset %jds", + s->plex, s->plex_offset / 512); + sbuf_printf(sb, "\n"); + } + sbuf_printf(sb, "\nDrive /dev/%s: %jd MB (%jd bytes)\n", d->device, + (intmax_t)d->size / MEGABYTE, (intmax_t)d->size); +} + /* Save the vinum configuration back to disk. */ void gv_save_config(struct g_consumer *cp, struct gv_drive *d, struct gv_softc *sc) Index: geom_vinum_subr.c =================================================================== RCS file: /home/ncvs/src/sys/geom/vinum/geom_vinum_subr.c,v retrieving revision 1.15 diff -u -r1.15 geom_vinum_subr.c --- geom_vinum_subr.c 30 Mar 2006 14:01:25 -0000 1.15 +++ geom_vinum_subr.c 24 May 2006 15:08:43 -0000 @@ -169,6 +169,62 @@ } } +/* Get configuration from all disks */ +void +gv_dump_config(struct gv_softc *sc, struct gctl_req *req) +{ + struct gv_drive *d; + struct sbuf *sb; + int *argc, drives, i, type; + char *object, buf[30]; + + drives = 0; + i = 0; + argc = gctl_get_paraml(req, "argc", sizeof(*argc)); + if (argc == NULL) { + gctl_error(req, "No argument given"); + return; + } + + if (*argc > 1) { + /* Only if argument is specified */ + sb = sbuf_new(NULL, NULL, GV_CFG_LEN * (*argc), SBUF_FIXEDLEN); + for (i = 0; i < *argc; i++) { + snprintf(buf, sizeof(buf), "argv%d", i); + object = gctl_get_param(req, buf, NULL); + if (object == NULL) + continue; + type = gv_object_type(sc, object); + if (type == GV_TYPE_DRIVE) { + d = gv_find_drive(sc, object); + gv_read_config(d, sb); + } else { + LIST_FOREACH(d, &sc->drives, drive) { + snprintf(buf, sizeof(buf), "/dev/%s", d->device); + if (!strcmp(d->device, object) || + !strcmp(buf, object)) { + gv_read_config(d, sb); + } + } + } + } + } else { + /* + * First count number of drives, then allocate enough space for + * them. + */ + LIST_FOREACH(d, &sc->drives, drive) + drives++; + sb = sbuf_new(NULL, NULL, GV_CFG_LEN * drives, SBUF_FIXEDLEN); + LIST_FOREACH(d, &sc->drives, drive) { + gv_read_config(d, sb); + } + } + sbuf_finish(sb); + gctl_set_param(req, "config", sbuf_data(sb), sbuf_len(sb) + 1); + sbuf_delete(sb); +} + /* * Format the vinum configuration properly. If ondisk is non-zero then the * configuration is intended to be written to disk later. Index: geom_vinum_var.h =================================================================== RCS file: /home/ncvs/src/sys/geom/vinum/geom_vinum_var.h,v retrieving revision 1.11 diff -u -r1.11 geom_vinum_var.h --- geom_vinum_var.h 6 Jan 2006 18:03:17 -0000 1.11 +++ geom_vinum_var.h 24 May 2006 15:08:43 -0000 @@ -169,6 +169,7 @@ LIST_HEAD(,gv_plex) plexes; /* All plexes. */ LIST_HEAD(,gv_sd) subdisks; /* All subdisks. */ LIST_HEAD(,gv_volume) volumes; /* All volumes. */ + LIST_HEAD(,gv_group) groups; struct g_geom *geom; /* Pointer to our VINUM geom. */ }; @@ -329,4 +330,32 @@ struct gv_softc *vinumconf; /* Pointer to the vinum config. */ }; +/* softc for a group */ +struct gv_group { + char name[GV_MAXGROUPNAME]; /* The name of the group. */ + off_t size; /* The size of the group. */ + int volcount; /* The number of volumes. */ + int state; /* The state of the group. */ +#define GV_GROUP_DOWN 0 +#define GV_GROUP_UP 1 + + int flags; +#define GV_GROUP_THREAD_ACTIVE 0x01 /* Group has an active thread. */ +#define GV_GROUP_THREAD_DIE 0x02 /* Signal the thread to die. */ +#define GV_GROUP_THREAD_DEAD 0x04 /* The thread has died. */ + + struct mtx bqeue_mtx; /* Lock for the BIO queue. */ +#ifdef _KERNEL + struct bio_queue_head *bqueue; /* BIO queue. */ +#else + char *padding; +#endif + + LIST_HEAD(,gv_volume) volumes; /* List of attached volumes. */ + LIST_ENTRY(gv_group) group; /* Entry in vinum config. */ + + struct g_geom *geom; /* The geom of this group. */ + struct gv_softc *vinumconf; /* Pointer to the vinum config. */ +}; + #endif /* !_GEOM_VINUM_VAR_H */