PERFORCE change 123950 for review
Ulf Lilleengen
lulf at FreeBSD.org
Mon Jul 23 11:22:04 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=123950
Change 123950 by lulf at lulf_carrot on 2007/07/23 11:21:38
- Fix removal of drive panic. If a drive is removed when it has attached
subdisks, it will just go into referenced state. When it has no
subdisks, it is removed. The -r flag can be given to remove everything
recursively.
Affected files ...
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.c#29 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.h#22 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_rm.c#9 edit
Differences ...
==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.c#29 (text+ko) ====
@@ -588,7 +588,8 @@
case GV_EVENT_RM_DRIVE:
printf("VINUM: event 'remove drive'\n");
d = ev->arg1;
- gv_rm_drive(sc, d);
+ flags = ev->arg3;
+ gv_rm_drive(sc, d, flags);
/*gv_setup_objects(sc);*/
break;
==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.h#22 (text+ko) ====
@@ -65,7 +65,7 @@
void gv_remove(struct g_geom *, struct gctl_req *);
int gv_resetconfig(struct gv_softc *);
void gv_rm_sd(struct gv_softc *sc, struct gv_sd *s);
-void gv_rm_drive(struct gv_softc *, struct gv_drive *);
+void gv_rm_drive(struct gv_softc *, struct gv_drive *, int);
void gv_rm_plex(struct gv_softc *, struct gv_plex *);
void gv_rm_vol(struct gv_softc *, struct gv_volume *);
==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_rm.c#9 (text+ko) ====
@@ -133,14 +133,14 @@
}
/* A drive with subdisks needs a recursive removal. */
- if (!LIST_EMPTY(&d->subdisks) &&
+/* if (!LIST_EMPTY(&d->subdisks) &&
!(*flags & GV_FLAG_R)) {
gctl_error(req, "drive '%s' still has subdisks"
" - need recursive removal", d->name);
return;
- }
+ }*/
- gv_post_event(sc, GV_EVENT_RM_DRIVE, d, NULL, 0, 0);
+ gv_post_event(sc, GV_EVENT_RM_DRIVE, d, NULL, *flags, 0);
break;
default:
@@ -169,7 +169,7 @@
}
/* Then if not, we remove everything. */
LIST_FOREACH_SAFE(d, &sc->drives, drive, d2)
- gv_rm_drive(sc, d);
+ gv_rm_drive(sc, d, 0);
LIST_FOREACH_SAFE(s, &sc->subdisks, sd, s2)
gv_rm_sd(sc, s);
LIST_FOREACH_SAFE(p, &sc->plexes, plex, p2)
@@ -290,13 +290,14 @@
/* Remove a drive. */
void
-gv_rm_drive(struct gv_softc *sc, struct gv_drive *d)
+gv_rm_drive(struct gv_softc *sc, struct gv_drive *d, int flags)
{
struct g_consumer *cp;
struct gv_freelist *fl, *fl2;
struct gv_plex *p;
struct gv_sd *s, *s2;
struct gv_volume *v;
+ struct gv_drive *d2;
int err;
KASSERT(d != NULL, ("gv_rm_drive: NULL d"));
@@ -329,14 +330,16 @@
}
/* Remove all associated subdisks, plexes, volumes. */
- /* XXX not quite correct */
- if (!LIST_EMPTY(&d->subdisks)) {
- LIST_FOREACH_SAFE(s, &d->subdisks, from_drive, s2) {
- p = s->plex_sc;
- if (p != NULL) {
- v = p->vol_sc;
- if (v != NULL)
- gv_rm_vol(sc, v);
+ /* XXX not quite correct. Perhaps now...? */
+ if (flags & GV_FLAG_R) {
+ if (!LIST_EMPTY(&d->subdisks)) {
+ LIST_FOREACH_SAFE(s, &d->subdisks, from_drive, s2) {
+ p = s->plex_sc;
+ if (p != NULL) {
+ v = p->vol_sc;
+ if (v != NULL)
+ gv_rm_vol(sc, v);
+ }
}
}
}
@@ -346,8 +349,32 @@
LIST_REMOVE(fl, freelist);
g_free(fl);
}
+
LIST_REMOVE(d, drive);
g_free(d->hdr);
+
+ /* Put ourself into referenced state if we have subdisks. */
+ if (d->sdcount > 0) {
+ d->consumer = NULL;
+ d->hdr = NULL;
+ d->flags |= GV_DRIVE_REFERENCED;
+ snprintf(d->device, GV_MAXDRIVENAME, "???");
+ d->size = 0;
+ d->avail = 0;
+ d->freelist_entries = 0;
+ LIST_FOREACH(s, &d->subdisks, from_drive) {
+ s->flags |= GV_SD_TASTED;
+ gv_set_sd_state(s, GV_SD_DOWN, GV_SETSTATE_FORCE);
+ }
+ /* Shuffle around so we keep gv_is_newer happy. */
+ LIST_REMOVE(d, drive);
+ d2 = LIST_FIRST(&sc->drives);
+ if (d2 == NULL)
+ LIST_INSERT_HEAD(&sc->drives, d, drive);
+ else
+ LIST_INSERT_AFTER(d2, d, drive);
+ return;
+ }
g_free(d);
gv_save_config(sc);
More information about the p4-projects
mailing list