Print this page
Version bump SVP to 2

@@ -277,23 +277,56 @@
         mutex_exit(&srp->sr_lock);
         svp_remote_release(srp);
 }
 
 /*
- * Walk the list of connections and find the first one that's available, the
- * move it to the back of the list so it's less likely to be used again.
+ * See if the request can be sent over the connection's supported version.
+ * Scribble the version in the request itself.  NOTE that we do not check the
+ * version that already exists in sqp->sq_header.svp_ver, as we may be called
+ * from svp_remote_reassign() (and change versions when arriving at a new
+ * connection).
  */
 static boolean_t
+svp_outbound_version_check(int version, svp_query_t *sqp)
+{
+        uint16_t op = htons(sqp->sq_header.svp_op);
+
+        /*
+         * As of v1 -> v2, we really only need to restrict SVP_R_ROUTE_REQ
+         * as v2-only.  Reflect that here.
+         *
+         * NOTE that if any message semantics change between future versions,
+         * (e.g. "in v3 SVP_R_VL2_REQ takes on additional work"), we'll
+         * need to more-deeply inspect the query.  It's possible that the
+         * svp_op space is big enough to just continue op-only inspections.
+         */
+
+        assert(version > 0 && version <= SVP_CURRENT_VERSION);
+
+        if (op != SVP_R_ROUTE_REQ || version >= SVP_VERSION_TWO) {
+                sqp->sq_header.svp_ver = htons(version);
+                return (B_TRUE);
+        }
+        return (B_FALSE);
+}
+
+/*
+ * Walk the list of connections and find the first one that's available AND
+ * version-appropriate for the message, then move the matched connection to
+ * the back of the list so it's less likely to be used again.
+ */
+static boolean_t
 svp_remote_conn_queue(svp_remote_t *srp, svp_query_t *sqp)
 {
         svp_conn_t *scp;
 
         assert(MUTEX_HELD(&srp->sr_lock));
         for (scp = list_head(&srp->sr_conns); scp != NULL;
             scp = list_next(&srp->sr_conns, scp)) {
                 mutex_enter(&scp->sc_lock);
-                if (scp->sc_cstate != SVP_CS_ACTIVE) {
+                if (scp->sc_cstate != SVP_CS_ACTIVE ||
+                    !svp_outbound_version_check(scp->sc_version, sqp)) {
                         mutex_exit(&scp->sc_lock);
                         continue;
                 }
                 svp_conn_queue(scp, sqp);
                 mutex_exit(&scp->sc_lock);

@@ -329,11 +362,10 @@
         srp = svp->svp_remote;
         sqp->sq_func = svp_remote_vl2_lookup_cb;
         sqp->sq_arg = arg;
         sqp->sq_svp = svp;
         sqp->sq_state = SVP_QUERY_INIT;
-        sqp->sq_header.svp_ver = htons(SVP_CURRENT_VERSION);
         sqp->sq_header.svp_op = htons(SVP_R_VL2_REQ);
         sqp->sq_header.svp_size = htonl(sizeof (svp_vl2_req_t));
         sqp->sq_header.svp_id = id_alloc(svp_idspace);
         if (sqp->sq_header.svp_id == (id_t)-1)
                 libvarpd_panic("failed to allcoate from svp_idspace: %d",

@@ -381,11 +413,10 @@
         srp = svp->svp_remote;
         sqp->sq_func = svp_remote_route_lookup_cb;
         sqp->sq_arg = arg;
         sqp->sq_svp = svp;
         sqp->sq_state = SVP_QUERY_INIT;
-        sqp->sq_header.svp_ver = htons(SVP_CURRENT_VERSION);
         sqp->sq_header.svp_op = htons(SVP_R_ROUTE_REQ);
         sqp->sq_header.svp_size = htonl(sizeof (svp_route_req_t));
         sqp->sq_header.svp_id = id_alloc(svp_idspace);
         if (sqp->sq_header.svp_id == (id_t)-1)
                 libvarpd_panic("failed to allcoate from svp_idspace: %d",

@@ -433,11 +464,10 @@
                 libvarpd_panic("unexpected sa_family for the vl3 lookup");
 
         sqp->sq_func = func;
         sqp->sq_arg = arg;
         sqp->sq_state = SVP_QUERY_INIT;
-        sqp->sq_header.svp_ver = htons(SVP_CURRENT_VERSION);
         sqp->sq_header.svp_op = htons(SVP_R_VL3_REQ);
         sqp->sq_header.svp_size = htonl(sizeof (svp_vl3_req_t));
         sqp->sq_header.svp_id = id_alloc(svp_idspace);
         if (sqp->sq_header.svp_id == (id_t)-1)
                 libvarpd_panic("failed to allcoate from svp_idspace: %d",

@@ -515,11 +545,10 @@
         boolean_t queued;
 
         sqp->sq_func = svp_remote_log_request_cb;
         sqp->sq_state = SVP_QUERY_INIT;
         sqp->sq_arg = srp;
-        sqp->sq_header.svp_ver = htons(SVP_CURRENT_VERSION);
         sqp->sq_header.svp_op = htons(SVP_R_LOG_REQ);
         sqp->sq_header.svp_size = htonl(sizeof (svp_log_req_t));
         sqp->sq_header.svp_id = id_alloc(svp_idspace);
         if (sqp->sq_header.svp_id == (id_t)-1)
                 libvarpd_panic("failed to allcoate from svp_idspace: %d",

@@ -561,11 +590,10 @@
         svp_lrm_req_t *svrr = buf;
 
         sqp->sq_func = svp_remote_lrm_request_cb;
         sqp->sq_state = SVP_QUERY_INIT;
         sqp->sq_arg = srp;
-        sqp->sq_header.svp_ver = htons(SVP_CURRENT_VERSION);
         sqp->sq_header.svp_op = htons(SVP_R_LOG_RM);
         sqp->sq_header.svp_size = htonl(buflen);
         sqp->sq_header.svp_id = id_alloc(svp_idspace);
         if (sqp->sq_header.svp_id == (id_t)-1)
                 libvarpd_panic("failed to allcoate from svp_idspace: %d",