Index: sbin/gvinum/gvinum.c =================================================================== RCS file: /home/ncvs/src/sbin/gvinum/gvinum.c,v retrieving revision 1.7 diff -u -r1.7 gvinum.c --- sbin/gvinum/gvinum.c 20 Nov 2005 10:35:46 -0000 1.7 +++ sbin/gvinum/gvinum.c 17 Mar 2006 18:01:14 -0000 @@ -62,6 +62,7 @@ void gvinum_printconfig(int, char **); void gvinum_rename(int, char **); void gvinum_rm(int, char **); +void gvinum_resetconfig(void); void gvinum_saveconfig(void); void gvinum_setstate(int, char **); void gvinum_start(int, char **); @@ -349,6 +350,8 @@ " Change the name of the specified object.\n" "rebuildparity plex [-f]\n" " Rebuild the parity blocks of a RAID-5 plex.\n" + "resetconfig\n" + " Reset the complete gvinum configuration\n" "rm [-r] volume | plex | subdisk | drive\n" " Remove an object.\n" "saveconfig\n" @@ -729,6 +732,42 @@ } void +gvinum_resetconfig(void) +{ + struct gctl_req *req; + const char *errstr; + char reply[32]; + + if (!isatty(STDIN_FILENO)) { + warn("Please enter this command from a tty device\n"); + return; + } + printf(" WARNING! This command will completely wipe out your gvinum" + "configuration.\n" + " All data will be lost. If you really want to do this," + " enter the text\n\n" + " NO FUTURE\n" + " Enter text -> "); + fgets(reply, sizeof(reply), stdin); + if (strcmp(reply, "NO FUTURE\n")) { + printf("\n No change\n"); + return; + } + req = gctl_get_handle(); + gctl_ro_param(req, "class", -1, "VINUM"); + gctl_ro_param(req, "verb", -1, "resetconfig"); + errstr = gctl_issue(req); + if (errstr != NULL) { + warnx("can't reset config: %s", errstr); + gctl_free(req); + return; + } + gctl_free(req); + gvinum_list(0, NULL); + printf("gvinum configuration obliterated\n"); +} + +void gvinum_saveconfig(void) { struct gctl_req *req; @@ -848,6 +887,8 @@ gvinum_rename(argc, argv); else if (!strcmp(argv[0], "rm")) gvinum_rm(argc, argv); + else if (!strcmp(argv[0], "resetconfig")) + gvinum_resetconfig(); else if (!strcmp(argv[0], "saveconfig")) gvinum_saveconfig(); else if (!strcmp(argv[0], "setstate")) Index: sys/geom/vinum/geom_vinum.c =================================================================== RCS file: /home/ncvs/src/sys/geom/vinum/geom_vinum.c,v retrieving revision 1.19 diff -u -r1.19 geom_vinum.c --- sys/geom/vinum/geom_vinum.c 24 Nov 2005 15:11:41 -0000 1.19 +++ sys/geom/vinum/geom_vinum.c 17 Mar 2006 18:01:29 -0000 @@ -396,6 +396,9 @@ } else if (!strcmp(verb, "rename")) { gv_rename(gp, req); + + } else if (!strcmp(verb, "resetconfig")) { + gv_resetconfig(gp, req); } else if (!strcmp(verb, "start")) { gv_start_obj(gp, req); Index: sys/geom/vinum/geom_vinum.h =================================================================== RCS file: /home/ncvs/src/sys/geom/vinum/geom_vinum.h,v retrieving revision 1.10 diff -u -r1.10 geom_vinum.h --- sys/geom/vinum/geom_vinum.h 19 Nov 2005 20:25:18 -0000 1.10 +++ sys/geom/vinum/geom_vinum.h 17 Mar 2006 18:01:30 -0000 @@ -57,6 +57,7 @@ /* geom_vinum_rm.c */ void gv_remove(struct g_geom *, struct gctl_req *); +int gv_resetconfig(struct g_geom *, struct gctl_req *); int gv_rm_sd(struct gv_softc *sc, struct gctl_req *req, struct gv_sd *s, int flags); Index: sys/geom/vinum/geom_vinum_rm.c =================================================================== RCS file: /home/ncvs/src/sys/geom/vinum/geom_vinum_rm.c,v retrieving revision 1.9 diff -u -r1.9 geom_vinum_rm.c --- sys/geom/vinum/geom_vinum_rm.c 19 Nov 2005 20:25:18 -0000 1.9 +++ sys/geom/vinum/geom_vinum_rm.c 17 Mar 2006 18:01:30 -0000 @@ -125,6 +125,45 @@ gv_save_config_all(sc); } +/* Resets configuration */ +int +gv_resetconfig(struct g_geom *gp, struct gctl_req *req) +{ + struct gv_softc *sc; + struct gv_drive *d, *d2; + struct gv_volume *v, *v2; + struct gv_plex *p, *p2; + struct gv_sd *s, *s2; + int flags; + + d = NULL; + d2 = NULL; + p = NULL; + p2 = NULL; + s = NULL; + s2 = NULL; + flags = GV_FLAG_R; + sc = gp->softc; + /* First loop through to make sure no volumes are up */ + LIST_FOREACH_SAFE(v, &sc->volumes, volume, v2) { + if (gv_is_open(v->geom)) { + gctl_error(req, "volume '%s' is busy", v->name); + return (-1); + } + } + /* Then if not, we remove everything. */ + LIST_FOREACH_SAFE(v, &sc->volumes, volume, v2) + gv_rm_vol(sc, req, v, flags); + LIST_FOREACH_SAFE(p, &sc->plexes, plex, p2) + gv_rm_plex(sc, req, p, flags); + LIST_FOREACH_SAFE(s, &sc->subdisks, sd, s2) + gv_rm_sd(sc, req, s, flags); + LIST_FOREACH_SAFE(d, &sc->drives, drive, d2) + gv_rm_drive(sc, req, d, flags); + gv_save_config_all(sc); + return (0); +} + /* Remove a volume. */ static int gv_rm_vol(struct gv_softc *sc, struct gctl_req *req, struct gv_volume *v, int flags)