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",