[Midnightbsd-cvs] src [8017] trunk: new command gmultipath prefer to force selection of a provider

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Thu Sep 15 05:05:40 EDT 2016


Revision: 8017
          http://svnweb.midnightbsd.org/src/?rev=8017
Author:   laffer1
Date:     2016-09-15 05:05:39 -0400 (Thu, 15 Sep 2016)
Log Message:
-----------
new command gmultipath prefer to force selection of a provider

Modified Paths:
--------------
    trunk/sbin/geom/class/multipath/geom_multipath.c
    trunk/sbin/geom/class/multipath/gmultipath.8
    trunk/sys/geom/multipath/g_multipath.c

Modified: trunk/sbin/geom/class/multipath/geom_multipath.c
===================================================================
--- trunk/sbin/geom/class/multipath/geom_multipath.c	2016-09-15 09:04:42 UTC (rev 8016)
+++ trunk/sbin/geom/class/multipath/geom_multipath.c	2016-09-15 09:05:39 UTC (rev 8017)
@@ -49,6 +49,7 @@
 static void mp_main(struct gctl_req *, unsigned int);
 static void mp_label(struct gctl_req *);
 static void mp_clear(struct gctl_req *);
+static void mp_prefer(struct gctl_req *);
 
 struct g_command class_commands[] = {
 	{
@@ -87,6 +88,10 @@
 		"[-v] name prov"
 	},
 	{
+		"prefer", G_FLAG_VERBOSE, mp_main, G_NULL_OPTS,
+		"[-v] prov ..."
+	},
+	{
 		"fail", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
 		"[-v] name prov"
 	},
@@ -131,6 +136,8 @@
 		mp_label(req);
 	} else if (strcmp(name, "clear") == 0) {
 		mp_clear(req);
+	} else if (strcmp(name, "prefer") == 0) {
+		mp_prefer(req);
 	} else {
 		gctl_error(req, "Unknown command: %s.", name);
 	}
@@ -293,3 +300,22 @@
 	}
 }
 
+static void
+mp_prefer(struct gctl_req *req)
+{
+	const char *name, *comp, *errstr;
+	int nargs;
+
+	nargs = gctl_get_int(req, "nargs");
+	if (nargs != 2) {
+		gctl_error(req, "Usage: prefer GEOM PROVIDER");
+		return;
+	}
+	name = gctl_get_ascii(req, "arg0");
+	comp = gctl_get_ascii(req, "arg1");
+	errstr = gctl_issue (req);
+	if (errstr != NULL) {
+		fprintf(stderr, "Can't set %s preferred provider to %s: %s.\n",
+		    name, comp, errstr);
+	}
+}

Modified: trunk/sbin/geom/class/multipath/gmultipath.8
===================================================================
--- trunk/sbin/geom/class/multipath/gmultipath.8	2016-09-15 09:04:42 UTC (rev 8016)
+++ trunk/sbin/geom/class/multipath/gmultipath.8	2016-09-15 09:05:39 UTC (rev 8017)
@@ -66,6 +66,11 @@
 .Op Fl v
 .Ar name
 .Nm
+.Cm prefer
+.Op Fl v
+.Ar name
+.Ar prov
+.Nm
 .Cm getactive
 .Op Fl v
 .Ar name
@@ -171,7 +176,9 @@
 Mark specified provider as a path of the specified multipath device as
 operational, allowing it to handle requests.
 .It Cm rotate
-Change the active provider/path in Active/Passive mode.
+Change the active provider/path to the next available provider in Active/Passive mode.
+.It Cm prefer
+Change the active provider/path to the specified provider in Active/Passive mode.
 .It Cm getactive
 Get the currently active provider(s)/path(s).
 .It Cm destroy

Modified: trunk/sys/geom/multipath/g_multipath.c
===================================================================
--- trunk/sys/geom/multipath/g_multipath.c	2016-09-15 09:04:42 UTC (rev 8016)
+++ trunk/sys/geom/multipath/g_multipath.c	2016-09-15 09:05:39 UTC (rev 8017)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/multipath/g_multipath.c,v 1.3 2011/12/10 15:46:16 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2011 Alexander Motin <mav at FreeBSD.org>
  * Copyright (c) 2006-2007 Matthew Jacob <mjacob at FreeBSD.org>
@@ -850,6 +850,78 @@
 }
 
 static void
+g_multipath_ctl_prefer(struct gctl_req *req, struct g_class *mp)
+{
+	struct g_geom *gp;
+	struct g_multipath_softc *sc;
+	struct g_consumer *cp;
+	const char *name, *mpname;
+	static const char devpf[6] = "/dev/";
+	int *nargs;
+
+	g_topology_assert();
+
+	mpname = gctl_get_asciiparam(req, "arg0");
+        if (mpname == NULL) {
+                gctl_error(req, "No 'arg0' argument");
+                return;
+        }
+	gp = g_multipath_find_geom(mp, mpname);
+	if (gp == NULL) {
+		gctl_error(req, "Device %s is invalid", mpname);
+		return;
+	}
+	sc = gp->softc;
+
+	nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
+	if (nargs == NULL) {
+		gctl_error(req, "No 'nargs' argument");
+		return;
+	}
+	if (*nargs != 2) {
+		gctl_error(req, "missing device");
+		return;
+	}
+
+	name = gctl_get_asciiparam(req, "arg1");
+	if (name == NULL) {
+		gctl_error(req, "No 'arg1' argument");
+		return;
+	}
+	if (strncmp(name, devpf, 5) == 0) {
+		name += 5;
+	}
+
+	LIST_FOREACH(cp, &gp->consumer, consumer) {
+		if (cp->provider != NULL
+                      && strcmp(cp->provider->name, name) == 0)
+		    break;
+	}
+
+	if (cp == NULL) {
+		gctl_error(req, "Provider %s not found", name);
+		return;
+	}
+
+	mtx_lock(&sc->sc_mtx);
+
+	if (cp->index & MP_BAD) {
+		gctl_error(req, "Consumer %s is invalid", name);
+		mtx_unlock(&sc->sc_mtx);
+		return;
+	}
+
+	/* Here when the consumer is present and in good shape */
+
+	sc->sc_active = cp;
+	if (!sc->sc_active_active)
+	    printf("GEOM_MULTIPATH: %s now active path in %s\n",
+		sc->sc_active->provider->name, sc->sc_name);
+
+	mtx_unlock(&sc->sc_mtx);
+}
+
+static void
 g_multipath_ctl_add(struct gctl_req *req, struct g_class *mp)
 {
 	struct g_multipath_softc *sc;
@@ -1279,6 +1351,8 @@
 		gctl_error(req, "Userland and kernel parts are out of sync");
 	} else if (strcmp(verb, "add") == 0) {
 		g_multipath_ctl_add(req, mp);
+	} else if (strcmp(verb, "prefer") == 0) {
+		g_multipath_ctl_prefer(req, mp);
 	} else if (strcmp(verb, "create") == 0) {
 		g_multipath_ctl_create(req, mp);
 	} else if (strcmp(verb, "configure") == 0) {



More information about the Midnightbsd-cvs mailing list