Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Nov 2010 03:59:55 +0000 (UTC)
From:      Matt Jacob <mjacob@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r215932 - stable/8/sys/geom/multipath
Message-ID:  <201011270359.oAR3xtSj011363@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjacob
Date: Sat Nov 27 03:59:55 2010
New Revision: 215932
URL: http://svn.freebsd.org/changeset/base/215932

Log:
  This is an MFC of 205847
  Change how multipath labels are created and managed. This makes it easier
  to support various storage boxes which really aren't active-active.
  
  We only write the label on the *first* provider. For all other providers
  we just "add" the disk. This also allows for an "add" verb.
  
  A usage implication is that you should specificy the currently active
  storage path as the first provider.
  
  Note that this does not add RDAC-like functionality, but better allows for
  autovolumefailover configurations (additional checkins elsewhere will support
  this).

Modified:
  stable/8/sys/geom/multipath/g_multipath.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/geom/multipath/g_multipath.c
==============================================================================
--- stable/8/sys/geom/multipath/g_multipath.c	Sat Nov 27 03:57:18 2010	(r215931)
+++ stable/8/sys/geom/multipath/g_multipath.c	Sat Nov 27 03:59:55 2010	(r215932)
@@ -70,6 +70,7 @@ static int g_multipath_destroy(struct g_
 static int
 g_multipath_destroy_geom(struct gctl_req *, struct g_class *, struct g_geom *);
 
+static struct g_geom *g_multipath_find_geom(struct g_class *, const char *);
 static int g_multipath_rotate(struct g_geom *);
 
 static g_taste_t g_multipath_taste;
@@ -602,14 +603,13 @@ g_multipath_taste(struct g_class *mp, st
 }
 
 static void
-g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp)
+g_multipath_ctl_add(struct gctl_req *req, struct g_class *mp)
 {
 	struct g_geom *gp;
-	struct g_provider *pp0, *pp1;
-	struct g_multipath_metadata md;
-	const char *name, *mpname, *uuid;
+	struct g_consumer *cp;
+	struct g_provider *pp, *pp0;
+	const char *name, *mpname;
 	static const char devpf[6] = "/dev/";
-	int *nargs, error;
 
 	g_topology_assert();
 
@@ -618,14 +618,9 @@ g_multipath_ctl_create(struct gctl_req *
                 gctl_error(req, "No 'arg0' argument");
                 return;
         }
-
-	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
-	if (nargs == NULL) {
-		gctl_error(req, "No 'nargs' argument");
-		return;
-	}
-	if (*nargs != 4) {
-		gctl_error(req, "missing device or uuid arguments");
+	gp = g_multipath_find_geom(mp, mpname);
+	if (gp == NULL) {
+		gctl_error(req, "Device %s is invalid", mpname);
 		return;
 	}
 
@@ -636,78 +631,45 @@ g_multipath_ctl_create(struct gctl_req *
 	}
 	if (strncmp(name, devpf, 5) == 0)
 		name += 5;
-	pp0 = g_provider_by_name(name);
-	if (pp0 == NULL) {
-		gctl_error(req, "Provider %s is invalid", name);
-		return;
-	}
-
-	name = gctl_get_asciiparam(req, "arg2");
-	if (name == NULL) {
-		gctl_error(req, "No 'arg2' argument");
-		return;
-	}
-	if (strncmp(name, devpf, 5) == 0)
-		name += 5;
-	pp1 = g_provider_by_name(name);
-	if (pp1 == NULL) {
+	pp = g_provider_by_name(name);
+	if (pp == NULL) {
 		gctl_error(req, "Provider %s is invalid", name);
 		return;
 	}
 
-	uuid = gctl_get_asciiparam(req, "arg3");
-	if (uuid == NULL) {
-		gctl_error(req, "No uuid argument");
-		return;
-	}
-	if (strlen(uuid) != 36) {
-		gctl_error(req, "Malformed uuid argument");
-		return;
-	}
-
 	/*
-	 * Check to make sure parameters from the two providers are the same
+	 * Check to make sure parameters match, if we already have one.
 	 */
-	if (pp0 == pp1) {
-		gctl_error(req, "providers %s and %s are the same",
-		    pp0->name, pp1->name);
-		return;
-	}
-    	if (pp0->mediasize != pp1->mediasize) {
-		gctl_error(req, "Provider %s is %jd; Provider %s is %jd",
-		    pp0->name, (intmax_t) pp0->mediasize,
-		    pp1->name, (intmax_t) pp1->mediasize);
-		return;
+	cp = LIST_FIRST(&gp->consumer);
+	if (cp) {
+		pp0 = cp->provider;
+	} else {
+		pp0 = NULL;
 	}
-    	if (pp0->sectorsize != pp1->sectorsize) {
-		gctl_error(req, "Provider %s has sectorsize %u; Provider %s "
-		    "has sectorsize %u", pp0->name, pp0->sectorsize,
-		    pp1->name, pp1->sectorsize);
-		return;
+	if (pp0) {
+		if (pp0 == pp) {
+			gctl_error(req, "providers %s and %s are the same",
+			    pp0->name, pp->name);
+			return;
+		}
+		if (pp0->mediasize != pp->mediasize) {
+			gctl_error(req, "Provider %s is %jd; Provider %s is %jd",
+			    pp0->name, (intmax_t) pp0->mediasize,
+			    pp->name, (intmax_t) pp->mediasize);
+			return;
+		}
+		if (pp0->sectorsize != pp->sectorsize) {
+			gctl_error(req, "Provider %s has sectorsize %u; Provider %s "
+			    "has sectorsize %u", pp0->name, pp0->sectorsize,
+			    pp->name, pp->sectorsize);
+			return;
+		}
 	}
 
 	/*
-	 * cons up enough of a metadata structure to use.
+	 * Now add....
 	 */
-	memset(&md, 0, sizeof(md));
-	md.md_size = pp0->mediasize;
-	md.md_sectorsize = pp0->sectorsize;
-	strlcpy(md.md_name, mpname, sizeof(md.md_name));
-	strlcpy(md.md_uuid, uuid, sizeof(md.md_uuid));
-
-	gp = g_multipath_create(mp, &md);
-	if (gp == NULL)
-		return;
-	error = g_multipath_add_disk(gp, pp0);
-	if (error) {
-		g_multipath_destroy(gp);
-		return;
-	}
-	error = g_multipath_add_disk(gp, pp1);
-	if (error) {
-		g_multipath_destroy(gp);
-		return;
-	}
+	(void) g_multipath_add_disk(gp, pp);
 }
 
 static struct g_geom *
@@ -815,8 +777,8 @@ g_multipath_config(struct gctl_req *req,
 		gctl_error(req, "No 'version' argument");
 	} else if (*version != G_MULTIPATH_VERSION) {
 		gctl_error(req, "Userland and kernel parts are out of sync");
-	} else if (strcmp(verb, "create") == 0) {
-		g_multipath_ctl_create(req, mp);
+	} else if (strcmp(verb, "add") == 0) {
+		g_multipath_ctl_add(req, mp);
 	} else if (strcmp(verb, "destroy") == 0) {
 		g_multipath_ctl_destroy(req, mp);
 	} else if (strcmp(verb, "rotate") == 0) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011270359.oAR3xtSj011363>