Date: Fri, 19 Aug 2005 06:25:40 GMT From: soc-cjones <soc-cjones@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82251 for review Message-ID: <200508190625.j7J6PeUt008037@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82251 Change 82251 by soc-cjones@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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508190625.j7J6PeUt008037>