diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2012-02-02 19:56:50 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-02-09 11:32:44 -0500 |
commit | 2640335438ca4d7b139e114dae5f0d80e740e106 (patch) | |
tree | 0e254e2147dedefe04e385d0c97a9fbc15df2a23 | |
parent | eab6af71f0b83a7f62b9c48be5b2c0a82a86fad3 (diff) |
drivers: hv: kvp: Cleanup the kernel/user protocol
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>
-rw-r--r-- | drivers/hv/hv_kvp.c | 41 | ||||
-rw-r--r-- | include/linux/hyperv.h | 30 | ||||
-rw-r--r-- | tools/hv/hv_kvp_daemon.c | 30 |
3 files changed, 45 insertions, 56 deletions
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 4a6971e13539..0ef4c1f6ca54 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c | |||
@@ -71,15 +71,20 @@ kvp_register(void) | |||
71 | { | 71 | { |
72 | 72 | ||
73 | struct cn_msg *msg; | 73 | struct cn_msg *msg; |
74 | struct hv_kvp_msg *kvp_msg; | ||
75 | char *version; | ||
74 | 76 | ||
75 | msg = kzalloc(sizeof(*msg) + strlen(HV_DRV_VERSION) + 1 , GFP_ATOMIC); | 77 | msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg), GFP_ATOMIC); |
76 | 78 | ||
77 | if (msg) { | 79 | if (msg) { |
80 | kvp_msg = (struct hv_kvp_msg *)msg->data; | ||
81 | version = kvp_msg->body.kvp_version; | ||
78 | msg->id.idx = CN_KVP_IDX; | 82 | msg->id.idx = CN_KVP_IDX; |
79 | msg->id.val = CN_KVP_VAL; | 83 | msg->id.val = CN_KVP_VAL; |
80 | msg->seq = KVP_REGISTER; | 84 | |
81 | strcpy(msg->data, HV_DRV_VERSION); | 85 | kvp_msg->kvp_hdr.operation = KVP_OP_REGISTER; |
82 | msg->len = strlen(HV_DRV_VERSION) + 1; | 86 | strcpy(version, HV_DRV_VERSION); |
87 | msg->len = sizeof(struct hv_kvp_msg); | ||
83 | cn_netlink_send(msg, 0, GFP_ATOMIC); | 88 | cn_netlink_send(msg, 0, GFP_ATOMIC); |
84 | kfree(msg); | 89 | kfree(msg); |
85 | } | 90 | } |
@@ -101,23 +106,24 @@ kvp_work_func(struct work_struct *dummy) | |||
101 | static void | 106 | static void |
102 | kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) | 107 | kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) |
103 | { | 108 | { |
104 | struct hv_ku_msg *message; | 109 | struct hv_kvp_msg *message; |
110 | struct hv_kvp_msg_enumerate *data; | ||
105 | 111 | ||
106 | message = (struct hv_ku_msg *)msg->data; | 112 | message = (struct hv_kvp_msg *)msg->data; |
107 | if (msg->seq == KVP_REGISTER) { | 113 | if (message->kvp_hdr.operation == KVP_OP_REGISTER) { |
108 | pr_info("KVP: user-mode registering done.\n"); | 114 | pr_info("KVP: user-mode registering done.\n"); |
109 | kvp_register(); | 115 | kvp_register(); |
110 | } | 116 | } |
111 | 117 | ||
112 | if (msg->seq == KVP_USER_SET) { | 118 | if (message->kvp_hdr.operation == KVP_OP_ENUMERATE) { |
119 | data = &message->body.kvp_enum_data; | ||
113 | /* | 120 | /* |
114 | * Complete the transaction by forwarding the key value | 121 | * Complete the transaction by forwarding the key value |
115 | * to the host. But first, cancel the timeout. | 122 | * to the host. But first, cancel the timeout. |
116 | */ | 123 | */ |
117 | if (cancel_delayed_work_sync(&kvp_work)) | 124 | if (cancel_delayed_work_sync(&kvp_work)) |
118 | kvp_respond_to_host(message->kvp_key, | 125 | kvp_respond_to_host(data->data.key, data->data.value, |
119 | message->kvp_value, | 126 | !strlen(data->data.key)); |
120 | !strlen(message->kvp_key)); | ||
121 | } | 127 | } |
122 | } | 128 | } |
123 | 129 | ||
@@ -125,6 +131,7 @@ static void | |||
125 | kvp_send_key(struct work_struct *dummy) | 131 | kvp_send_key(struct work_struct *dummy) |
126 | { | 132 | { |
127 | struct cn_msg *msg; | 133 | struct cn_msg *msg; |
134 | struct hv_kvp_msg *message; | ||
128 | int index = kvp_transaction.index; | 135 | int index = kvp_transaction.index; |
129 | 136 | ||
130 | msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC); | 137 | msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC); |
@@ -132,9 +139,11 @@ kvp_send_key(struct work_struct *dummy) | |||
132 | if (msg) { | 139 | if (msg) { |
133 | msg->id.idx = CN_KVP_IDX; | 140 | msg->id.idx = CN_KVP_IDX; |
134 | msg->id.val = CN_KVP_VAL; | 141 | msg->id.val = CN_KVP_VAL; |
135 | msg->seq = KVP_KERNEL_GET; | 142 | |
136 | ((struct hv_ku_msg *)msg->data)->kvp_index = index; | 143 | message = (struct hv_kvp_msg *)msg->data; |
137 | msg->len = sizeof(struct hv_ku_msg); | 144 | message->kvp_hdr.operation = KVP_OP_ENUMERATE; |
145 | message->body.kvp_enum_data.index = index; | ||
146 | msg->len = sizeof(struct hv_kvp_msg); | ||
138 | cn_netlink_send(msg, 0, GFP_ATOMIC); | 147 | cn_netlink_send(msg, 0, GFP_ATOMIC); |
139 | kfree(msg); | 148 | kfree(msg); |
140 | } | 149 | } |
@@ -191,7 +200,7 @@ kvp_respond_to_host(char *key, char *value, int error) | |||
191 | kvp_msg = (struct hv_kvp_msg *) | 200 | kvp_msg = (struct hv_kvp_msg *) |
192 | &recv_buffer[sizeof(struct vmbuspipe_hdr) + | 201 | &recv_buffer[sizeof(struct vmbuspipe_hdr) + |
193 | sizeof(struct icmsg_hdr)]; | 202 | sizeof(struct icmsg_hdr)]; |
194 | kvp_data = &kvp_msg->kvp_data; | 203 | kvp_data = &kvp_msg->body.kvp_enum_data; |
195 | key_name = key; | 204 | key_name = key; |
196 | 205 | ||
197 | /* | 206 | /* |
@@ -266,7 +275,7 @@ void hv_kvp_onchannelcallback(void *context) | |||
266 | sizeof(struct vmbuspipe_hdr) + | 275 | sizeof(struct vmbuspipe_hdr) + |
267 | sizeof(struct icmsg_hdr)]; | 276 | sizeof(struct icmsg_hdr)]; |
268 | 277 | ||
269 | kvp_data = &kvp_msg->kvp_data; | 278 | kvp_data = &kvp_msg->body.kvp_enum_data; |
270 | 279 | ||
271 | /* | 280 | /* |
272 | * We only support the "get" operation on | 281 | * We only support the "get" operation on |
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index b822978ecbc8..75aee6720c1b 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h | |||
@@ -113,30 +113,6 @@ | |||
113 | * (not supported), a NULL key string is returned. | 113 | * (not supported), a NULL key string is returned. |
114 | */ | 114 | */ |
115 | 115 | ||
116 | /* | ||
117 | * | ||
118 | * The following definitions are shared with the user-mode component; do not | ||
119 | * change any of this without making the corresponding changes in | ||
120 | * the KVP user-mode component. | ||
121 | */ | ||
122 | |||
123 | enum hv_ku_op { | ||
124 | KVP_REGISTER = 0, /* Register the user mode component */ | ||
125 | KVP_KERNEL_GET, /* Kernel is requesting the value */ | ||
126 | KVP_KERNEL_SET, /* Kernel is providing the value */ | ||
127 | KVP_USER_GET, /* User is requesting the value */ | ||
128 | KVP_USER_SET /* User is providing the value */ | ||
129 | }; | ||
130 | |||
131 | struct hv_ku_msg { | ||
132 | __u32 kvp_index; /* Key index */ | ||
133 | __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ | ||
134 | __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ | ||
135 | }; | ||
136 | |||
137 | |||
138 | |||
139 | |||
140 | 116 | ||
141 | /* | 117 | /* |
142 | * Registry value types. | 118 | * Registry value types. |
@@ -149,6 +125,7 @@ enum hv_kvp_exchg_op { | |||
149 | KVP_OP_SET, | 125 | KVP_OP_SET, |
150 | KVP_OP_DELETE, | 126 | KVP_OP_DELETE, |
151 | KVP_OP_ENUMERATE, | 127 | KVP_OP_ENUMERATE, |
128 | KVP_OP_REGISTER, | ||
152 | KVP_OP_COUNT /* Number of operations, must be last. */ | 129 | KVP_OP_COUNT /* Number of operations, must be last. */ |
153 | }; | 130 | }; |
154 | 131 | ||
@@ -182,7 +159,10 @@ struct hv_kvp_msg_enumerate { | |||
182 | 159 | ||
183 | struct hv_kvp_msg { | 160 | struct hv_kvp_msg { |
184 | struct hv_kvp_hdr kvp_hdr; | 161 | struct hv_kvp_hdr kvp_hdr; |
185 | struct hv_kvp_msg_enumerate kvp_data; | 162 | union { |
163 | struct hv_kvp_msg_enumerate kvp_enum_data; | ||
164 | char kvp_version[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; | ||
165 | } body; | ||
186 | } __attribute__((packed)); | 166 | } __attribute__((packed)); |
187 | 167 | ||
188 | #ifdef __KERNEL__ | 168 | #ifdef __KERNEL__ |
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index b75523cde2cd..4ebf70380582 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c | |||
@@ -302,7 +302,7 @@ int main(void) | |||
302 | struct pollfd pfd; | 302 | struct pollfd pfd; |
303 | struct nlmsghdr *incoming_msg; | 303 | struct nlmsghdr *incoming_msg; |
304 | struct cn_msg *incoming_cn_msg; | 304 | struct cn_msg *incoming_cn_msg; |
305 | struct hv_ku_msg *hv_msg; | 305 | struct hv_kvp_msg *hv_msg; |
306 | char *p; | 306 | char *p; |
307 | char *key_value; | 307 | char *key_value; |
308 | char *key_name; | 308 | char *key_name; |
@@ -340,9 +340,11 @@ int main(void) | |||
340 | message = (struct cn_msg *)kvp_send_buffer; | 340 | message = (struct cn_msg *)kvp_send_buffer; |
341 | message->id.idx = CN_KVP_IDX; | 341 | message->id.idx = CN_KVP_IDX; |
342 | message->id.val = CN_KVP_VAL; | 342 | message->id.val = CN_KVP_VAL; |
343 | message->seq = KVP_REGISTER; | 343 | |
344 | hv_msg = (struct hv_kvp_msg *)message->data; | ||
345 | hv_msg->kvp_hdr.operation = KVP_OP_REGISTER; | ||
344 | message->ack = 0; | 346 | message->ack = 0; |
345 | message->len = 0; | 347 | message->len = sizeof(struct hv_kvp_msg); |
346 | 348 | ||
347 | len = netlink_send(fd, message); | 349 | len = netlink_send(fd, message); |
348 | if (len < 0) { | 350 | if (len < 0) { |
@@ -368,14 +370,15 @@ int main(void) | |||
368 | 370 | ||
369 | incoming_msg = (struct nlmsghdr *)kvp_recv_buffer; | 371 | incoming_msg = (struct nlmsghdr *)kvp_recv_buffer; |
370 | incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg); | 372 | incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg); |
373 | hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data; | ||
371 | 374 | ||
372 | switch (incoming_cn_msg->seq) { | 375 | switch (hv_msg->kvp_hdr.operation) { |
373 | case KVP_REGISTER: | 376 | case KVP_OP_REGISTER: |
374 | /* | 377 | /* |
375 | * Driver is registering with us; stash away the version | 378 | * Driver is registering with us; stash away the version |
376 | * information. | 379 | * information. |
377 | */ | 380 | */ |
378 | p = (char *)incoming_cn_msg->data; | 381 | p = (char *)hv_msg->body.kvp_version; |
379 | lic_version = malloc(strlen(p) + 1); | 382 | lic_version = malloc(strlen(p) + 1); |
380 | if (lic_version) { | 383 | if (lic_version) { |
381 | strcpy(lic_version, p); | 384 | strcpy(lic_version, p); |
@@ -386,17 +389,15 @@ int main(void) | |||
386 | } | 389 | } |
387 | continue; | 390 | continue; |
388 | 391 | ||
389 | case KVP_KERNEL_GET: | ||
390 | break; | ||
391 | default: | 392 | default: |
392 | continue; | 393 | break; |
393 | } | 394 | } |
394 | 395 | ||
395 | hv_msg = (struct hv_ku_msg *)incoming_cn_msg->data; | 396 | hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data; |
396 | key_name = (char *)hv_msg->kvp_key; | 397 | key_name = (char *)hv_msg->body.kvp_enum_data.data.key; |
397 | key_value = (char *)hv_msg->kvp_value; | 398 | key_value = (char *)hv_msg->body.kvp_enum_data.data.value; |
398 | 399 | ||
399 | switch (hv_msg->kvp_index) { | 400 | switch (hv_msg->body.kvp_enum_data.index) { |
400 | case FullyQualifiedDomainName: | 401 | case FullyQualifiedDomainName: |
401 | kvp_get_domain_name(key_value, | 402 | kvp_get_domain_name(key_value, |
402 | HV_KVP_EXCHANGE_MAX_VALUE_SIZE); | 403 | HV_KVP_EXCHANGE_MAX_VALUE_SIZE); |
@@ -456,9 +457,8 @@ int main(void) | |||
456 | 457 | ||
457 | incoming_cn_msg->id.idx = CN_KVP_IDX; | 458 | incoming_cn_msg->id.idx = CN_KVP_IDX; |
458 | incoming_cn_msg->id.val = CN_KVP_VAL; | 459 | incoming_cn_msg->id.val = CN_KVP_VAL; |
459 | incoming_cn_msg->seq = KVP_USER_SET; | ||
460 | incoming_cn_msg->ack = 0; | 460 | incoming_cn_msg->ack = 0; |
461 | incoming_cn_msg->len = sizeof(struct hv_ku_msg); | 461 | incoming_cn_msg->len = sizeof(struct hv_kvp_msg); |
462 | 462 | ||
463 | len = netlink_send(fd, incoming_cn_msg); | 463 | len = netlink_send(fd, incoming_cn_msg); |
464 | if (len < 0) { | 464 | if (len < 0) { |