[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