PERFORCE change 119260 for review

Ulf Lilleengen lulf at FreeBSD.org
Sat May 5 00:11:02 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=119260

Change 119260 by lulf at lulf_carrot on 2007/05/05 00:10:12

	- Add gv_set_plex_state to make it possible to set plex state.
	- Add gv_plexdown to count number of plexes down in a volume.
	- Hook this up in the event system.

Affected files ...

.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.c#6 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.h#5 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_state.c#7 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_subr.c#3 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_var.h#4 edit

Differences ...

==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.c#6 (text+ko) ====

@@ -547,6 +547,19 @@
 				g_free(ev->arg3);
 				break;
 
+			case GV_EVENT_SET_PLEX_STATE:
+				printf("VINUM: event 'setstate plex'\n");
+				p = ev->arg1;
+				newstate = *(int *)ev->arg2;
+				flags = *(int *)ev->arg3;
+				err = gv_set_plex_state(p, newstate, flags);
+				if (err)
+					printf("VINUM: error setting plex "
+					    "state\n");
+				g_free(ev->arg2);
+				g_free(ev->arg3);
+				break;
+
 			case GV_EVENT_THREAD_EXIT:
 				printf("VINUM: event 'thread exit'\n");
 				g_free(ev);

==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum.h#5 (text+ko) ====

@@ -64,6 +64,7 @@
 int	gv_set_drive_state(struct gv_drive *, int, int);
 int	gv_set_sd_state(struct gv_sd *, int, int);
 int	gv_set_vol_state(struct gv_volume *, int, int);
+int	gv_set_plex_state(struct gv_plex *, int, int);
 void	gv_update_sd_state(struct gv_sd *);
 void	gv_update_plex_state(struct gv_plex *);
 void	gv_update_vol_state(struct gv_volume *);
@@ -87,6 +88,7 @@
 void	gv_update_vol_size(struct gv_volume *, off_t);
 off_t	gv_vol_size(struct gv_volume *);
 off_t	gv_plex_size(struct gv_plex *);
+int	gv_plexdown(struct gv_volume *);
 
 void	gv_worker(void *);
 void	gv_post_event(struct gv_softc *, int, void *, void *, void *);

==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_state.c#7 (text+ko) ====

@@ -44,6 +44,7 @@
 	struct gv_sd *s;
 	struct gv_drive *d;
 	struct gv_volume *v;
+	struct gv_plex *p;
 	char *obj, *state;
 	int f, *flags, *newstatep, *flagp, type;
 
@@ -79,6 +80,7 @@
 		}
 		v = gv_find_vol(sc, obj);
 
+		/* XXX: Should try to avoid malloc. */
 		newstatep = g_malloc(sizeof(int), M_WAITOK | M_ZERO);
 		*newstatep = gv_volstatei(state);
 		flagp = g_malloc(sizeof(int), M_WAITOK | M_ZERO);
@@ -87,7 +89,18 @@
 		break;
 
 	case GV_TYPE_PLEX:
-		gctl_error(req, "plex state cannot be set currently");
+		if (gv_plexstatei(state) < 0) {
+			gctl_error(req, "invalid plex state '%s'", state);
+			break;
+		}
+		p = gv_find_plex(sc, obj);
+
+		/* XXX: Should try to avoid malloc. */
+		newstatep = g_malloc(sizeof(int), M_WAITOK | M_ZERO);
+		*newstatep = gv_sdstatei(state);
+		flagp = g_malloc(sizeof(int), M_WAITOK | M_ZERO);
+		*flagp = f;
+		gv_post_event(sc, GV_EVENT_SET_PLEX_STATE, p, newstatep, flagp);
 		break;
 
 	case GV_TYPE_SD:
@@ -277,6 +290,56 @@
 }
 
 int
+gv_set_plex_state(struct gv_plex *p, int newstate, int flags)
+{
+	struct gv_volume *v;
+	int oldstate, plexdown;
+
+	KASSERT(p != NULL, ("gv_set_plex_state: NULL p"));
+
+	oldstate = p->state;
+	v = p->vol_sc;
+	plexdown = 0;
+
+	if (newstate == oldstate)
+		return (0);
+
+	switch (newstate) {
+	case GV_PLEX_UP:
+		/* Let update_plex handle if the plex can come up */
+		gv_update_plex_state(p);
+		if (p->state != GV_PLEX_UP && !(flags & GV_SETSTATE_FORCE))
+			return (-1); /* XXX: ERROR CODES. */
+		p->state = newstate;
+		break;
+	case GV_PLEX_DOWN:
+		/*
+		 * Set state to GV_PLEX_DOWN only if no-one is using the plex,
+		 * or if the state is forced.
+		 */
+		if (v != NULL) {
+			/* If the only one up, force is needed. */
+			plexdown = gv_plexdown(v);
+			if ((v->plexcount == 1 ||
+			    (v->plexcount - plexdown == 1)) &&
+			    ((flags & GV_SETSTATE_FORCE) == 0))
+				return (-1); /* XXX: ERROR CODES. */
+		}
+		p->state = newstate;
+		break;
+	}
+
+	/* Update our volume if we have one. */
+	if (v != NULL)
+		gv_update_vol_state(v);
+
+	/* Save config. */
+	if (flags & GV_SETSTATE_CONFIG)
+		gv_save_config(p->vinumconf);
+	return (0);
+}
+
+int
 gv_set_vol_state(struct gv_volume *v, int newstate, int flags)
 {
 	int oldstate;
@@ -298,7 +361,7 @@
 		break;
 	case GV_VOL_DOWN:
 		/*
-		 * Set state to GV_VOL_DOWN only if noone is using the volume,
+		 * Set state to GV_VOL_DOWN only if no-one is using the volume,
 		 * or if the state should be forced.
 		 */
 		if (!gv_provider_is_open(v->provider) &&

==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_subr.c#3 (text+ko) ====

@@ -245,6 +245,24 @@
 	return (smallest);
 }
 
+/* Walk over plexes in a volume and count how many are down. */
+int
+gv_plexdown(struct gv_volume *v)
+{
+	int plexdown;
+	struct gv_plex *p;
+
+	KASSERT(v != NULL, ("gv_plexdown: NULL v"));
+
+	plexdown = 0;
+
+	LIST_FOREACH(p, &v->plexes, plex) {
+		if (p->state == GV_PLEX_DOWN)
+			plexdown++;
+	}
+	return (plexdown);
+}
+
 int
 gv_sd_to_plex(struct gv_sd *s, struct gv_plex *p)
 {

==== //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_var.h#4 (text+ko) ====

@@ -175,6 +175,7 @@
 #define GV_EVENT_SET_SD_STATE		13
 #define GV_EVENT_SET_DRIVE_STATE	14
 #define GV_EVENT_SET_VOL_STATE		15
+#define GV_EVENT_SET_PLEX_STATE		16
 
 struct gv_event {
 	int	type;


More information about the p4-projects mailing list