From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756284AbbDKXwR (ORCPT ); Sat, 11 Apr 2015 19:52:17 -0400 Received: from p3plsmtps2ded01.prod.phx3.secureserver.net ([208.109.80.58]:41623 "EHLO p3plsmtps2ded01.prod.phx3.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753345AbbDKXuD (ORCPT ); Sat, 11 Apr 2015 19:50:03 -0400 x-originating-ip: 72.167.245.219 From: "K. Y. Srinivasan" To: gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, devel@linuxdriverproject.org, olaf@aepfle.de, apw@canonical.com, vkuznets@redhat.com, jasowang@redhat.com Cc: "K. Y. Srinivasan" Subject: [PATCH 19/21] Drivers: hv: vss: full handshake support Date: Sat, 11 Apr 2015 18:07:57 -0700 Message-Id: <1428800879-25816-19-git-send-email-kys@microsoft.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1428800879-25816-1-git-send-email-kys@microsoft.com> References: <1428800853-25775-1-git-send-email-kys@microsoft.com> <1428800879-25816-1-git-send-email-kys@microsoft.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vitaly Kuznetsov Introduce VSS_OP_REGISTER1 to support kernel replying to the negotiation message with its own version. Signed-off-by: Vitaly Kuznetsov Tested-by: Alex Ng Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv_snapshot.c | 49 ++++++++++++++++++++++++++++++++---------- include/uapi/linux/hyperv.h | 5 ++++ tools/hv/hv_vss_daemon.c | 14 ++++++++++++ 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c index 2c8c246..ee1762b 100644 --- a/drivers/hv/hv_snapshot.c +++ b/drivers/hv/hv_snapshot.c @@ -59,6 +59,11 @@ static struct { static void vss_respond_to_host(int error); +/* + * This state maintains the version number registered by the daemon. + */ +static int dm_reg_value; + static const char vss_devname[] = "vmbus/hv_vss"; static __u8 *recv_buffer; static struct hvutil_transport *hvt; @@ -89,6 +94,29 @@ static void vss_timeout_func(struct work_struct *dummy) hv_vss_onchannelcallback); } +static int vss_handle_handshake(struct hv_vss_msg *vss_msg) +{ + u32 our_ver = VSS_OP_REGISTER1; + + switch (vss_msg->vss_hdr.operation) { + case VSS_OP_REGISTER: + /* Daemon doesn't expect us to reply */ + dm_reg_value = VSS_OP_REGISTER; + break; + case VSS_OP_REGISTER1: + /* Daemon expects us to reply with our own version*/ + if (hvutil_transport_send(hvt, &our_ver, sizeof(our_ver))) + return -EFAULT; + dm_reg_value = VSS_OP_REGISTER1; + break; + default: + return -EINVAL; + } + vss_transaction.state = HVUTIL_READY; + pr_info("VSS daemon registered\n"); + return 0; +} + static int vss_on_msg(void *msg, int len) { struct hv_vss_msg *vss_msg = (struct hv_vss_msg *)msg; @@ -96,18 +124,15 @@ static int vss_on_msg(void *msg, int len) if (len != sizeof(*vss_msg)) return -EINVAL; - /* - * Don't process registration messages if we're in the middle of - * a transaction processing. - */ - if (vss_transaction.state > HVUTIL_READY && - vss_msg->vss_hdr.operation == VSS_OP_REGISTER) - return -EINVAL; - - if (vss_transaction.state == HVUTIL_DEVICE_INIT && - vss_msg->vss_hdr.operation == VSS_OP_REGISTER) { - pr_info("VSS daemon registered\n"); - vss_transaction.state = HVUTIL_READY; + if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER || + vss_msg->vss_hdr.operation == VSS_OP_REGISTER1) { + /* + * Don't process registration messages if we're in the middle + * of a transaction processing. + */ + if (vss_transaction.state > HVUTIL_READY) + return -EINVAL; + return vss_handle_handshake(vss_msg); } else if (vss_transaction.state == HVUTIL_USERSPACE_REQ) { vss_transaction.state = HVUTIL_USERSPACE_RECV; if (cancel_delayed_work_sync(&vss_timeout_work)) { diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h index bb1cb73..66c76df 100644 --- a/include/uapi/linux/hyperv.h +++ b/include/uapi/linux/hyperv.h @@ -45,6 +45,11 @@ #define VSS_OP_REGISTER 128 +/* + Daemon code with full handshake support. + */ +#define VSS_OP_REGISTER1 129 + enum hv_vss_op { VSS_OP_CREATE = 0, VSS_OP_DELETE, diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 36f1821..96234b6 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -148,6 +148,8 @@ int main(int argc, char *argv[]) int op; struct hv_vss_msg vss_msg[1]; int daemonize = 1, long_index = 0, opt; + int in_handshake = 1; + __u32 kernel_modver; static struct option long_options[] = { {"help", no_argument, 0, 'h' }, @@ -211,6 +213,18 @@ int main(int argc, char *argv[]) len = read(vss_fd, vss_msg, sizeof(struct hv_vss_msg)); + if (in_handshake) { + if (len != sizeof(kernel_modver)) { + syslog(LOG_ERR, "invalid version negotiation"); + exit(EXIT_FAILURE); + } + kernel_modver = *(__u32 *)vss_msg; + in_handshake = 0; + syslog(LOG_INFO, "VSS: kernel module version: %d", + kernel_modver); + continue; + } + if (len != sizeof(struct hv_vss_msg)) { syslog(LOG_ERR, "read failed; error:%d %s", errno, strerror(errno)); -- 1.7.4.1