From owner-svn-src-head@FreeBSD.ORG Fri Aug 3 14:55:36 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BE69D106566B; Fri, 3 Aug 2012 14:55:36 +0000 (UTC) (envelope-from thomas@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 9EB2E8FC08; Fri, 3 Aug 2012 14:55:36 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q73EtauI035433; Fri, 3 Aug 2012 14:55:36 GMT (envelope-from thomas@svn.freebsd.org) Received: (from thomas@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q73Etast035428; Fri, 3 Aug 2012 14:55:36 GMT (envelope-from thomas@svn.freebsd.org) Message-Id: <201208031455.q73Etast035428@svn.freebsd.org> From: Thomas Quinot Date: Fri, 3 Aug 2012 14:55:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r239012 - in head: sbin/geom/class/multipath sys/geom/multipath X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Aug 2012 14:55:37 -0000 Author: thomas Date: Fri Aug 3 14:55:35 2012 New Revision: 239012 URL: http://svn.freebsd.org/changeset/base/239012 Log: New command "gmultipath prefer" to force selection of a specified provider in an Active/Passive configuration. Reviewed by: mav MFC after: 4 weeks Modified: head/sbin/geom/class/multipath/geom_multipath.c head/sbin/geom/class/multipath/gmultipath.8 head/sys/geom/multipath/g_multipath.c Modified: head/sbin/geom/class/multipath/geom_multipath.c ============================================================================== --- head/sbin/geom/class/multipath/geom_multipath.c Fri Aug 3 14:49:18 2012 (r239011) +++ head/sbin/geom/class/multipath/geom_multipath.c Fri Aug 3 14:55:35 2012 (r239012) @@ -49,6 +49,7 @@ uint32_t version = G_MULTIPATH_VERSION; 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 @@ struct g_command class_commands[] = { "[-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_main(struct gctl_req *req, unsigned i 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); } @@ -294,3 +301,22 @@ mp_clear(struct gctl_req *req) } } +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: head/sbin/geom/class/multipath/gmultipath.8 ============================================================================== --- head/sbin/geom/class/multipath/gmultipath.8 Fri Aug 3 14:49:18 2012 (r239011) +++ head/sbin/geom/class/multipath/gmultipath.8 Fri Aug 3 14:55:35 2012 (r239012) @@ -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 @@ If there are other paths present, new re 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: head/sys/geom/multipath/g_multipath.c ============================================================================== --- head/sys/geom/multipath/g_multipath.c Fri Aug 3 14:49:18 2012 (r239011) +++ head/sys/geom/multipath/g_multipath.c Fri Aug 3 14:55:35 2012 (r239012) @@ -849,6 +849,78 @@ g_multipath_ctl_add_name(struct gctl_req } 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; @@ -1278,6 +1350,8 @@ g_multipath_config(struct gctl_req *req, 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) {