Date: Sun, 21 Mar 2010 15:02:47 +0000 (UTC) From: Matt Jacob <mjacob@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r205412 - in head: sbin/geom/class/multipath sys/geom/multipath Message-ID: <201003211502.o2LF2lmq034078@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mjacob Date: Sun Mar 21 15:02:47 2010 New Revision: 205412 URL: http://svn.freebsd.org/changeset/base/205412 Log: Add 'rotate' and 'getactive' verbs to provide some control and information about what the currently active path is. Sponsored by: Panasas MFC after: 1 month Modified: head/sbin/geom/class/multipath/geom_multipath.c head/sys/geom/multipath/g_multipath.c Modified: head/sbin/geom/class/multipath/geom_multipath.c ============================================================================== --- head/sbin/geom/class/multipath/geom_multipath.c Sun Mar 21 15:00:33 2010 (r205411) +++ head/sbin/geom/class/multipath/geom_multipath.c Sun Mar 21 15:02:47 2010 (r205412) @@ -62,6 +62,14 @@ struct g_command class_commands[] = { "clear", G_FLAG_VERBOSE, mp_main, G_NULL_OPTS, NULL, "[-v] prov ..." }, + { + "rotate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS, + NULL, "[-v] prov ..." + }, + { + "getactive", G_FLAG_VERBOSE, NULL, G_NULL_OPTS, + NULL, "[-v] prov ..." + }, G_CMD_SENTINEL }; Modified: head/sys/geom/multipath/g_multipath.c ============================================================================== --- head/sys/geom/multipath/g_multipath.c Sun Mar 21 15:00:33 2010 (r205411) +++ head/sys/geom/multipath/g_multipath.c Sun Mar 21 15:02:47 2010 (r205412) @@ -70,6 +70,8 @@ static int g_multipath_destroy(struct g_ static int g_multipath_destroy_geom(struct gctl_req *, struct g_class *, struct g_geom *); +static int g_multipath_rotate(struct g_geom *); + static g_taste_t g_multipath_taste; static g_ctl_req_t g_multipath_config; static g_init_t g_multipath_init; @@ -406,6 +408,30 @@ g_multipath_destroy_geom(struct gctl_req return (g_multipath_destroy(gp)); } +static int +g_multipath_rotate(struct g_geom *gp) +{ + struct g_consumer *lcp; + struct g_multipath_softc *sc = gp->softc; + + g_topology_assert(); + if (sc == NULL) + return (ENXIO); + LIST_FOREACH(lcp, &gp->consumer, consumer) { + if ((lcp->index & MP_BAD) == 0) { + if (sc->cp_active != lcp) { + break; + } + } + } + if (lcp) { + sc->cp_active = lcp; + printf("GEOM_MULTIPATH: %s now active path in %s\n", + lcp->provider->name, sc->sc_name); + } + return (0); +} + static void g_multipath_init(struct g_class *mp) { @@ -723,6 +749,63 @@ g_multipath_ctl_destroy(struct gctl_req } static void +g_multipath_ctl_rotate(struct gctl_req *req, struct g_class *mp) +{ + struct g_geom *gp; + const char *name; + int error; + + g_topology_assert(); + + name = gctl_get_asciiparam(req, "arg0"); + if (name == NULL) { + gctl_error(req, "No 'arg0' argument"); + return; + } + gp = g_multipath_find_geom(mp, name); + if (gp == NULL) { + gctl_error(req, "Device %s is invalid", name); + return; + } + error = g_multipath_rotate(gp); + if (error != 0) { + gctl_error(req, "failed to rotate %s (err=%d)", name, error); + } +} + +static void +g_multipath_ctl_getactive(struct gctl_req *req, struct g_class *mp) +{ + struct sbuf *sb; + struct g_geom *gp; + struct g_multipath_softc *sc; + const char *name; + + sb = sbuf_new_auto(); + + g_topology_assert(); + name = gctl_get_asciiparam(req, "arg0"); + if (name == NULL) { + gctl_error(req, "No 'arg0' argument"); + return; + } + gp = g_multipath_find_geom(mp, name); + if (gp == NULL) { + gctl_error(req, "Device %s is invalid", name); + return; + } + sc = gp->softc; + if (sc->cp_active) { + sbuf_printf(sb, "%s\n", sc->cp_active->provider->name); + } else { + sbuf_printf(sb, "none\n"); + } + sbuf_finish(sb); + gctl_set_param_err(req, "output", sbuf_data(sb), sbuf_len(sb) + 1); + sbuf_delete(sb); +} + +static void g_multipath_config(struct gctl_req *req, struct g_class *mp, const char *verb) { uint32_t *version; @@ -736,6 +819,10 @@ g_multipath_config(struct gctl_req *req, g_multipath_ctl_create(req, mp); } else if (strcmp(verb, "destroy") == 0) { g_multipath_ctl_destroy(req, mp); + } else if (strcmp(verb, "rotate") == 0) { + g_multipath_ctl_rotate(req, mp); + } else if (strcmp(verb, "getactive") == 0) { + g_multipath_ctl_getactive(req, mp); } else { gctl_error(req, "Unknown verb %s", verb); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003211502.o2LF2lmq034078>