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