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