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