drivers: hv: kvp: Cleanup the kernel/user protocol
authorK. Y. Srinivasan <kys@microsoft.com>
Fri, 3 Feb 2012 00:56:50 +0000 (16:56 -0800)
committerLeann Ogasawara <leann.ogasawara@canonical.com>
Mon, 2 Apr 2012 20:25:34 +0000 (13:25 -0700)
Now, cleanup the user/kernel KVP protocol by using the same structure
definition that is used for host/guest KVP protocol. This simplifies the code.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 2640335438ca4d7b139e114dae5f0d80e740e106)

Signed-off-by: Andy Whitcroft <apw@canonical.com>

drivers/hv/hv_kvp.c
include/linux/hyperv.h
tools/hv/hv_kvp_daemon.c

index 7495db7..ddfe73e 100644 (file)
@@ -71,15 +71,20 @@ kvp_register(void)
 {
 
        struct cn_msg *msg;
+       struct hv_kvp_msg *kvp_msg;
+       char *version;
 
-       msg = kzalloc(sizeof(*msg) + strlen(HV_DRV_VERSION) + 1 , GFP_ATOMIC);
+       msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg), GFP_ATOMIC);
 
        if (msg) {
+               kvp_msg = (struct hv_kvp_msg *)msg->data;
+               version = kvp_msg->body.kvp_version;
                msg->id.idx =  CN_KVP_IDX;
                msg->id.val = CN_KVP_VAL;
-               msg->seq = KVP_REGISTER;
-               strcpy(msg->data, HV_DRV_VERSION);
-               msg->len = strlen(HV_DRV_VERSION) + 1;
+
+               kvp_msg->kvp_hdr.operation = KVP_OP_REGISTER;
+               strcpy(version, HV_DRV_VERSION);
+               msg->len = sizeof(struct hv_kvp_msg);
                cn_netlink_send(msg, 0, GFP_ATOMIC);
                kfree(msg);
        }
@@ -101,23 +106,24 @@ kvp_work_func(struct work_struct *dummy)
 static void
 kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 {
-       struct hv_ku_msg *message;
+       struct hv_kvp_msg *message;
+       struct hv_kvp_msg_enumerate *data;
 
-       message = (struct hv_ku_msg *)msg->data;
-       if (msg->seq == KVP_REGISTER) {
+       message = (struct hv_kvp_msg *)msg->data;
+       if (message->kvp_hdr.operation == KVP_OP_REGISTER) {
                pr_info("KVP: user-mode registering done.\n");
                kvp_register();
        }
 
-       if (msg->seq == KVP_USER_SET) {
+       if (message->kvp_hdr.operation == KVP_OP_ENUMERATE) {
+               data = &message->body.kvp_enum_data;
                /*
                 * Complete the transaction by forwarding the key value
                 * to the host. But first, cancel the timeout.
                 */
                if (cancel_delayed_work_sync(&kvp_work))
-                       kvp_respond_to_host(message->kvp_key,
-                                               message->kvp_value,
-                                               !strlen(message->kvp_key));
+                       kvp_respond_to_host(data->data.key, data->data.value,
+                                       !strlen(data->data.key));
        }
 }
 
@@ -125,6 +131,7 @@ static void
 kvp_send_key(struct work_struct *dummy)
 {
        struct cn_msg *msg;
+       struct hv_kvp_msg *message;
        int index = kvp_transaction.index;
 
        msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC);
@@ -132,9 +139,11 @@ kvp_send_key(struct work_struct *dummy)
        if (msg) {
                msg->id.idx =  CN_KVP_IDX;
                msg->id.val = CN_KVP_VAL;
-               msg->seq = KVP_KERNEL_GET;
-               ((struct hv_ku_msg *)msg->data)->kvp_index = index;
-               msg->len = sizeof(struct hv_ku_msg);
+
+               message = (struct hv_kvp_msg *)msg->data;
+               message->kvp_hdr.operation = KVP_OP_ENUMERATE;
+               message->body.kvp_enum_data.index = index;
+               msg->len = sizeof(struct hv_kvp_msg);
                cn_netlink_send(msg, 0, GFP_ATOMIC);
                kfree(msg);
        }
@@ -191,7 +200,7 @@ kvp_respond_to_host(char *key, char *value, int error)
        kvp_msg = (struct hv_kvp_msg *)
                        &recv_buffer[sizeof(struct vmbuspipe_hdr) +
                        sizeof(struct icmsg_hdr)];
-       kvp_data = &kvp_msg->kvp_data;
+       kvp_data = &kvp_msg->body.kvp_enum_data;
        key_name = key;
 
        /*
@@ -264,7 +273,7 @@ void hv_kvp_onchannelcallback(void *context)
                                sizeof(struct vmbuspipe_hdr) +
                                sizeof(struct icmsg_hdr)];
 
-                       kvp_data = &kvp_msg->kvp_data;
+                       kvp_data = &kvp_msg->body.kvp_enum_data;
 
                        /*
                         * We only support the "get" operation on
index dd0e3ee..e57a6c6 100644 (file)
  * (not supported), a NULL key string is returned.
  */
 
-/*
- *
- * The following definitions are shared with the user-mode component; do not
- * change any of this without making the corresponding changes in
- * the KVP user-mode component.
- */
-
-enum hv_ku_op {
-       KVP_REGISTER = 0, /* Register the user mode component */
-       KVP_KERNEL_GET, /* Kernel is requesting the value */
-       KVP_KERNEL_SET, /* Kernel is providing the value */
-       KVP_USER_GET,  /* User is requesting the value */
-       KVP_USER_SET  /* User is providing the value */
-};
-
-struct hv_ku_msg {
-       __u32 kvp_index; /* Key index */
-       __u8  kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */
-       __u8  kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key  value */
-};
-
-
-
-
 
 /*
  * Registry value types.
@@ -149,6 +125,7 @@ enum hv_kvp_exchg_op {
        KVP_OP_SET,
        KVP_OP_DELETE,
        KVP_OP_ENUMERATE,
+       KVP_OP_REGISTER,
        KVP_OP_COUNT /* Number of operations, must be last. */
 };
 
@@ -182,7 +159,10 @@ struct hv_kvp_msg_enumerate {
 
 struct hv_kvp_msg {
        struct hv_kvp_hdr       kvp_hdr;
-       struct hv_kvp_msg_enumerate     kvp_data;
+       union {
+               struct hv_kvp_msg_enumerate     kvp_enum_data;
+               char    kvp_version[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
+       } body;
 } __attribute__((packed));
 
 #ifdef __KERNEL__
index b75523c..4ebf703 100644 (file)
@@ -302,7 +302,7 @@ int main(void)
        struct pollfd pfd;
        struct nlmsghdr *incoming_msg;
        struct cn_msg   *incoming_cn_msg;
-       struct hv_ku_msg *hv_msg;
+       struct hv_kvp_msg *hv_msg;
        char    *p;
        char    *key_value;
        char    *key_name;
@@ -340,9 +340,11 @@ int main(void)
        message = (struct cn_msg *)kvp_send_buffer;
        message->id.idx = CN_KVP_IDX;
        message->id.val = CN_KVP_VAL;
-       message->seq = KVP_REGISTER;
+
+       hv_msg = (struct hv_kvp_msg *)message->data;
+       hv_msg->kvp_hdr.operation = KVP_OP_REGISTER;
        message->ack = 0;
-       message->len = 0;
+       message->len = sizeof(struct hv_kvp_msg);
 
        len = netlink_send(fd, message);
        if (len < 0) {
@@ -368,14 +370,15 @@ int main(void)
 
                incoming_msg = (struct nlmsghdr *)kvp_recv_buffer;
                incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
+               hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
 
-               switch (incoming_cn_msg->seq) {
-               case KVP_REGISTER:
+               switch (hv_msg->kvp_hdr.operation) {
+               case KVP_OP_REGISTER:
                        /*
                         * Driver is registering with us; stash away the version
                         * information.
                         */
-                       p = (char *)incoming_cn_msg->data;
+                       p = (char *)hv_msg->body.kvp_version;
                        lic_version = malloc(strlen(p) + 1);
                        if (lic_version) {
                                strcpy(lic_version, p);
@@ -386,17 +389,15 @@ int main(void)
                        }
                        continue;
 
-               case KVP_KERNEL_GET:
-                       break;
                default:
-                       continue;
+                       break;
                }
 
-               hv_msg = (struct hv_ku_msg *)incoming_cn_msg->data;
-               key_name = (char *)hv_msg->kvp_key;
-               key_value = (char *)hv_msg->kvp_value;
+               hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
+               key_name = (char *)hv_msg->body.kvp_enum_data.data.key;
+               key_value = (char *)hv_msg->body.kvp_enum_data.data.value;
 
-               switch (hv_msg->kvp_index) {
+               switch (hv_msg->body.kvp_enum_data.index) {
                case FullyQualifiedDomainName:
                        kvp_get_domain_name(key_value,
                                        HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
@@ -456,9 +457,8 @@ int main(void)
 
                incoming_cn_msg->id.idx = CN_KVP_IDX;
                incoming_cn_msg->id.val = CN_KVP_VAL;
-               incoming_cn_msg->seq = KVP_USER_SET;
                incoming_cn_msg->ack = 0;
-               incoming_cn_msg->len = sizeof(struct hv_ku_msg);
+               incoming_cn_msg->len = sizeof(struct hv_kvp_msg);
 
                len = netlink_send(fd, incoming_cn_msg);
                if (len < 0) {