PERFORCE change 82251 for review
soc-cjones
soc-cjones at FreeBSD.org
Fri Aug 19 06:25:42 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=82251
Change 82251 by soc-cjones at soc-cjones_ishtar on 2005/08/19 06:25:12
Moving subdisks now almost works, but setting the consumer doesn't yet, so all dies when it's time to sync plexes. Sigh.
Affected files ...
.. //depot/projects/soc2005/gvinum/src/sys/geom/vinum/geom_vinum_move.c#10 edit
Differences ...
==== //depot/projects/soc2005/gvinum/src/sys/geom/vinum/geom_vinum_move.c#10 (text+ko) ====
@@ -56,7 +56,7 @@
struct gv_drive *d;
int *argc, *flags;
- char *argv, buf[20];
+ char buf[20];
char *object, *destination;
int i, type, err;
@@ -75,6 +75,7 @@
return;
}
+ printf("gv_move: getting argv[]\n");
for (i = 0; i < *argc; i++) {
snprintf(buf, sizeof(buf), "argv%d", i);
object = gctl_get_param(req, buf, NULL);
@@ -111,9 +112,13 @@
gctl_error(req, "unknown subdisk '%s'", object);
return;
}
+ printf("gv_move: calling gv_move_sd\n");
err = gv_move_sd(sc, req, s, destination, *flags);
- if (err)
+ if (err)
+{
+ printf("gv_move: gv_move_sd returned %d\n", err);
return;
+}
break;
case GV_TYPE_DRIVE:
d = gv_find_drive(sc, object);
@@ -121,8 +126,6 @@
gctl_error(req, "unknown drive '%s'", object);
return;
}
- gctl_error(req, "no touching drives!");
- return 1;
err = gv_move_drive(sc, req, d, destination, *flags);
if (err)
return;
@@ -151,8 +154,6 @@
static int
gv_move_plex(struct gv_softc *sc, struct gctl_req *req, struct gv_plex *p, char *destination, int flags)
{
- int err;
-
g_topology_assert();
KASSERT(p != NULL, ("gv_move_plex: NULL p"));
@@ -162,16 +163,21 @@
/* Move a subdisk. */
static int
-gv_move_sd(struct gv_softc *sc, struct gctl_req *req, struct gv_sd *s, char *destination, int flags)
+gv_move_sd(struct gv_softc *sc, struct gctl_req *req, struct gv_sd *cursd, char *destination, int flags)
{
int err;
struct gv_drive *d;
- struct gv_sd *s2;
+ struct gv_sd *newsd, *s, *s2;
struct gv_plex *p;
+ struct gv_volume *v;
char errstr[ERRBUFSIZ];
+ printf("gv_move_sd: entering\n");
+
g_topology_assert();
- KASSERT(s != NULL, ("gv_move_sd: NULL s"));
+ KASSERT(cursd != NULL, ("gv_move_sd: NULL cursd"));
+
+ printf("gv_move_sd: topology asserted\n");
if (!(flags && GV_FLAG_F)) {
gctl_error(req, "-f flag not passed; move would be destructive");
@@ -184,89 +190,102 @@
return 97;
}
- if (!strncmp(s->drive, d->name, GV_MAXDRIVENAME)) {
- gctl_error(req, "subdisk '%s' already on drive '%s'", s->name, destination);
+ if (!strncmp(cursd->drive, d->name, GV_MAXDRIVENAME)) {
+ gctl_error(req, "subdisk '%s' already on drive '%s'", cursd->name, destination);
return 96;
}
- /* Create new sd, set vital stats, and try allocating space
- on the new drive. Unfortunately, we can't use gv_new_sd,
- since we don't really want to deal with tokenizing stuff.
- Oh well. */
- g_topology_lock();
- s2 = g_malloc(sizeof(*s2), M_WAITOK | M_ZERO);
- snprintf(s2->name, GV_MAXSDNAME, "temp.s0"); /* TODO Come up with temp name. */
- printf("gv_move_sd: B (s2->name = %s)\n", s2->name);
- s2->size = s->size;
- strncpy(s2->drive, d->name, GV_MAXSDNAME);
- /* XXX this breaks allocating the sd to a drive. s2->drive_sc = d; */
- s2->drive_offset = -1;
- s2->plex_offset = -1;
- s2->plex_sc = (struct gv_plex *) NULL;
- s2->state = GV_SD_DOWN;
- s2->vinumconf = sc;
- printf("gv_move_sd: E\n");
- err = gv_sd_to_drive(sc, d, s2, errstr, sizeof(errstr));
+ p = gv_find_plex(sc, cursd->plex);
+ if (NULL == p) {
+ gctl_error(req, "subdisk '%s' is not part of a plex", cursd->name);
+ return 95;
+ }
+
+ /* Stale the old subdisk. */
+ err = gv_set_sd_state(cursd, GV_SD_STALE, GV_SETSTATE_FORCE | GV_SETSTATE_CONFIG);
+ printf("gv_move_sd: staling old sd\n");
if (err) {
- printf("gv_move_sd: F errstr = %s\n", errstr);
- gctl_error(req, errstr);
- g_free(s2);
- g_topology_unlock();
- return err;
+ printf("gv_move_sd: gv_set_sd_state = %d\n", err);
+ return err;
+ }
+
+ /* Create new subdisk. Ideally, we'd use gv_new_sd, but that requires us to
+ create a string for it to parse, which is silly. TODO: maybe refactor
+ gv_new_sd such that this is no longer the case. */
+ newsd = g_malloc(sizeof(struct gv_sd), M_WAITOK | M_ZERO);
+ printf("gv_move_sd: allocated newsd ptr\n");
+ if (!newsd) {
+ printf("gv_move_sd: couldn't allocate memory for new subdisk struct\n");
+ return 95;
+ }
+ newsd->plex_offset = cursd->plex_offset;
+ newsd->size = cursd->size;
+ newsd->drive_offset = -1;
+ strncpy(newsd->name, cursd->name, GV_MAXSDNAME);
+ strncpy(newsd->drive, destination, GV_MAXDRIVENAME);
+ newsd->state = GV_SD_STALE;
+ printf("gv_move_sd: initialized newsd; name='%s', drive='%s', size=%lld, plex_offset=%lld\n", newsd->name, newsd->drive, newsd->size, newsd->plex_offset);
+ err = gv_sd_to_drive(sc, d, newsd, errstr, ERRBUFSIZ);
+ printf("gv_move_sd: allocated newsd to drive, drive_offset=%lld\n", newsd->drive_offset);
+ if (err) { /* XXX not enough free space? */
+ printf("gv_move_sd: gv_sd_to_drive = %d\n", err);
+ gctl_error(req, errstr);
+ g_free(newsd);
+ return err;
+ }
+
+ /* Replace the old sd by the new one. */
+ LIST_FOREACH_SAFE(s, &p->subdisks, in_plex, s2) {
+ printf("gv_move_sd: traversing in_plex list (s: %p, s->name: '%s', s2: %p)\n", s, s->name, s2);
+ printf("gv_move_sd: for sd '%s', consumer = %p\n", s->name, s->consumer);
+ if (s == cursd) {
+ printf("\thit!\n");
+ p->sdcount--;
+ err = gv_rm_sd(sc, req, s, 0);
+ printf("gv_move_sd: removed subdisk\n");
+ if (err) {
+ printf("gv_move_sd: gv_rm_sd = %d\n", err);
+ return err;
+ }
+
+ }
}
- printf("gv_move_sd: G\n");
- s2->flags |= GV_SD_NEWBORN;
- LIST_INSERT_HEAD(&sc->subdisks, s2, sd);
- printf("gv_move_sd: I\n");
+ printf("gv_move_sd: completed traversing in_plex\n");
+ gv_sd_to_plex(p, newsd, 1);
+ newsd->flags |= GV_SD_NEWBORN;
+ printf("gv_move_sd: gave sd to plex, set flags\n");
+ gv_drive_modify(d);
+ printf("gv_move_sd: gv_drive_modify(d)\n");
+ /* XXX - how to get the consumer set? s->consumer = g_new_consumer(p->geom); */
+ printf("gv_move_sd: set s->consumer to %p\n", s->consumer);
+ LIST_INSERT_HEAD(&sc->subdisks, newsd, sd);
+ printf("gv_move_sd: inserted sd into subdisks list\n");
+
+ LIST_FOREACH(s, &sc->subdisks, sd)
+ gv_update_sd_state(s);
+ printf("gv_move_sd: updated subdisk states\n");
+ LIST_FOREACH(p, &sc->plexes, plex)
+ gv_update_plex_config(p);
+ printf("gv_move_sd: updated plex configs\n");
+ LIST_FOREACH(v, &sc->volumes, volume)
+ gv_update_vol_state(v);
+ printf("gv_move_sd: updated volume states\n");
- printf("gv_move_sd: J\n");
gv_save_config_all(sc);
- printf("gv_move_sd: K\n");
- /* TODO -- move data from old sd to new sd. */
+ printf("gv_move_sd: exiting at bottom\n");
- /* TODO -- rename new sd, update plexes, and delete old sd. */
- strncpy(s2->name, s->name, GV_MAXSDNAME);
- strncpy(s2->plex, s->plex, GV_MAXPLEXNAME);
- printf("gv_move_sd: L\n");
- s2->plex_offset = s->plex_offset;
- printf("gv_move_sd: M\n");
- LIST_INSERT_BEFORE(s, s2, in_plex);
- printf("gv_move_sd: M2\n");
- p = gv_find_plex(sc, s2->plex); /* We know it's not null, since the plex exists. */
- p->sdcount--;
- p->state = GV_PLEX_DEGRADED;
- LIST_REMOVE(s, in_plex); /* Get rid of the current sd. */
- s->plex_sc = NULL;
- printf("gv_move_sd: N\n");
- err = gv_rm_sd(sc, req, s, flags);
- printf("gv_move_sd: O, err = %d\n", err);
- if (err) {
- g_topology_unlock();
- return (err);
- }
-
- gv_sd_to_plex(p, s2, 0);
- printf("gv_move_sd: P\n");
- gv_set_sd_state(s2, GV_SD_STALE, GV_SETSTATE_CONFIG);
- printf("gv_move_sd: Q\n");
- gv_save_config_all(sc);
- g_topology_unlock();
- printf("gv_move_sd: done gv_move_sd\n");
- return (0);
+ return 0;
}
/* Move a drive. */
static int
gv_move_drive(struct gv_softc *sc, struct gctl_req *req, struct gv_drive *d, char *destination, int flags)
{
- int err = 0;
-
g_topology_assert();
- KASSERT(d != NULL, ("gv_move_drive: NULL d"));
+ KASSERT(v != NULL, ("gv_move_vol: NULL v"));
- /* TODO find all sds on drive, then move them. */
-
- return (err);
+ gctl_error(req, "moving a volume makes no sense");
+ return 99;
}
More information about the p4-projects
mailing list