aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2012-02-02 19:56:50 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-09 11:32:44 -0500
commit2640335438ca4d7b139e114dae5f0d80e740e106 (patch)
tree0e254e2147dedefe04e385d0c97a9fbc15df2a23
parenteab6af71f0b83a7f62b9c48be5b2c0a82a86fad3 (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.c41
-rw-r--r--include/linux/hyperv.h30
-rw-r--r--tools/hv/hv_kvp_daemon.c30
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)
101static void 106static void
102kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) 107kvp_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
125kvp_send_key(struct work_struct *dummy) 131kvp_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
123enum 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
131struct 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
183struct hv_kvp_msg { 160struct 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) {