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>
This commit is contained in:
parent
eab6af71f0
commit
2640335438
3 changed files with 45 additions and 56 deletions
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -266,7 +275,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
|
||||
|
|
|
@ -113,30 +113,6 @@
|
|||
* (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__
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue