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);
        }
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to