PERFORCE change 124188 for review

Ulf Lilleengen lulf at FreeBSD.org
Fri Jul 27 15:05:34 UTC 2007


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

Change 124188 by lulf at lulf_carrot on 2007/07/27 15:05:25

	- Prevent from getting a bogus sd name that crashes vinum when not
	  specified in config. Generate a new name if not given.
	- Remove checking of sdnum  (sdname.plexnum.sdnum) to be the same in
	  rename...  it shouldn't have to be the same.
	- Modify gv_plex_smallest sd to not take initial arg but look for it in
	  the plex itself.
	- Modify the remainder check code in gv_sd_to_plex to make sure all
	  subdisks are the same size in striped plexes (stripe and raid5).
	  Reduce size of other subdisks (only when newborn plex) or the subdisk
	  that is added. Prevents possibility of getting unequal subdisk-sizes
	  as well as giving space that is not needed back to the drive. 
	- Remove old debug printfs.

Affected files ...

.. //depot/projects/soc2007/lulf/gvinum_fixup/sbin/gvinum/gvinum.c#13 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_rename.c#3 edit
.. //depot/projects/soc2007/lulf/gvinum_fixup/sys/geom/vinum/geom_vinum_subr.c#21 edit

Differences ...

==== //depot/projects/soc2007/lulf/gvinum_fixup/sbin/gvinum/gvinum.c#13 (text+ko) ====

@@ -170,9 +170,9 @@
 	struct gv_volume *v;
 	FILE *tmp;
 	int drives, errors, fd, line, plexes, plex_in_volume;
-	int sd_in_plex, status, subdisks, tokens, volumes;
+	int sd_in_plex, status, subdisks, tokens, undeffd, volumes;
 	const char *errstr;
-	char buf[BUFSIZ], buf1[BUFSIZ], commandline[BUFSIZ], *ed;
+	char buf[BUFSIZ], buf1[BUFSIZ], commandline[BUFSIZ], *ed, *sdname;
 	char original[BUFSIZ], tmpfile[20], *token[GV_MAXARGS];
 	char plex[GV_MAXPLEXNAME], volume[GV_MAXVOLNAME];
 
@@ -218,7 +218,8 @@
 	gctl_ro_param(req, "verb", -1, "create");
 
 	drives = volumes = plexes = subdisks = 0;
-	plex_in_volume = sd_in_plex = 0;
+	plex_in_volume = sd_in_plex = undeffd = 0;
+	plex[0] = '\0';
 	errors = 0;
 	line = 1;
 	while ((fgets(buf, BUFSIZ, tmp)) != NULL) {
@@ -319,8 +320,16 @@
 
 			/* Default name. */
 			if (strlen(s->name) == 0) {
-				snprintf(s->name, GV_MAXSDNAME, "%s.s%d",
-				    plex, sd_in_plex++);
+				if (strlen(plex) == 0) {
+					sdname = find_name("gvinumsubdisk.p",
+					    GV_TYPE_SD, GV_MAXSDNAME);
+					snprintf(s->name, GV_MAXSDNAME,
+					    "%s.s%d", sdname, undeffd++);
+					free(sdname);
+				} else {
+					snprintf(s->name, GV_MAXSDNAME,
+					    "%s.s%d",plex, sd_in_plex++);
+				}
 			}
 
 			/* Default plex. */

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

@@ -273,12 +273,13 @@
 		err = GV_ERR_INVNAME;
 		goto fail;
 	}
-	if (strcmp(newp, oldp)) {
+	/* XXX: Uhm, why is this important?. */
+/*	if (strcmp(newp, oldp)) {
 		printf("VINUM: current and proposed sd numbers (%s, %s) do "
 		    "not match\n", oldp, newp);
 		err = GV_ERR_INVNAME;
 		goto fail;
-	}
+	}*/
 
 	strncpy(s->name, newname, GV_MAXSDNAME);
 

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

@@ -56,7 +56,7 @@
 #include <geom/vinum/geom_vinum_share.h>
 
 int	gv_drive_is_newer(struct gv_softc *);
-static off_t gv_plex_smallest_sd(struct gv_plex *, off_t);
+static off_t gv_plex_smallest_sd(struct gv_plex *);
 
 void
 gv_parse_config(struct gv_softc *sc, char *buf)
@@ -232,12 +232,17 @@
 }
 
 static off_t
-gv_plex_smallest_sd(struct gv_plex *p, off_t smallest)
+gv_plex_smallest_sd(struct gv_plex *p)
 {
 	struct gv_sd *s;
+	off_t smallest;
 
 	KASSERT(p != NULL, ("gv_plex_smallest_sd: NULL p"));
 
+	s = LIST_FIRST(&p->subdisks);
+	if (s == NULL)
+		return (-1);
+	smallest = s->size;
 	LIST_FOREACH(s, &p->subdisks, in_plex) {
 		if (s->size < smallest)
 			smallest = s->size;
@@ -267,7 +272,7 @@
 gv_sd_to_plex(struct gv_sd *s, struct gv_plex *p)
 {
 	struct gv_sd *s2;
-	off_t psizeorig, remainder;
+	off_t psizeorig, remainder, smallest;
 
 	/* If this subdisk was already given to this plex, do nothing. */
 	if (s->plex_sc == p)
@@ -277,7 +282,9 @@
 	s2 = LIST_FIRST(&p->subdisks);
 	/* Adjust the subdisk-size if necessary. */
 	if (s2 != NULL && gv_is_striped(p)) {
+		/* First adjust to the stripesize. */
 		remainder = s->size % p->stripesize;
+
 		if (remainder) {
 			printf("VINUM: size of sd %s is not a "
 			    "multiple of plex stripesize, taking off "
@@ -285,6 +292,35 @@
 			    (intmax_t)remainder);
 			gv_adjust_freespace(s, remainder);
 		}
+
+		smallest = gv_plex_smallest_sd(p);
+		/* Then take off extra if other subdisks are smaller. */
+		remainder = s->size - smallest;
+
+		/*
+		 * Don't allow a remainder below zero for running plexes, it's too
+		 * painful, and if someone were to accidentally do this, the
+		 * resulting array might be smaller than the original... not god 
+		 */
+		if (remainder < 0) {
+			if (!(p->flags & GV_PLEX_NEWBORN)) {
+				printf("VINUM: sd %s too small for plex %s!\n",
+				    s->name, p->name);
+				return (GV_ERR_BADSIZE);
+			}
+			/* Adjust other subdisks. */
+			LIST_FOREACH(s2, &p->subdisks, in_plex) {
+				printf("VINUM: size of sd %s is to big, "
+				    "taking off %jd bytes\n", s->name,
+				    (intmax_t)remainder);
+				gv_adjust_freespace(s2, (remainder * -1));
+			}
+		} else if (remainder > 0) {
+			printf("VINUM: size of sd %s is to big, "
+			    "taking off %jd bytes\n", s->name,
+			    (intmax_t)remainder);
+			gv_adjust_freespace(s, remainder);
+		}
 	}
 
 	/* Find the correct plex offset for this subdisk, if needed. */
@@ -338,8 +374,6 @@
 		if ((p->org == GV_PLEX_RAID5 ||
 		    p->org == GV_PLEX_STRIPED) &&
 		    !(p->flags & GV_PLEX_NEWBORN)) {
-			printf("Adding to a running plex, must add grow-flag to"
-			    " sd and plex\n");
 			s->flags |= GV_SD_GROW;
 		}
 		p->sdcount++;
@@ -485,7 +519,6 @@
 	} else {
 		LIST_FOREACH(s, &p->subdisks, in_plex) {
 			if (s->flags & GV_SD_GROW) {
-				printf("Setting state\n");
 				gv_set_plex_state(p, GV_PLEX_DEGRADED,
 				    GV_SETSTATE_FORCE);
 				break;


More information about the p4-projects mailing list