drivers: hv: kvp
Subsystems (2)
v2 cover drivers: hv: kvp
This patchset expands the KVP (Key Value Pair) functionality to implement the mechanism to GET/SET IP addresses in the guest. This functionality is used in Windows Server 2012 to implement VM replication functionality. The way IP configuration information is managed is distro specific. Based on the feedback I have gotten from Olaf, Greg, Steve, Ben and Mairus, I have chosen to seperate distro specific code from this patch-set. Most of the GET operation can be implemented in a way that is completely distro independent and I have implemented that as such and is included in this patch-set. Some of the attributes that can only be fetched in a distro dependent way as well the mechanism for configuring an interface (the SET operation) that is clearly distro specific is to be implemented via external scripts that will be invoked via the KVP code. We define here the interface to these scripts.
Adding support for IP injection resulted in some changes to the protocol between the user level daemon and the kernel driver. These changes have been implemented in way that would retain compatibility with older daemons. I would like to thank Olaf and Greg for pointing out the compatibility issue.
This version of the patch set addresses all of the comments that I have received to date from Olaf, Ben and others. Specifically, I have cleanedup all of the string manipulation code. Furthermore, I have also simplified the format of the interface configuration file that is generated by the KVP daemon and gotten rid of some constant strings that may not be relevant on all distros. I would like to thank Olaf and Ben for their detailed review.
K. Y. Srinivasan (18):
Drivers: hv: vmbus: Use the standard format string to format GUIDs
Drivers: hv: Add KVP definitions for IP address injection
Drivers: hv: kvp: Cleanup error handling in KVP
Drivers: hv: kvp: Support the new IP injection messages
Tools: hv: Prepare to expand kvp_get_ip_address() functionality
Tools: hv: Further refactor kvp_get_ip_address()
Tools: hv: Gather address family information
Tools: hv: Gather subnet information
Tools: hv: Represent the ipv6 mask using CIDR notation
Tools: hv: Gather ipv[4,6] gateway information
Tools: hv: Gather DNS information
Tools: hv: Gather DHCP information
Tools: hv: Implement the KVP verb - KVP_OP_SET_IP_INFO
Tools: hv: Rename the function kvp_get_ip_address()
Tools: hv: Implement the KVP verb - KVP_OP_GET_IP_INFO
Tools: hv: Get rid of some unused variables
Tools: hv: Correctly type string variables
Tools: hv: Properly manage open streams
drivers/hv/hv_kvp.c | 253 +++++++++++-- drivers/hv/hv_util.c | 4 +- drivers/hv/vmbus_drv.c | 38 +-- include/linux/hyperv.h | 93 +++++- tools/hv/hv_kvp_daemon.c | 928 +++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 1147 insertions(+), 169 deletions(-)
Signature · 1 line
1.7.4.1
PATCH v2 1/18 Drivers: hv: vmbus: Use the standard format string to format GUIDs
Format GUIDS as per MSFT standard. This makes interacting with MSFT tool stack easier.
--- drivers/hv/vmbus_drv.c | 38 ++------------------------------------ 1 files changed, 2 insertions(+), 36 deletions(-)
drivers/hv/vmbus_drv.c +2 -36
@@ -146,43 +146,9 @@ static ssize_t vmbus_show_device_attr(struct device *dev,get_channel_info (hv_dev, device_info);if (!strcmp (dev_attr->attr.name,"class_id" )) { - ret =sprintf (buf,"{%02x%02x%02x%02x-%02x%02x-%02x%02x-" -"%02x%02x%02x%02x%02x%02x%02x%02x}\n" , - device_info->chn_type.b[3 ], - device_info->chn_type.b[2 ], - device_info->chn_type.b[1 ], - device_info->chn_type.b[0 ], - device_info->chn_type.b[5 ], - device_info->chn_type.b[4 ], - device_info->chn_type.b[7 ], - device_info->chn_type.b[6 ], - device_info->chn_type.b[8 ], - device_info->chn_type.b[9 ], - device_info->chn_type.b[10 ], - device_info->chn_type.b[11 ], - device_info->chn_type.b[12 ], - device_info->chn_type.b[13 ], - device_info->chn_type.b[14 ], - device_info->chn_type.b[15 ]); + ret =sprintf (buf,"{%pUl}\n" , device_info->chn_type.b); }else if (!strcmp (dev_attr->attr.name,"device_id" )) { - ret =sprintf (buf,"{%02x%02x%02x%02x-%02x%02x-%02x%02x-" -"%02x%02x%02x%02x%02x%02x%02x%02x}\n" , - device_info->chn_instance.b[3 ], - device_info->chn_instance.b[2 ], - device_info->chn_instance.b[1 ], - device_info->chn_instance.b[0 ], - device_info->chn_instance.b[5 ], - device_info->chn_instance.b[4 ], - device_info->chn_instance.b[7 ], - device_info->chn_instance.b[6 ], - device_info->chn_instance.b[8 ], - device_info->chn_instance.b[9 ], - device_info->chn_instance.b[10 ], - device_info->chn_instance.b[11 ], - device_info->chn_instance.b[12 ], - device_info->chn_instance.b[13 ], - device_info->chn_instance.b[14 ], - device_info->chn_instance.b[15 ]); + ret =sprintf (buf,"{%pUl}\n" , device_info->chn_instance.b); }else if (!strcmp (dev_attr->attr.name,"modalias" )) {print_alias_name (hv_dev, alias_name); ret =sprintf (buf,"vmbus:%s\n" , alias_name);
Signature · 1 line
1.7.4.1
PATCH v2 2/18 Drivers: hv: Add KVP definitions for IP address injection
Add the necessary definitions for supporting the IP injection functionality.
--- drivers/hv/hv_util.c | 4 +- include/linux/hyperv.h | 76 ++++++++++++++++++++++++++++++++++++++++++++- tools/hv/hv_kvp_daemon.c | 2 +- 3 files changed, 77 insertions(+), 5 deletions(-)
drivers/hv/hv_util.c +2 -2
@@ -263,7 +263,7 @@ static int util_probe(struct hv_device *dev, (struct hv_util_service *)dev_id->driver_data;int ret; - srv->recv_buffer =kmalloc (PAGE_SIZE ,GFP_KERNEL ); + srv->recv_buffer =kmalloc (PAGE_SIZE *2 ,GFP_KERNEL );if (!srv->recv_buffer)return -ENOMEM ;if (srv->util_init) {
@@ -274,7 +274,7 @@ static int util_probe(struct hv_device *dev, } } - ret =vmbus_open (dev->channel,2 *PAGE_SIZE ,2 *PAGE_SIZE ,NULL ,0 , + ret =vmbus_open (dev->channel,4 *PAGE_SIZE ,4 *PAGE_SIZE ,NULL ,0 , srv->util_cb, dev->channel);if (ret) goto error;
include/linux/hyperv.h +74 -2
114 lines not on this page · raw message
tools/hv/hv_kvp_daemon.c +1 -1
@@ -69,7 +69,7 @@ enum key_index { };static char kvp_send_buffer[4096 ]; -static char kvp_recv_buffer[4096 ]; +static char kvp_recv_buffer[4096 *2 ];static struct sockaddr_nl addr;static char *os_name ="" ;
Signature · 1 line
1.7.4.1
Re: [PATCH V2 02/18] Drivers: hv: Add KVP definitions for IP address injection
Quoted 62 lines · K. Y. Srinivasan
Add the necessary definitions for supporting the IP injection functionality.
Signed-off-by K. Y. Srinivasan <[email protected]>Reviewed-by Haiyang Zhang <[email protected]>Reviewed-by Olaf Hering <[email protected]>Reviewed-by Ben Hutchings <[email protected]>--- drivers/hv/hv_util.c | 4 +- include/linux/hyperv.h | 76 ++++++++++++++++++++++++++++++++++++++++++++- tools/hv/hv_kvp_daemon.c | 2 +- 3 files changed, 77 insertions(+), 5 deletions(-)drivers/hv/hv_util.c +2
-2@@ -263,7 +263,7 @@ static int util_probe(struct hv_device *dev, (struct hv_util_service *)dev_id->driver_data;int ret; - srv->recv_buffer =kmalloc (PAGE_SIZE ,GFP_KERNEL ); + srv->recv_buffer =kmalloc (PAGE_SIZE *2 ,GFP_KERNEL );if (!srv->recv_buffer)return -ENOMEM ;if (srv->util_init) {@@ -274,7 +274,7 @@ static int util_probe(struct hv_device *dev, } } - ret =vmbus_open (dev->channel,2 *PAGE_SIZE ,2 *PAGE_SIZE ,NULL ,0 , + ret =vmbus_open (dev->channel,4 *PAGE_SIZE ,4 *PAGE_SIZE ,NULL ,0 , srv->util_cb, dev->channel);if (ret) goto error;include/linux/hyperv.h +20
-0@@ -122,12 +122,53 @@#define REG_U32 4#define REG_U64 8 +/* +* As we look at expanding the KVP functionality to include +* IP injection functionality, we need to maintain binary +* compatibility with older daemons. +* +* The KVP opcodes are defined by the host and it was unfortunate +* that I chose to treat the registration operation as part of the +* KVP operations defined by the host. +* Here is the level of compatibility +* (between the user level daemon and the kernel KVP driver) that we +* will implement: +* +* An older daemon will always be supported on a newer driver. +* A given user level daemon will require a minimal version of the +* kernel driver. +* If we cannot handle the version differences, we will fail gracefully +* (this can happen when we have a user level daemon that is more +* advanced than the KVP driver. +* +* We will use values used in this handshake for determining if we have
include/linux/hyperv.h line 154
Quoted 10 lines
include/linux/hyperv.h +10
-0+* workable user level daemon and the kernel driver. We begin by taking the +* registration opcode out of the KVP opcode namespace. We will however, +* maintain compatibility with the existing user-level daemon code. +*/ + +/* +* Daemon code not supporting IP injection (legacy daemon). +*/ + +#define KVP_OP_REGISTER 4
Huh?
Quoted 7 lines
include/linux/hyperv.h +7
-0+/* +* Daemon code supporting IP injection. +* The KVP opcode field is used to communicate the +* registration information; so define a namespace that +* will be distinct from the host defined KVP opcode. +*/ +
include/linux/hyperv.h line 171
Quoted 10 lines
include/linux/hyperv.h +4
-1+#define KVP_OP_REGISTER1 100 +enum hv_kvp_exchg_op {KVP_OP_GET =0 ,KVP_OP_SET ,KVP_OP_DELETE ,KVP_OP_ENUMERATE , -KVP_OP_REGISTER , +KVP_OP_GET_IP_INFO , +KVP_OP_SET_IP_INFO ,
So you overloaded the command and somehow think that is ok? How is that supposed to work? Why not just always keep it there, but fail if it is called as you know you have a mismatch?
Otherwise, again, you just broke older tools on a newer kernel.
Or am I missing something here?
confused,
greg k-h
Re: [PATCH V2 02/18] Drivers: hv: Add KVP definitions for IP address injection
Quoted 2 lines · Greg KH
Quoted 1 line · K. Y. Srinivasan
Add the necessary definitions for supporting the IP injection functionality.
[...]
Quoted 61 lines
Quoted 26 lines
include/linux/hyperv.h +20
-0@@ -122,12 +122,53 @@#define REG_U32 4#define REG_U64 8 +/* +* As we look at expanding the KVP functionality to include +* IP injection functionality, we need to maintain binary +* compatibility with older daemons. +* +* The KVP opcodes are defined by the host and it was unfortunate +* that I chose to treat the registration operation as part of the +* KVP operations defined by the host. +* Here is the level of compatibility +* (between the user level daemon and the kernel KVP driver) that we +* will implement: +* +* An older daemon will always be supported on a newer driver. +* A given user level daemon will require a minimal version of the +* kernel driver. +* If we cannot handle the version differences, we will fail gracefully +* (this can happen when we have a user level daemon that is more +* advanced than the KVP driver. +* +* We will use values used in this handshake for determining if we have include/linux/hyperv.h line 154
Quoted 10 lines
include/linux/hyperv.h +10
-0+* workable user level daemon and the kernel driver. We begin by taking the +* registration opcode out of the KVP opcode namespace. We will however, +* maintain compatibility with the existing user-level daemon code. +*/ + +/* +* Daemon code not supporting IP injection (legacy daemon). +*/ + +#define KVP_OP_REGISTER 4Huh?
Quoted 7 lines
include/linux/hyperv.h +7
-0+/* +* Daemon code supporting IP injection. +* The KVP opcode field is used to communicate the +* registration information; so define a namespace that +* will be distinct from the host defined KVP opcode. +*/ +include/linux/hyperv.h line 171
Quoted 10 lines
include/linux/hyperv.h +4
-1+#define KVP_OP_REGISTER1 100 +enum hv_kvp_exchg_op {KVP_OP_GET =0 ,KVP_OP_SET ,KVP_OP_DELETE ,KVP_OP_ENUMERATE , -KVP_OP_REGISTER , +KVP_OP_GET_IP_INFO , +KVP_OP_SET_IP_INFO ,So you overloaded the command and somehow think that is ok? How is that supposed to work? Why not just always keep it there, but fail if it is called as you know you have a mismatch?
Quoted 3 lines
Otherwise, again, you just broke older tools on a newer kernel.
Or am I missing something here?
You are. The above enumeration is for the hypervisor-to-guest protocol, whereas KVP_OP_REGISTER and KVP_OP_REGISTER1 are only used between daemon and driver. The registration operation code should have been defined as a sufficiently high value to avoid collision.
However, since the daemon will always send one of the registration operations at start of day (and then never again), it seems that the driver can avoid confusing registration with a reply to KVP_OP_GET_IP_INFO. Instead, the two registration operation codes distinguish the capabilities of the daemon and actually aid backward compatibility.
Ben.
Signature · 2 lines
Ben Hutchings I say we take off; nuke the site from orbit. It's the only way to be sure.
RE: [PATCH V2 02/18] Drivers: hv: Add KVP definitions for IP address injection
In reply to Greg KHQuoted 113 lines
-----Original Message-----
From: Greg KH [mailto:[email protected]]
Sent: Monday, August 13, 2012 9:38 PM
To: KY Srinivasan
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH V2 02/18] Drivers: hv: Add KVP definitions for IP address injectionQuoted 9 lines · K. Y. Srinivasan
Add the necessary definitions for supporting the IP injection functionality.
Signed-off-by K. Y. Srinivasan <[email protected]>Reviewed-by Haiyang Zhang <[email protected]>Reviewed-by Olaf Hering <[email protected]>Reviewed-by Ben Hutchings <[email protected]>--- drivers/hv/hv_util.c | 4 +- include/linux/hyperv.h | 76++++++++++++++++++++++++++++++++++++++++++++-
Quoted 17 lines
tools/hv/hv_kvp_daemon.c | 2 +- 3 files changed, 77 insertions(+), 5 deletions(-)drivers/hv/hv_util.c +1
-1@@ -263,7 +263,7 @@ static int util_probe(struct hv_device *dev, (struct hv_util_service *)dev_id->driver_data;int ret; - srv->recv_buffer =kmalloc (PAGE_SIZE ,GFP_KERNEL ); + srv->recv_buffer =kmalloc (PAGE_SIZE *2 ,GFP_KERNEL );if (!srv->recv_buffer)return -ENOMEM ;if (srv->util_init) {drivers/hv/hv_util.c static int util_probe(struct hv_device *dev, · line 277
Quoted 4 lines
drivers/hv/hv_util.c +0
-1@@ -274,7 +274,7 @@ static int util_probe(struct hv_device *dev, } } - ret = vmbus_open(dev->channel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL,0,
drivers/hv/hv_util.c static int util_probe(struct hv_device *dev, · line 277
Quoted 1 line
drivers/hv/hv_util.c +1
-0+ ret = vmbus_open(dev->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL,0,
Quoted 31 lines
drivers/hv/hv_util.c +0
-0srv->util_cb, dev->channel);if (ret) goto error;include/linux/hyperv.h +20
-0@@ -122,12 +122,53 @@#define REG_U32 4#define REG_U64 8 +/* +* As we look at expanding the KVP functionality to include +* IP injection functionality, we need to maintain binary +* compatibility with older daemons. +* +* The KVP opcodes are defined by the host and it was unfortunate +* that I chose to treat the registration operation as part of the +* KVP operations defined by the host. +* Here is the level of compatibility +* (between the user level daemon and the kernel KVP driver) that we +* will implement: +* +* An older daemon will always be supported on a newer driver. +* A given user level daemon will require a minimal version of the +* kernel driver. +* If we cannot handle the version differences, we will fail gracefully +* (this can happen when we have a user level daemon that is more +* advanced than the KVP driver. +* +* We will use values used in this handshake for determining if we have include/linux/hyperv.h line 154
Quoted 10 lines
include/linux/hyperv.h +10
-0+* workable user level daemon and the kernel driver. We begin by taking the +* registration opcode out of the KVP opcode namespace. We will however, +* maintain compatibility with the existing user-level daemon code. +*/ + +/* +* Daemon code not supporting IP injection (legacy daemon). +*/ + +#define KVP_OP_REGISTER 4Huh?
Quoted 7 lines
include/linux/hyperv.h +7
-0+/* +* Daemon code supporting IP injection. +* The KVP opcode field is used to communicate the +* registration information; so define a namespace that +* will be distinct from the host defined KVP opcode. +*/ +include/linux/hyperv.h line 171
Quoted 10 lines
include/linux/hyperv.h +4
-1+#define KVP_OP_REGISTER1 100 +enum hv_kvp_exchg_op {KVP_OP_GET =0 ,KVP_OP_SET ,KVP_OP_DELETE ,KVP_OP_ENUMERATE , -KVP_OP_REGISTER , +KVP_OP_GET_IP_INFO , +KVP_OP_SET_IP_INFO ,So you overloaded the command and somehow think that is ok? How is that supposed to work? Why not just always keep it there, but fail if it is called as you know you have a mismatch?
Quoted 3 lines
Otherwise, again, you just broke older tools on a newer kernel.
Or am I missing something here?
Greg,
The registration operation occurs when the daemon first starts up. I should have established a distinct namespace for the daemon versions that would not overlap with the host defined KVP operations initially. Unfortunately when I first implemented KVP, I did not know about the new KVP verbs and so selected a value that ended up colliding with the new KVP operations. To maintain compatibility with older daemons, I have to support this old registration value, which is what you are seeing here. Since the initial driver/daemon handshake phase does not overlap with the normal functioning of the KVP stack, we can use the old daemon registration value to distinguish that the daemon does not support IP injection. The current implementation does support a compatible environment for older daemons.
Regards,
K. Y
RE: [PATCH V2 02/18] Drivers: hv: Add KVP definitions for IP address injection
Quoted 140 lines
-----Original Message-----
From: [email protected] [mailto:devel- [email protected]] On Behalf Of KY Srinivasan
Sent: Monday, August 13, 2012 10:57 PM
To: Greg KH
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: RE: [PATCH V2 02/18] Drivers: hv: Add KVP definitions for IP address injectionQuoted 111 lines
-----Original Message-----
From: Greg KH [mailto:[email protected]]
Sent: Monday, August 13, 2012 9:38 PM
To: KY Srinivasan
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH V2 02/18] Drivers: hv: Add KVP definitions for IP address injectionQuoted 9 lines · K. Y. Srinivasan
Add the necessary definitions for supporting the IP injection functionality.
Signed-off-by K. Y. Srinivasan <[email protected]>Reviewed-by Haiyang Zhang <[email protected]>Reviewed-by Olaf Hering <[email protected]>Reviewed-by Ben Hutchings <[email protected]>--- drivers/hv/hv_util.c | 4 +- include/linux/hyperv.h | 76++++++++++++++++++++++++++++++++++++++++++++-
Quoted 17 lines
tools/hv/hv_kvp_daemon.c | 2 +- 3 files changed, 77 insertions(+), 5 deletions(-)drivers/hv/hv_util.c +1
-1@@ -263,7 +263,7 @@ static int util_probe(struct hv_device *dev, (struct hv_util_service *)dev_id->driver_data;int ret; - srv->recv_buffer =kmalloc (PAGE_SIZE ,GFP_KERNEL ); + srv->recv_buffer =kmalloc (PAGE_SIZE *2 ,GFP_KERNEL );if (!srv->recv_buffer)return -ENOMEM ;if (srv->util_init) {drivers/hv/hv_util.c static int util_probe(struct hv_device *dev, · line 277
Quoted 4 lines
drivers/hv/hv_util.c +0
-1@@ -274,7 +274,7 @@ static int util_probe(struct hv_device *dev, } } - ret = vmbus_open(dev->channel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL,0,
drivers/hv/hv_util.c static int util_probe(struct hv_device *dev, · line 277
Quoted 1 line
drivers/hv/hv_util.c +1
-0+ ret = vmbus_open(dev->channel, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL,0,
Quoted 31 lines
drivers/hv/hv_util.c +0
-0srv->util_cb, dev->channel);if (ret) goto error;include/linux/hyperv.h +20
-0@@ -122,12 +122,53 @@#define REG_U32 4#define REG_U64 8 +/* +* As we look at expanding the KVP functionality to include +* IP injection functionality, we need to maintain binary +* compatibility with older daemons. +* +* The KVP opcodes are defined by the host and it was unfortunate +* that I chose to treat the registration operation as part of the +* KVP operations defined by the host. +* Here is the level of compatibility +* (between the user level daemon and the kernel KVP driver) that we +* will implement: +* +* An older daemon will always be supported on a newer driver. +* A given user level daemon will require a minimal version of the +* kernel driver. +* If we cannot handle the version differences, we will fail gracefully +* (this can happen when we have a user level daemon that is more +* advanced than the KVP driver. +* +* We will use values used in this handshake for determining if we have include/linux/hyperv.h line 154
Quoted 10 lines
include/linux/hyperv.h +10
-0+* workable user level daemon and the kernel driver. We begin by taking the +* registration opcode out of the KVP opcode namespace. We will however, +* maintain compatibility with the existing user-level daemon code. +*/ + +/* +* Daemon code not supporting IP injection (legacy daemon). +*/ + +#define KVP_OP_REGISTER 4Huh?
Quoted 7 lines
include/linux/hyperv.h +7
-0+/* +* Daemon code supporting IP injection. +* The KVP opcode field is used to communicate the +* registration information; so define a namespace that +* will be distinct from the host defined KVP opcode. +*/ +include/linux/hyperv.h line 171
Quoted 10 lines
include/linux/hyperv.h +4
-1+#define KVP_OP_REGISTER1 100 +enum hv_kvp_exchg_op {KVP_OP_GET =0 ,KVP_OP_SET ,KVP_OP_DELETE ,KVP_OP_ENUMERATE , -KVP_OP_REGISTER , +KVP_OP_GET_IP_INFO , +KVP_OP_SET_IP_INFO ,So you overloaded the command and somehow think that is ok? How is that supposed to work? Why not just always keep it there, but fail if it is called as you know you have a mismatch?
Quoted 3 lines
Otherwise, again, you just broke older tools on a newer kernel.
Or am I missing something here?
Greg,
The registration operation occurs when the daemon first starts up. I should have established
a distinct namespace for the daemon versions that would not overlap with the host
defined KVP operations initially. Unfortunately when I first implemented KVP, I did not know
about the new KVP verbs and so selected a value that ended up colliding with the new KVP
operations. To maintain compatibility with older daemons, I have to support this
Quoted 9 lines
old registration
value, which is what you are seeing here. Since the initial driver/daemon handshake phase does
not overlap with the normal functioning of the KVP stack, we can use the old daemon
registration value to distinguish that the daemon does not support IP injection. The current
implementation does support a compatible environment for older daemons.
Greg,
I hope this explanation is satisfactory. If there are other issues that you would want me to address before this patch set can be accepted, let me know and I will address them right away.
Regards,
K. Y
PATCH v2 3/18 Drivers: hv: kvp: Cleanup error handling in KVP
In reply to K. Y. SrinivasanIn preparation to implementing IP injection, cleanup the way we propagate and handle errors both in the driver as well as in the user level daemon.
--- drivers/hv/hv_kvp.c | 114 ++++++++++++++++++++++++++++++++++++--------- include/linux/hyperv.h | 17 ++++-- tools/hv/hv_kvp_daemon.c | 66 +++++++++++++------------- 3 files changed, 135 insertions(+), 62 deletions(-)
drivers/hv/hv_kvp.c +91 -23
@@ -48,13 +48,24 @@ static struct {void *kvp_context;/* for the channel callback */ } kvp_transaction; +/* +* Before we can accept KVP messages from the host, we need +* to handshake with the user level daemon. This state tracks +* if we are in the handshake phase. +*/ +static bool in_hand_shake = true; + +/* +* This state maintains the version number registered by the daemon. +*/ +static int dm_reg_value; +static void kvp_send_key (struct work_struct *dummy); -#define TIMEOUT_FIRED 1static void kvp_respond_to_host (char *key,char *value,int error);static void kvp_work_func (struct work_struct *dummy); -static void kvp_register (void ); +static void kvp_register (int ); static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func); static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
@@ -68,7 +79,7 @@ static u8 *recv_buffer;*/ static void -kvp_register (void ) +kvp_register (int reg_value) {struct cn_msg *msg;
@@ -83,7 +94,7 @@ kvp_register(void) msg->id.idx =CN_KVP_IDX ; msg->id.val =CN_KVP_VAL ; - kvp_msg->kvp_hdr.operation =KVP_OP_REGISTER ; + kvp_msg->kvp_hdr.operation = reg_value;strcpy (version,HV_DRV_VERSION ); msg->len =sizeof (struct hv_kvp_msg );cn_netlink_send (msg,0 ,GFP_ATOMIC );
@@ -97,9 +108,43 @@ kvp_work_func(struct work_struct *dummy)* If the timer fires, the user-mode component has not responded; * process the pending transaction. */ -kvp_respond_to_host ("Unknown key" ,"Guest timed out" ,TIMEOUT_FIRED ); +kvp_respond_to_host ("Unknown key" ,"Guest timed out" ,HV_E_FAIL ); +} + +static int kvp_handle_handshake (struct hv_kvp_msg *msg) +{ +int ret =1 ; + +switch (msg->kvp_hdr.operation) { +case KVP_OP_REGISTER : + dm_reg_value =KVP_OP_REGISTER ; +pr_info ("KVP: IP injection functionality not available\n" ); +pr_info ("KVP: Upgrade the KVP daemon\n" ); +break ; +case KVP_OP_REGISTER1 : + dm_reg_value =KVP_OP_REGISTER1 ; +break ; +default : +pr_info ("KVP: incompatible daemon\n" ); +pr_info ("KVP: KVP version: %d, Daemon version: %d\n" , +KVP_OP_REGISTER1 , msg->kvp_hdr.operation); + ret =0 ; + } + +if (ret) { +/* +* We have a compatible daemon; complete the handshake. +*/ +pr_info ("KVP: user-mode registering done.\n" ); +kvp_register (dm_reg_value); + kvp_transaction.active = false; +if (kvp_transaction.kvp_context) +hv_kvp_onchannelcallback (kvp_transaction.kvp_context); + } +return ret; } +/* * Callback when data is received from user mode. */
@@ -109,27 +154,52 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) {struct hv_kvp_msg *message;struct hv_kvp_msg_enumerate *data; +int error =0 ; message = (struct hv_kvp_msg *)msg->data; -switch (message->kvp_hdr.operation) { + +/* +* If we are negotiating the version information +* with the daemon; handle that first. +*/ + +if (in_hand_shake) { +if (kvp_handle_handshake (message)) + in_hand_shake = false; +return ; + } + +/* +* Based on the version of the daemon, we propagate errors from the +* daemon differently. +*/ + + data = &message->body.kvp_enum_data; + +switch (dm_reg_value) {case KVP_OP_REGISTER : -pr_info ("KVP: user-mode registering done.\n" ); -kvp_register (); - kvp_transaction.active = false; -hv_kvp_onchannelcallback (kvp_transaction.kvp_context); +/* +* Null string is used to pass back error condition. +*/ +if (data->data.key[0 ] ==0 ) + error =HV_S_CONT ;break ; -default : - data = &message->body.kvp_enum_data; +case KVP_OP_REGISTER1 :/* -* Complete the transaction by forwarding the key value -* to the host. But first, cancel the timeout. +* We use the message header information from +* the user level daemon to transmit errors. */ -if (cancel_delayed_work_sync (&kvp_work)) -kvp_respond_to_host (data->data.key, - data->data.value, - !strlen (data->data.key)); + error = message->error; +break ; } + +/* +* 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 (data->data.key, data->data.value, error); } static void
@@ -287,6 +357,7 @@ kvp_respond_to_host(char *key, char *value, int error)*/ return ; + icmsghdrp->status = error;/* * If the error parameter is set, terminate the host's enumeration
@@ -294,15 +365,12 @@ kvp_respond_to_host(char *key, char *value, int error)*/ if (error) {/* -* Something failed or the we have timedout; -* terminate the current host-side iteration. +* Something failed or we have timedout; +* terminate the current host-side iteration. */ - icmsghdrp->status =HV_S_CONT ; goto response_done; } - icmsghdrp->status =HV_S_OK ; - kvp_msg = (struct hv_kvp_msg *) &recv_buffer[sizeof (struct vmbuspipe_hdr ) +sizeof (struct icmsg_hdr )];
include/linux/hyperv.h +11 -6
@@ -181,6 +181,17 @@ enum hv_kvp_exchg_pool { KVP_POOL_COUNT /* Number of pools, must be last. */ }; +/* +* Some Hyper-V status codes. +*/ + +#define HV_S_OK 0x00000000 +#define HV_E_FAIL 0x80004005 +#define HV_S_CONT 0x80070103 +#define HV_ERROR_NOT_SUPPORTED 0x80070032 +#define HV_ERROR_MACHINE_LOCKED 0x800704F7 +#define HV_ERROR_DEVICE_NOT_CONNECTED 0x8007048F +#define ADDR_FAMILY_NONE 0x00#define ADDR_FAMILY_IPV4 0x01#define ADDR_FAMILY_IPV6 0x02
@@ -1048,12 +1059,6 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver);#define ICMSGHDRFLAG_REQUEST 2#define ICMSGHDRFLAG_RESPONSE 4 -#define HV_S_OK 0x00000000 -#define HV_E_FAIL 0x80004005 -#define HV_S_CONT 0x80070103 -#define HV_ERROR_NOT_SUPPORTED 0x80070032 -#define HV_ERROR_MACHINE_LOCKED 0x800704F7 -#define HV_ERROR_DEVICE_NOT_CONNECTED 0x8007048F/* * While we want to handle util services as regular devices,
tools/hv/hv_kvp_daemon.c +33 -33
162 lines not on this page · raw message
Signature · 1 line
1.7.4.1
PATCH v2 4/18 Drivers: hv: kvp: Support the new IP injection messages
In reply to K. Y. SrinivasanImplement support for the new IP injection messages in the driver code.
--- drivers/hv/hv_kvp.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 137 insertions(+), 6 deletions(-)
drivers/hv/hv_kvp.c +137 -6
@@ -63,7 +63,7 @@ static int dm_reg_value;static void kvp_send_key (struct work_struct *dummy); -static void kvp_respond_to_host (char *key,char *value,int error); +static void kvp_respond_to_host (struct hv_kvp_msg *msg,int error);static void kvp_work_func (struct work_struct *dummy);static void kvp_register (int );
@@ -108,7 +108,7 @@ kvp_work_func(struct work_struct *dummy)* If the timer fires, the user-mode component has not responded; * process the pending transaction. */ -kvp_respond_to_host ("Unknown key" ,"Guest timed out" ,HV_E_FAIL ); +kvp_respond_to_host (NULL ,HV_E_FAIL ); }static int kvp_handle_handshake (struct hv_kvp_msg *msg)
@@ -199,9 +199,120 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)* to the host. But first, cancel the timeout. */ if (cancel_delayed_work_sync (&kvp_work)) -kvp_respond_to_host (data->data.key, data->data.value, error); +kvp_respond_to_host (message, error); } + +static int process_ob_ipinfo (void *in_msg,void *out_msg,int op) +{ +struct hv_kvp_msg *in = in_msg; +struct hv_kvp_ip_msg *out = out_msg; +int len; + +switch (op) { +case KVP_OP_GET_IP_INFO : +/* +* Transform all parameters into utf16 encoding. +*/ + len =utf8s_to_utf16s ((char *)in->body.kvp_ip_val.ip_addr, +strlen ((char *)in->body.kvp_ip_val.ip_addr), +UTF16_HOST_ENDIAN , + (wchar_t *)out->kvp_ip_val.ip_addr, +MAX_IP_ADDR_SIZE ); +if (len <0 ) +return len; + + len =utf8s_to_utf16s ((char *)in->body.kvp_ip_val.sub_net, +strlen ((char *)in->body.kvp_ip_val.sub_net), +UTF16_HOST_ENDIAN , + (wchar_t *)out->kvp_ip_val.sub_net, +MAX_IP_ADDR_SIZE ); +if (len <0 ) +return len; + + len =utf8s_to_utf16s ((char *)in->body.kvp_ip_val.gate_way, +strlen ((char *)in->body.kvp_ip_val.gate_way), +UTF16_HOST_ENDIAN , + (wchar_t *)out->kvp_ip_val.gate_way, +MAX_GATEWAY_SIZE ); +if (len <0 ) +return len; + + len =utf8s_to_utf16s ((char *)in->body.kvp_ip_val.dns_addr, +strlen ((char *)in->body.kvp_ip_val.dns_addr), +UTF16_HOST_ENDIAN , + (wchar_t *)out->kvp_ip_val.dns_addr, +MAX_IP_ADDR_SIZE ); +if (len <0 ) +return len; + + len =utf8s_to_utf16s ((char *)in->body.kvp_ip_val.adapter_id, +strlen ((char *)in->body.kvp_ip_val.adapter_id), +UTF16_HOST_ENDIAN , + (wchar_t *)out->kvp_ip_val.adapter_id, +MAX_IP_ADDR_SIZE ); +if (len <0 ) +return len; + + out->kvp_ip_val.dhcp_enabled = + in->body.kvp_ip_val.dhcp_enabled; + } + +return 0 ; +} + +static void process_ib_ipinfo (void *in_msg,void *out_msg,int op) +{ +struct hv_kvp_ip_msg *in = in_msg; +struct hv_kvp_msg *out = out_msg; + +switch (op) { +case KVP_OP_SET_IP_INFO : +/* +* Transform all parameters into utf8 encoding. +*/ +utf16s_to_utf8s ((wchar_t *)in->kvp_ip_val.ip_addr, +MAX_IP_ADDR_SIZE , +UTF16_LITTLE_ENDIAN , + (__u8 *)out->body.kvp_ip_val.ip_addr, +MAX_IP_ADDR_SIZE ); + +utf16s_to_utf8s ((wchar_t *)in->kvp_ip_val.sub_net, +MAX_IP_ADDR_SIZE , +UTF16_LITTLE_ENDIAN , + (__u8 *)out->body.kvp_ip_val.sub_net, +MAX_IP_ADDR_SIZE ); + +utf16s_to_utf8s ((wchar_t *)in->kvp_ip_val.gate_way, +MAX_GATEWAY_SIZE , +UTF16_LITTLE_ENDIAN , + (__u8 *)out->body.kvp_ip_val.gate_way, +MAX_GATEWAY_SIZE ); + +utf16s_to_utf8s ((wchar_t *)in->kvp_ip_val.dns_addr, +MAX_IP_ADDR_SIZE , +UTF16_LITTLE_ENDIAN , + (__u8 *)out->body.kvp_ip_val.dns_addr, +MAX_IP_ADDR_SIZE ); + + out->body.kvp_ip_val.dhcp_enabled = + in->kvp_ip_val.dhcp_enabled; + +default : +utf16s_to_utf8s ((wchar_t *)in->kvp_ip_val.adapter_id, +MAX_ADAPTER_ID_SIZE , +UTF16_LITTLE_ENDIAN , + (__u8 *)out->body.kvp_ip_val.adapter_id, +MAX_ADAPTER_ID_SIZE ); + + out->body.kvp_ip_val.addr_family = + in->kvp_ip_val.addr_family; + } +} + + + +static void kvp_send_key (struct work_struct *dummy) {
@@ -237,6 +348,12 @@ kvp_send_key(struct work_struct *dummy)*/ switch (message->kvp_hdr.operation) { +case KVP_OP_SET_IP_INFO : +process_ib_ipinfo (in_msg, message,KVP_OP_SET_IP_INFO ); +break ; +case KVP_OP_GET_IP_INFO : +process_ib_ipinfo (in_msg, message,KVP_OP_GET_IP_INFO ); +break ;case KVP_OP_SET :switch (in_msg->body.kvp_set.data.value_type) {case REG_SZ :
@@ -313,17 +430,19 @@ kvp_send_key(struct work_struct *dummy)*/ static void -kvp_respond_to_host (char *key,char *value,int error) +kvp_respond_to_host (struct hv_kvp_msg *msg_to_host,int error) {struct hv_kvp_msg *kvp_msg;struct hv_kvp_exchg_msg_value *kvp_data;char *key_name; +char *value;struct icmsg_hdr *icmsghdrp;int keylen =0 ;int valuelen =0 ;u32 buf_len;struct vmbus_channel *channel;u64 req_id; +int ret;/* * If a transaction is not active; log and return.
@@ -376,6 +495,16 @@ kvp_respond_to_host(char *key, char *value, int error) sizeof(struct icmsg_hdr)];switch (kvp_transaction.kvp_msg->kvp_hdr.operation) { +case KVP_OP_GET_IP_INFO : + ret =process_ob_ipinfo (msg_to_host, + (struct hv_kvp_ip_msg *)kvp_msg, +KVP_OP_GET_IP_INFO ); +if (ret <0 ) + icmsghdrp->status =HV_E_FAIL ; + + goto response_done; +case KVP_OP_SET_IP_INFO : + goto response_done;case KVP_OP_GET : kvp_data = &kvp_msg->body.kvp_get.data; goto copy_value;
@@ -389,7 +518,7 @@ kvp_respond_to_host(char *key, char *value, int error) } kvp_data = &kvp_msg->body.kvp_enum_data.data; - key_name = key; + key_name = msg_to_host->body.kvp_enum_data.data.key;/* * The windows host expects the key/value pair to be encoded
@@ -403,6 +532,7 @@ kvp_respond_to_host(char *key, char *value, int error) kvp_data->key_size =2 *(keylen +1 );/* utf16 encoding */ copy_value: + value = msg_to_host->body.kvp_enum_data.data.value; valuelen =utf8s_to_utf16s (value,strlen (value),UTF16_HOST_ENDIAN , (wchar_t *) kvp_data->value, (HV_KVP_EXCHANGE_MAX_VALUE_SIZE /2 ) -2 );
@@ -455,7 +585,8 @@ void hv_kvp_onchannelcallback(void *context)return ; } -vmbus_recvpacket (channel, recv_buffer,PAGE_SIZE , &recvlen, &requestid); +vmbus_recvpacket (channel, recv_buffer,PAGE_SIZE *2 , &recvlen, + &requestid);if (recvlen >0 ) { icmsghdrp = (struct icmsg_hdr *)&recv_buffer[
Signature · 1 line
1.7.4.1
Re: [PATCH V2 04/18] Drivers: hv: kvp: Support the new IP injection messages
drivers/hv/hv_kvp.c kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) · line 309
Quoted 9 lines · K. Y. Srinivasan
drivers/hv/hv_kvp.c +9
-0+default : +utf16s_to_utf8s ((wchar_t *)in->kvp_ip_val.adapter_id, +MAX_ADAPTER_ID_SIZE , +UTF16_LITTLE_ENDIAN , + (__u8 *)out->body.kvp_ip_val.adapter_id, +MAX_ADAPTER_ID_SIZE ); + + out->body.kvp_ip_val.addr_family = + in->kvp_ip_val.addr_family;
That's some wierd indenting, did you really mean to do that?
greg k-h
PATCH v2 5/18 Tools: hv: Prepare to expand kvp_get_ip_address() functionality
In reply to K. Y. Srinivasankvp_get_ip_address() implemented the functionality to retrieve IP address info. Make this function more generic so that we could retrieve additional per-interface information.
--- tools/hv/hv_kvp_daemon.c | 129 ++++++++++++++++++++++++++++++---------------- 1 files changed, 84 insertions(+), 45 deletions(-)
tools/hv/hv_kvp_daemon.c +84 -45
@@ -492,7 +492,8 @@ done: }static int -kvp_get_ip_address (int family,char *buffer,int length) +kvp_get_ip_address (int family,char *if_name,int op, +void *out_buffer,int length) {struct ifaddrs *ifap;struct ifaddrs *curp;
@@ -502,10 +503,19 @@ kvp_get_ip_address(int family, char *buffer, int length)const char *str;char tmp[50 ];int error =0 ; - +char *buffer; +struct hv_kvp_ipaddr_value *ip_buffer; + +if (op ==KVP_OP_ENUMERATE ) { + buffer = out_buffer; + }else { + ip_buffer = out_buffer; + buffer = (char *)ip_buffer->ip_addr; + ip_buffer->addr_family =0 ; + }/* * On entry into this function, the buffer is capable of holding the -* maximum key value (2048 bytes). +* maximum key value. */ if (getifaddrs (&ifap)) {
@@ -515,58 +525,87 @@ kvp_get_ip_address(int family, char *buffer, int length) curp = ifap;while (curp !=NULL ) { -if ((curp->ifa_addr !=NULL ) && - (curp->ifa_addr->sa_family == family)) { -if (family ==AF_INET ) { -struct sockaddr_in *addr = - (struct sockaddr_in *) curp->ifa_addr; - - str =inet_ntop (family, &addr->sin_addr, - tmp,50 ); -if (str ==NULL ) { -strcpy (buffer,"inet_ntop failed\n" ); - error =1 ; - goto getaddr_done; - } -if (offset ==0 ) -strcpy (buffer, tmp); -else -strcat (buffer, tmp); -strcat (buffer,";" ); +if (curp->ifa_addr ==NULL ) { + curp = curp->ifa_next; +continue ; + } - offset +=strlen (str) +1 ; -if ((length - offset) < (ipv4_len +1 )) - goto getaddr_done; +if ((if_name !=NULL ) && + (strncmp (curp->ifa_name, if_name,strlen (if_name)))) { +/* +* We want info about a specific interface; +* just continue. +*/ + curp = curp->ifa_next; +continue ; + } - }else { +/* +* We only support two address families: AF_INET and AF_INET6. +* If a family value of 0 is specified, we collect both +* supported address families; if not we gather info on +* the specified address family. +*/ +if ((family !=0 ) && (curp->ifa_addr->sa_family != family)) { + curp = curp->ifa_next; +continue ; + } +if ((curp->ifa_addr->sa_family !=AF_INET ) && + (curp->ifa_addr->sa_family !=AF_INET6 )) { + curp = curp->ifa_next; +continue ; + } + +if ((curp->ifa_addr->sa_family ==AF_INET ) && + ((family ==AF_INET ) || (family ==0 ))) { +struct sockaddr_in *addr = + (struct sockaddr_in *) curp->ifa_addr; + + str =inet_ntop (AF_INET , &addr->sin_addr, tmp,50 ); +if (str ==NULL ) { +strcpy (buffer,"inet_ntop failed\n" ); + error =1 ; + goto getaddr_done; + } +if (offset ==0 ) +strcpy (buffer, tmp); +else +strcat (buffer, tmp); +strcat (buffer,";" ); + + offset +=strlen (str) +1 ; +if ((length - offset) < (ipv4_len +1 )) + goto getaddr_done; + + }else if ((family ==AF_INET6 ) || (family ==0 )) {/* * We only support AF_INET and AF_INET6 * and the list of addresses is separated by a ";". */ -struct sockaddr_in6 *addr = +struct sockaddr_in6 *addr = (struct sockaddr_in6 *) curp->ifa_addr; - str =inet_ntop (family, + str =inet_ntop (AF_INET6 , &addr->sin6_addr.s6_addr, tmp,50 ); -if (str ==NULL ) { -strcpy (buffer,"inet_ntop failed\n" ); - error =1 ; - goto getaddr_done; - } -if (offset ==0 ) -strcpy (buffer, tmp); -else -strcat (buffer, tmp); -strcat (buffer,";" ); - offset +=strlen (str) +1 ; -if ((length - offset) < (ipv6_len +1 )) - goto getaddr_done; - +if (str ==NULL ) { +strcpy (buffer,"inet_ntop failed\n" ); + error =1 ; + goto getaddr_done; } +if (offset ==0 ) +strcpy (buffer, tmp); +else +strcat (buffer, tmp); +strcat (buffer,";" ); + offset +=strlen (str) +1 ; +if ((length - offset) < (ipv6_len +1 )) + goto getaddr_done; } + + curp = curp->ifa_next; }
@@ -811,13 +850,13 @@ int main(void)strcpy (key_value, lic_version);break ;case NetworkAddressIPv4: -kvp_get_ip_address (AF_INET , key_value, -HV_KVP_EXCHANGE_MAX_VALUE_SIZE ); +kvp_get_ip_address (AF_INET ,NULL ,KVP_OP_ENUMERATE , + key_value,HV_KVP_EXCHANGE_MAX_VALUE_SIZE );strcpy (key_name,"NetworkAddressIPv4" );break ;case NetworkAddressIPv6: -kvp_get_ip_address (AF_INET6 , key_value, -HV_KVP_EXCHANGE_MAX_VALUE_SIZE ); +kvp_get_ip_address (AF_INET6 ,NULL ,KVP_OP_ENUMERATE , + key_value,HV_KVP_EXCHANGE_MAX_VALUE_SIZE );strcpy (key_name,"NetworkAddressIPv6" );break ;case OSBuildNumber:
Signature · 1 line
1.7.4.1
PATCH v2 6/18 Tools: hv: Further refactor kvp_get_ip_address()
In reply to K. Y. SrinivasanIn preparation for making kvp_get_ip_address() more generic, factor out the code for handling IP addresses.
--- tools/hv/hv_kvp_daemon.c | 94 ++++++++++++++++++++------------------------- 1 files changed, 42 insertions(+), 52 deletions(-)
tools/hv/hv_kvp_daemon.c +42 -52
@@ -491,17 +491,50 @@ done:return ; } +static int kvp_process_ip_address (void *addrp, +int family,char *buffer, +int length,int *offset) +{ +struct sockaddr_in *addr; +struct sockaddr_in6 *addr6; +int addr_length; +char tmp[50 ]; +const char *str; + +if (family ==AF_INET ) { + addr = (struct sockaddr_in *)addrp; + str =inet_ntop (family, &addr->sin_addr, tmp,50 ); + addr_length =INET_ADDRSTRLEN ; + }else { + addr6 = (struct sockaddr_in6 *)addrp; + str =inet_ntop (family, &addr6->sin6_addr.s6_addr, tmp,50 ); + addr_length =INET6_ADDRSTRLEN ; + } + +if ((length - *offset) < addr_length +1 ) +return 1 ; +if (str ==NULL ) { +strcpy (buffer,"inet_ntop failed\n" ); +return 1 ; + } +if (*offset ==0 ) +strcpy (buffer, tmp); +else +strcat (buffer, tmp); +strcat (buffer,";" ); + + *offset +=strlen (str) +1 ; +return 0 ; +} +static int kvp_get_ip_address (int family,char *if_name,int op,void *out_buffer,int length) {struct ifaddrs *ifap;struct ifaddrs *curp; -int ipv4_len =strlen ("255.255.255.255" ) +1 ; -int ipv6_len =strlen ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" )+1 ;int offset =0 ;const char *str; -char tmp[50 ];int error =0 ;char *buffer;struct hv_kvp_ipaddr_value *ip_buffer;
@@ -556,55 +589,12 @@ kvp_get_ip_address(int family, char *if_name, int op,continue ; } -if ((curp->ifa_addr->sa_family ==AF_INET ) && - ((family ==AF_INET ) || (family ==0 ))) { -struct sockaddr_in *addr = - (struct sockaddr_in *) curp->ifa_addr; - - str =inet_ntop (AF_INET , &addr->sin_addr, tmp,50 ); -if (str ==NULL ) { -strcpy (buffer,"inet_ntop failed\n" ); - error =1 ; - goto getaddr_done; - } -if (offset ==0 ) -strcpy (buffer, tmp); -else -strcat (buffer, tmp); -strcat (buffer,";" ); - - offset +=strlen (str) +1 ; -if ((length - offset) < (ipv4_len +1 )) - goto getaddr_done; - - }else if ((family ==AF_INET6 ) || (family ==0 )) { - -/* -* We only support AF_INET and AF_INET6 -* and the list of addresses is separated by a ";". -*/ -struct sockaddr_in6 *addr = - (struct sockaddr_in6 *) curp->ifa_addr; - - str =inet_ntop (AF_INET6 , - &addr->sin6_addr.s6_addr, - tmp,50 ); -if (str ==NULL ) { -strcpy (buffer,"inet_ntop failed\n" ); - error =1 ; - goto getaddr_done; - } -if (offset ==0 ) -strcpy (buffer, tmp); -else -strcat (buffer, tmp); -strcat (buffer,";" ); - offset +=strlen (str) +1 ; -if ((length - offset) < (ipv6_len +1 )) - goto getaddr_done; - - } - + error =kvp_process_ip_address (curp->ifa_addr, + curp->ifa_addr->sa_family, + buffer, + length, &offset); +if (error) + goto getaddr_done; curp = curp->ifa_next; }
Signature · 1 line
1.7.4.1
Re: [PATCH V2 06/18] Tools: hv: Further refactor kvp_get_ip_address()
Quoted 7 lines · K. Y. Srinivasan
In preparation for making
kvp_get_ip_address()more generic, factor out the code for handling IP addresses.Signed-off-by K. Y. Srinivasan <[email protected]>Reviewed-by Haiyang Zhang <[email protected]>Reviewed-by Olaf Hering <[email protected]>Reviewed-by Ben Hutchings <[email protected]>
I looked at your last patch set, so in a sense these have been reviewed by me. But the 'Reviewed-by' line in a commit message means the reviewer thinks it's OK; the reviewer must say that, and I didn't.
Ben.
Quoted 124 lines
--- tools/hv/hv_kvp_daemon.c | 94 ++++++++++++++++++++------------------------- 1 files changed, 42 insertions(+), 52 deletions(-)tools/hv/hv_kvp_daemon.c +42
-52@@ -491,17 +491,50 @@ done:return ; } +static int kvp_process_ip_address (void *addrp, +int family,char *buffer, +int length,int *offset) +{ +struct sockaddr_in *addr; +struct sockaddr_in6 *addr6; +int addr_length; +char tmp[50 ]; +const char *str; + +if (family ==AF_INET ) { + addr = (struct sockaddr_in *)addrp; + str =inet_ntop (family, &addr->sin_addr, tmp,50 ); + addr_length =INET_ADDRSTRLEN ; + }else { + addr6 = (struct sockaddr_in6 *)addrp; + str =inet_ntop (family, &addr6->sin6_addr.s6_addr, tmp,50 ); + addr_length =INET6_ADDRSTRLEN ; + } + +if ((length - *offset) < addr_length +1 ) +return 1 ; +if (str ==NULL ) { +strcpy (buffer,"inet_ntop failed\n" ); +return 1 ; + } +if (*offset ==0 ) +strcpy (buffer, tmp); +else +strcat (buffer, tmp); +strcat (buffer,";" ); + + *offset +=strlen (str) +1 ; +return 0 ; +} +static int kvp_get_ip_address (int family,char *if_name,int op,void *out_buffer,int length) {struct ifaddrs *ifap;struct ifaddrs *curp; -int ipv4_len =strlen ("255.255.255.255" ) +1 ; -int ipv6_len =strlen ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" )+1 ;int offset =0 ;const char *str; -char tmp[50 ];int error =0 ;char *buffer;struct hv_kvp_ipaddr_value *ip_buffer;@@ -556,55 +589,12 @@ kvp_get_ip_address(int family, char *if_name, int op,continue ; } -if ((curp->ifa_addr->sa_family ==AF_INET ) && - ((family ==AF_INET ) || (family ==0 ))) { -struct sockaddr_in *addr = - (struct sockaddr_in *) curp->ifa_addr; - - str =inet_ntop (AF_INET , &addr->sin_addr, tmp,50 ); -if (str ==NULL ) { -strcpy (buffer,"inet_ntop failed\n" ); - error =1 ; - goto getaddr_done; - } -if (offset ==0 ) -strcpy (buffer, tmp); -else -strcat (buffer, tmp); -strcat (buffer,";" ); - - offset +=strlen (str) +1 ; -if ((length - offset) < (ipv4_len +1 )) - goto getaddr_done; - - }else if ((family ==AF_INET6 ) || (family ==0 )) { - -/* -* We only support AF_INET and AF_INET6 -* and the list of addresses is separated by a ";". -*/ -struct sockaddr_in6 *addr = - (struct sockaddr_in6 *) curp->ifa_addr; - - str =inet_ntop (AF_INET6 , - &addr->sin6_addr.s6_addr, - tmp,50 ); -if (str ==NULL ) { -strcpy (buffer,"inet_ntop failed\n" ); - error =1 ; - goto getaddr_done; - } -if (offset ==0 ) -strcpy (buffer, tmp); -else -strcat (buffer, tmp); -strcat (buffer,";" ); - offset +=strlen (str) +1 ; -if ((length - offset) < (ipv6_len +1 )) - goto getaddr_done; - - } - + error =kvp_process_ip_address (curp->ifa_addr, + curp->ifa_addr->sa_family, + buffer, + length, &offset); +if (error) + goto getaddr_done; curp = curp->ifa_next; }
Signature · 2 lines
Ben Hutchings I say we take off; nuke the site from orbit. It's the only way to be sure.
RE: [PATCH V2 06/18] Tools: hv: Further refactor kvp_get_ip_address()
Quoted 15 lines
-----Original Message-----
From: Ben Hutchings [mailto:[email protected]]
Sent: Monday, August 13, 2012 9:46 PM
To: KY Srinivasan
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH V2 06/18] Tools: hv: Further refactorkvp_get_ip_address()Quoted 3 lines · K. Y. Srinivasan
In preparation for making
kvp_get_ip_address()more generic, factor out the code for handling IP addresses.
Quoted 8 lines
Quoted 4 lines
Signed-off-by K. Y. Srinivasan <[email protected]>Reviewed-by Haiyang Zhang <[email protected]>Reviewed-by Olaf Hering <[email protected]>Reviewed-by Ben Hutchings <[email protected]>I looked at your last patch set, so in a sense these have been reviewed by me. But the 'Reviewed-by' line in a commit message means the reviewer thinks it's OK; the reviewer must say that, and I didn't.
My mistake, sorry about that.
Regards,
K. Y
PATCH v2 7/18 Tools: hv: Gather address family information
In reply to K. Y. SrinivasanNow, gather address family information for the specified interface.
--- tools/hv/hv_kvp_daemon.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
tools/hv/hv_kvp_daemon.c +11 -0
@@ -589,6 +589,17 @@ kvp_get_ip_address(int family, char *if_name, int op,continue ; } +if (op ==KVP_OP_GET_IP_INFO ) { +/* +* Gather info other than the IP address. +* IP address info will be gathered later. +*/ +if (curp->ifa_addr->sa_family ==AF_INET ) + ip_buffer->addr_family |=ADDR_FAMILY_IPV4 ; +else + ip_buffer->addr_family |=ADDR_FAMILY_IPV6 ; + } + error = kvp_process_ip_address(curp->ifa_addr, curp->ifa_addr->sa_family, buffer,
Signature · 1 line
1.7.4.1
PATCH v2 8/18 Tools: hv: Gather subnet information
In reply to K. Y. SrinivasanNow, gather sub-net information for the specified interface.
--- tools/hv/hv_kvp_daemon.c | 31 +++++++++++++++++++++++++++++-- 1 files changed, 29 insertions(+), 2 deletions(-)
tools/hv/hv_kvp_daemon.c +29 -2
@@ -534,6 +534,7 @@ kvp_get_ip_address(int family, char *if_name, int op,struct ifaddrs *ifap;struct ifaddrs *curp;int offset =0 ; +int sn_offset =0 ;const char *str;int error =0 ;char *buffer;
@@ -594,12 +595,38 @@ kvp_get_ip_address(int family, char *if_name, int op,* Gather info other than the IP address. * IP address info will be gathered later. */ -if (curp->ifa_addr->sa_family ==AF_INET ) +if (curp->ifa_addr->sa_family ==AF_INET ) { ip_buffer->addr_family |=ADDR_FAMILY_IPV4 ; -else +/* +* Get subnet info. +*/ + error =kvp_process_ip_address ( + curp->ifa_netmask, +AF_INET , + (char *) + ip_buffer->sub_net, + length, + &sn_offset); +if (error) + goto gather_ipaddr; + }else { ip_buffer->addr_family |=ADDR_FAMILY_IPV6 ; +/* +* Get subnet info. +*/ + error =kvp_process_ip_address ( + curp->ifa_netmask, +AF_INET6 , + (char *) + ip_buffer->sub_net, + length, + &sn_offset); +if (error) + goto gather_ipaddr; + } } +gather_ipaddr: error = kvp_process_ip_address(curp->ifa_addr, curp->ifa_addr->sa_family, buffer,
Signature · 1 line
1.7.4.1
PATCH v2 9/18 Tools: hv: Represent the ipv6 mask using CIDR notation
In reply to K. Y. SrinivasanTransform ipv6 subnet information to CIDR notation.
--- tools/hv/hv_kvp_daemon.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 files changed, 36 insertions(+), 10 deletions(-)
tools/hv/hv_kvp_daemon.c +36 -10
@@ -491,6 +491,15 @@ done:return ; } +static unsigned int hweight32 (unsigned int *w) +{ +unsigned int res = *w - ((*w >>1 ) &0x55555555 ); + res = (res &0x33333333 ) + ((res >>2 ) &0x33333333 ); + res = (res + (res >>4 )) &0x0F0F0F0F ; + res = res + (res >>8 ); +return (res + (res >>16 )) &0x000000FF ; +} +static int kvp_process_ip_address (void *addrp,int family,char *buffer,int length,int *offset)
@@ -535,10 +544,15 @@ kvp_get_ip_address(int family, char *if_name, int op,struct ifaddrs *curp;int offset =0 ;int sn_offset =0 ; -const char *str;int error =0 ;char *buffer;struct hv_kvp_ipaddr_value *ip_buffer; +char cidr_mask[5 ];/* /xyz */ +int weight; +int i; +unsigned int *w; +char *sn_str; +struct sockaddr_in6 *addr6;if (op ==KVP_OP_ENUMERATE ) { buffer = out_buffer;
@@ -611,18 +625,30 @@ kvp_get_ip_address(int family, char *if_name, int op, goto gather_ipaddr; }else { ip_buffer->addr_family |=ADDR_FAMILY_IPV6 ; +/* -* Get subnet info. +* Get subnet info in CIDR format. */ - error =kvp_process_ip_address ( - curp->ifa_netmask, -AF_INET6 , - (char *) - ip_buffer->sub_net, - length, - &sn_offset); -if (error) + weight =0 ; + sn_str = (char *)ip_buffer->sub_net; + addr6 = (struct sockaddr_in6 *) + curp->ifa_netmask; + w = addr6->sin6_addr.s6_addr32; + +for (i =0 ; i <4 ; i++) + weight +=hweight32 (&w[i]); + +sprintf (cidr_mask,"/%d" , weight); +if ((length - sn_offset) < + (strlen (cidr_mask) +1 )) goto gather_ipaddr; + +if (sn_offset ==0 ) +strcpy (sn_str, cidr_mask); +else +strcat (sn_str, cidr_mask); +strcat ((char *)ip_buffer->sub_net,";" ); + sn_offset +=strlen (sn_str) +1 ; } }
Signature · 1 line
1.7.4.1
PATCH v2 10/18 Tools: hv: Gather ipv[4,6] gateway information
In reply to K. Y. SrinivasanGather information on the default gateways - ipv4/ipv6.
--- tools/hv/hv_kvp_daemon.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 68 insertions(+), 0 deletions(-)
tools/hv/hv_kvp_daemon.c +68 -0
@@ -491,6 +491,68 @@ done:return ; } +static void kvp_process_ipconfig_file (char *cmd, +char *config_buf,int len, +int element_size,int offset) +{ +char buf[256 ]; +char *p; +char *x; +FILE *file; + +/* +* First execute the command. +*/ + file =popen (cmd,"r" ); +if (file ==NULL ) +return ; + +if (offset ==0 ) +memset (config_buf,0 , len); +while ((p =fgets (buf,sizeof (buf), file)) !=NULL ) { +if ((len -strlen (config_buf)) < (element_size +1 )) +break ; + + x =strchr (p,'\n' ); + *x ='\0' ; +strcat (config_buf, p); +strcat (config_buf,";" ); + } +pclose (file); +} + +static void kvp_get_ipconfig_info (char *if_name, +struct hv_kvp_ipaddr_value *buffer) +{ +char cmd[512 ]; + +/* +* Get the address of default gateway (ipv4). +*/ +sprintf (cmd,"%s %s" ,"ip route show dev" , if_name); +strcat (cmd," | awk '/default/ {print $3 }'" ); + +/* +* Execute the command to gather gateway info. +*/ +kvp_process_ipconfig_file (cmd, (char *)buffer->gate_way, + (MAX_GATEWAY_SIZE *2 ),INET_ADDRSTRLEN ,0 ); + +/* +* Get the address of default gateway (ipv6). +*/ +sprintf (cmd,"%s %s" ,"ip -f inet6 route show dev" , if_name); +strcat (cmd," | awk '/default/ {print $3 }'" ); + +/* +* Execute the command to gather gateway info (ipv6). +*/ +kvp_process_ipconfig_file (cmd, (char *)buffer->gate_way, + (MAX_GATEWAY_SIZE *2 ),INET6_ADDRSTRLEN ,1 ); + +} + +static unsigned int hweight32 (unsigned int *w) {unsigned int res = *w - ((*w >>1 ) &0x55555555 );
@@ -650,6 +712,12 @@ kvp_get_ip_address(int family, char *if_name, int op,strcat ((char *)ip_buffer->sub_net,";" ); sn_offset +=strlen (sn_str) +1 ; } + +/* +* Collect other ip related configuration info. +*/ + +kvp_get_ipconfig_info (if_name, ip_buffer); } gather_ipaddr:
Signature · 1 line
1.7.4.1
PATCH v2 11/18 Tools: hv: Gather DNS information
In reply to K. Y. SrinivasanNow, gather DNS information. Invoke an external script (that can be distro dependent) to gather the DNS information.
--- tools/hv/hv_kvp_daemon.c | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-)
tools/hv/hv_kvp_daemon.c +23 -0
@@ -550,6 +550,29 @@ static void kvp_get_ipconfig_info(char *if_name,kvp_process_ipconfig_file (cmd, (char *)buffer->gate_way, (MAX_GATEWAY_SIZE *2 ),INET6_ADDRSTRLEN ,1 ); + +/* +* Gather the DNS state. +* Since there is no standard way to get this information +* across various distributions of interest; we just invoke +* an external script that needs to be ported across distros +* of interest. +* +* Following is the expected format of the information from the script: +* +* ipaddr1 (nameserver1) +* ipaddr2 (nameserver2) +* . +* . +*/ + +sprintf (cmd,"%s" ,"hv_get_dns_info" ); + +/* +* Execute the command to gather DNS info. +*/ +kvp_process_ipconfig_file (cmd, (char *)buffer->dns_addr, + (MAX_IP_ADDR_SIZE *2 ),INET_ADDRSTRLEN ,0 ); }
Signature · 1 line
1.7.4.1
PATCH v2 12/18 Tools: hv: Gather DHCP information
In reply to K. Y. SrinivasanCollect information on dhcp setting for the specified interface. We invoke an external script to get this information.
--- tools/hv/hv_kvp_daemon.c | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-)
tools/hv/hv_kvp_daemon.c +31 -0
@@ -525,6 +525,9 @@ static void kvp_get_ipconfig_info(char *if_name, struct hv_kvp_ipaddr_value *buffer) {char cmd[512 ]; +char dhcp_info[128 ]; +char *p; +FILE *file;/* * Get the address of default gateway (ipv4).
@@ -573,6 +576,34 @@ static void kvp_get_ipconfig_info(char *if_name,*/ kvp_process_ipconfig_file (cmd, (char *)buffer->dns_addr, (MAX_IP_ADDR_SIZE *2 ),INET_ADDRSTRLEN ,0 ); + +/* +* Gather the DHCP state. +* We will gather this state by invoking an external script. +* The parameter to the script is the interface name. +* Here is the expected output: +* +* Enabled: DHCP enabled. +*/ + +sprintf (cmd,"%s %s" ,"hv_get_dhcp_info" , if_name); + + file =popen (cmd,"r" ); +if (file ==NULL ) +return ; + + p =fgets (dhcp_info,sizeof (dhcp_info), file); +if (p ==NULL ) { +pclose (file); +return ; + } + +if (!strncmp (p,"Enabled" ,7 )) + buffer->dhcp_enabled =1 ; +else + buffer->dhcp_enabled =0 ; + +pclose (file); }
Signature · 1 line
1.7.4.1
PATCH v2 13/18 Tools: hv: Implement the KVP verb - KVP_OP_SET_IP_INFO
In reply to K. Y. SrinivasanImplement the KVP verb - KVP_OP_SET_IP_INFO. This operation configures the specified interface based on the given configuration. Since configuring an interface is very distro specific, we invoke an external script to configure the interface.
--- include/linux/hyperv.h | 2 + tools/hv/hv_kvp_daemon.c | 443 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 445 insertions(+), 0 deletions(-)
include/linux/hyperv.h +2 -0
@@ -191,6 +191,8 @@ enum hv_kvp_exchg_pool {#define HV_ERROR_NOT_SUPPORTED 0x80070032#define HV_ERROR_MACHINE_LOCKED 0x800704F7#define HV_ERROR_DEVICE_NOT_CONNECTED 0x8007048F +#define HV_INVALIDARG 0x80070057 +#define HV_GUID_NOTFOUND 0x80041002#define ADDR_FAMILY_NONE 0x00#define ADDR_FAMILY_IPV4 0x01
tools/hv/hv_kvp_daemon.c +443 -0
491 lines not on this page · raw message
Signature · 1 line
1.7.4.1
PATCH v2 14/18 Tools: hv: Rename the function kvp_get_ip_address()
In reply to K. Y. SrinivasanRename the function kvp_get_ip_address() to better reflect the functionality being implemented.
--- tools/hv/hv_kvp_daemon.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
tools/hv/hv_kvp_daemon.c +3 -3
@@ -766,7 +766,7 @@ static int kvp_process_ip_address(void *addrp, }static int -kvp_get_ip_address (int family,char *if_name,int op, +kvp_get_ip_info (int family,char *if_name,int op,void *out_buffer,int length) {struct ifaddrs *ifap;
@@ -1469,12 +1469,12 @@ int main(void)strcpy (key_value, lic_version);break ;case NetworkAddressIPv4: -kvp_get_ip_address (AF_INET ,NULL ,KVP_OP_ENUMERATE , +kvp_get_ip_info (AF_INET ,NULL ,KVP_OP_ENUMERATE , key_value,HV_KVP_EXCHANGE_MAX_VALUE_SIZE );strcpy (key_name,"NetworkAddressIPv4" );break ;case NetworkAddressIPv6: -kvp_get_ip_address (AF_INET6 ,NULL ,KVP_OP_ENUMERATE , +kvp_get_ip_info (AF_INET6 ,NULL ,KVP_OP_ENUMERATE , key_value,HV_KVP_EXCHANGE_MAX_VALUE_SIZE );strcpy (key_name,"NetworkAddressIPv6" );break ;
Signature · 1 line
1.7.4.1
PATCH v2 15/18 Tools: hv: Implement the KVP verb - KVP_OP_GET_IP_INFO
In reply to K. Y. SrinivasanNow implement the KVP verb - KVP_OP_GET_IP_INFO. This operation retrieves IP information for the specified interface.
--- tools/hv/hv_kvp_daemon.c | 93 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 90 insertions(+), 3 deletions(-)
tools/hv/hv_kvp_daemon.c +90 -3
@@ -604,6 +604,69 @@ static char *kvp_if_name_to_mac(char *if_name) } +/* +* Retrieve the interface name given tha MAC address. +*/ + +static char *kvp_mac_to_if_name (char *mac) +{ +DIR *dir; +struct dirent *entry; +FILE *file; +char *p, *q, *x; +char *if_name =NULL ; +char buf[256 ]; +char *kvp_net_dir ="/sys/class/net/" ; +char dev_id[256 ]; +int i; + + dir =opendir (kvp_net_dir); +if (dir ==NULL ) +return NULL ; + +snprintf (dev_id,sizeof (dev_id), kvp_net_dir); + q = dev_id +strlen (kvp_net_dir); + +while ((entry =readdir (dir)) !=NULL ) { +/* +* Set the state for the next pass. +*/ + *q ='\0' ; + +strcat (dev_id, entry->d_name); +strcat (dev_id,"/address" ); + + file =fopen (dev_id,"r" ); +if (file ==NULL ) +continue ; + + p =fgets (buf,sizeof (buf), file); +if (p) { + x =strchr (p,'\n' ); +if (x) + *x ='\0' ; + +for (i =0 ; i <strlen (p); i++) + p[i] =toupper (p[i]); + +if (!strcmp (p, mac)) { +/* +* Found the MAC match; return the interface +* name. The caller will free the memory. +*/ + if_name =strdup (entry->d_name); +fclose (file); +break ; + } + } +fclose (file); + } + +closedir (dir); +return if_name; +} + +static void kvp_process_ipconfig_file (char *cmd,char *config_buf,int len,int element_size,int offset)
@@ -750,10 +813,10 @@ static int kvp_process_ip_address(void *addrp, }if ((length - *offset) < addr_length +1 ) -return 1 ; +return HV_E_FAIL ;if (str ==NULL ) {strcpy (buffer,"inet_ntop failed\n" ); -return 1 ; +return HV_E_FAIL ; }if (*offset ==0 )strcpy (buffer, tmp);
@@ -797,7 +860,7 @@ kvp_get_ip_info(int family, char *if_name, int op,if (getifaddrs (&ifap)) {strcpy (buffer,"getifaddrs failed\n" ); -return 1 ; +return HV_E_FAIL ; } curp = ifap;
@@ -1387,6 +1450,30 @@ int main(void) }switch (op) { +case KVP_OP_GET_IP_INFO : + kvp_ip_val = &hv_msg->body.kvp_ip_val; + if_name = +kvp_mac_to_if_name ((char *)kvp_ip_val->adapter_id); + +if (if_name ==NULL ) { +/* +* We could not map the mac address to an +* interface name; return error. +*/ + hv_msg->error =HV_E_FAIL ; +break ; + } + error =kvp_get_ip_info ( +0 , if_name,KVP_OP_GET_IP_INFO , + kvp_ip_val, + (MAX_IP_ADDR_SIZE *2 )); + +if (error) + hv_msg->error = error; + +free (if_name); +break ; +case KVP_OP_SET_IP_INFO : kvp_ip_val = &hv_msg->body.kvp_ip_val; if_name = kvp_get_if_name(
Signature · 1 line
1.7.4.1
PATCH v2 16/18 Tools: hv: Get rid of some unused variables
In reply to K. Y. SrinivasanGet rid of unused variables. I would like to thank Ben Hutchings for pointing out the issue ([email protected]).
--- tools/hv/hv_kvp_daemon.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
tools/hv/hv_kvp_daemon.c +1 -2
@@ -211,7 +211,7 @@ static void kvp_update_mem_state(int pool) }static int kvp_file_init (void ) { -int ret, fd; +int fd;FILE *filep;size_t records_read;__u8 *fname;
@@ -327,7 +327,6 @@ static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value, int value_size) {int i; -int j, k;int num_records;struct kvp_record *record;int num_blocks;
Signature · 1 line
1.7.4.1
PATCH v2 17/18 Tools: hv: Correctly type string variables
In reply to K. Y. SrinivasanCorrectly type character strings. I would like to thank Ben Hutchings for pointing out the issue ([email protected]).
--- tools/hv/hv_kvp_daemon.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
tools/hv/hv_kvp_daemon.c +4 -4
@@ -101,8 +101,8 @@ static struct utsname uts_buf;#define ENTRIES_PER_BLOCK 50struct kvp_record { -__u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE ]; -__u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE ]; +char key[HV_KVP_EXCHANGE_MAX_KEY_SIZE ]; +char value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE ]; };struct kvp_file_state {
@@ -110,7 +110,7 @@ struct kvp_file_state {int num_blocks;struct kvp_record *records;int num_records; -__u8 fname[MAX_FILE_NAME ]; +char fname[MAX_FILE_NAME ]; };static struct kvp_file_state kvp_file_info[KVP_POOL_COUNT ];
@@ -214,7 +214,7 @@ static int kvp_file_init(void)int fd;FILE *filep;size_t records_read; -__u8 *fname; +char *fname;struct kvp_record *record;struct kvp_record *readp;int num_blocks;
Signature · 1 line
1.7.4.1
PATCH v2 18/18 Tools: hv: Properly manage open streams
In reply to K. Y. SrinivasanClose the open streams properly.
--- tools/hv/hv_kvp_daemon.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
tools/hv/hv_kvp_daemon.c +2 -2
@@ -160,7 +160,7 @@ static void kvp_update_file(int pool)sizeof (struct kvp_record ), kvp_file_info[pool].num_records, filep); -fflush (filep); +fclose (filep);kvp_release_lock (pool); }
@@ -206,7 +206,7 @@ static void kvp_update_mem_state(int pool) kvp_file_info[pool].num_blocks = num_blocks; kvp_file_info[pool].records = record; kvp_file_info[pool].num_records = records_read; - +fclose (filep);kvp_release_lock (pool); }static int kvp_file_init (void )
Signature · 1 line
1.7.4.1
Re: [PATCH V2 18/18] Tools: hv: Properly manage open streams
Quoted 6 lines · K. Y. Srinivasan
Close the open streams properly.
Signed-off-by K. Y. Srinivasan <[email protected]>Reviewed-by Haiyang Zhang <[email protected]>Reviewed-by Olaf Hering <[email protected]>Reviewed-by Ben Hutchings <[email protected]>
This isn't reviewed by me, I'm the author!
Ben.
Quoted 26 lines
--- tools/hv/hv_kvp_daemon.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)tools/hv/hv_kvp_daemon.c +2
-2@@ -160,7 +160,7 @@ static void kvp_update_file(int pool)sizeof (struct kvp_record ), kvp_file_info[pool].num_records, filep); -fflush (filep); +fclose (filep);kvp_release_lock (pool); }@@ -206,7 +206,7 @@ static void kvp_update_mem_state(int pool) kvp_file_info[pool].num_blocks = num_blocks; kvp_file_info[pool].records = record; kvp_file_info[pool].num_records = records_read; - +fclose (filep);kvp_release_lock (pool); }static int kvp_file_init (void )
Signature · 2 lines
Ben Hutchings I say we take off; nuke the site from orbit. It's the only way to be sure.
RE: [PATCH V2 18/18] Tools: hv: Properly manage open streams
Quoted 12 lines
-----Original Message-----
From: Ben Hutchings [mailto:[email protected]]
Sent: Monday, August 13, 2012 9:58 PM
To: KY Srinivasan
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH V2 18/18] Tools: hv: Properly manage open streamsOn Mon, 2012-08-13 at 10:07 -0700, K. Y. Srinivasan wrote:
Quoted 8 lines
Quoted 6 lines
Close the open streams properly.
Signed-off-by K. Y. Srinivasan <[email protected]>Reviewed-by Haiyang Zhang <[email protected]>Reviewed-by Olaf Hering <[email protected]>Reviewed-by Ben Hutchings <[email protected]>This isn't reviewed by me, I'm the author!
I am truly sorry for this confusion. I was cleaning up the code based on the last set of comments I got from Olaf and I did not realize that you had authored this very patch! Perhaps we can drop this patch from this set.
Regards,
K. Y
Quoted 33 lines
Ben.
Quoted 18 lines
--- tools/hv/hv_kvp_daemon.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)tools/hv/hv_kvp_daemon.c +1
-1@@ -160,7 +160,7 @@ static void kvp_update_file(int pool)sizeof (struct kvp_record ), kvp_file_info[pool].num_records, filep); -fflush (filep); +fclose (filep);kvp_release_lock (pool); }tools/hv/hv_kvp_daemon.c static void kvp_update_mem_state(int pool) · line 212
Quoted 8 lines
tools/hv/hv_kvp_daemon.c +1
-1@@ -206,7 +206,7 @@ static void kvp_update_mem_state(int pool) kvp_file_info[pool].num_blocks = num_blocks; kvp_file_info[pool].records = record; kvp_file_info[pool].num_records = records_read; - +fclose (filep);kvp_release_lock (pool); }static int kvp_file_init (void )--
Ben Hutchings
I say we take off; nuke the site from orbit. It's the only way to be sure.
Quoted 21 lines · K. Y. Srinivasan
This patchset expands the KVP (Key Value Pair) functionality to implement the mechanism to GET/SET IP addresses in the guest. This functionality is used in Windows Server 2012 to implement VM replication functionality. The way IP configuration information is managed is distro specific. Based on the feedback I have gotten from Olaf, Greg, Steve, Ben and Mairus, I have chosen to seperate distro specific code from this patch-set. Most of the GET operation can be implemented in a way that is completely distro independent and I have implemented that as such and is included in this patch-set. Some of the attributes that can only be fetched in a distro dependent way as well the mechanism for configuring an interface (the SET operation) that is clearly distro specific is to be implemented via external scripts that will be invoked via the KVP code. We define here the interface to these scripts.
Adding support for IP injection resulted in some changes to the protocol between the user level daemon and the kernel driver. These changes have been implemented in way that would retain compatibility with older daemons. I would like to thank Olaf and Greg for pointing out the compatibility issue.
Quoted 7 lines
This version of the patch set addresses all of the comments that I have received to date from Olaf, Ben and others. Specifically, I have cleanedup all of the string manipulation code. Furthermore, I have also simplified the format of the interface configuration file that is generated by the KVP daemon and gotten rid of some constant strings that may not be relevant on all distros. I would like to thank Olaf and Ben for their detailed review.
I've applied some of these, care to resend the rest, with the change I pointed out, and get the reviewed-by: lines correct.
thanks,
greg k-h
Quoted 41 lines
-----Original Message-----
From: Greg KH [mailto:[email protected]]
Sent: Thursday, August 16, 2012 4:55 PM
To: KY Srinivasan
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [PATCH V2 00/18] drivers: hv: kvpQuoted 21 lines · K. Y. Srinivasan
This patchset expands the KVP (Key Value Pair) functionality to implement the mechanism to GET/SET IP addresses in the guest. This functionality is used in Windows Server 2012 to implement VM replication functionality. The way IP configuration information is managed is distro specific. Based on the feedback I have gotten from Olaf, Greg, Steve, Ben and Mairus, I have chosen to seperate distro specific code from this patch-set. Most of the GET operation can be implemented in a way that is completely distro independent and I have implemented that as such and is included in this patch-set. Some of the attributes that can only be fetched in a distro dependent way as well the mechanism for configuring an interface (the SET operation) that is clearly distro specific is to be implemented via external scripts that will be invoked via the KVP code. We define here the interface to these scripts.
Adding support for IP injection resulted in some changes to the protocol between the user level daemon and the kernel driver. These changes have been implemented in way that would retain compatibility with older daemons. I would like to thank Olaf and Greg for pointing out the compatibility issue.
Quoted 7 lines
This version of the patch set addresses all of the comments that I have received to date from Olaf, Ben and others. Specifically, I have cleanedup all of the string manipulation code. Furthermore, I have also simplified the format of the interface configuration file that is generated by the KVP daemon and gotten rid of some constant strings that may not be relevant on all distros. I would like to thank Olaf and Ben for their detailed review.
Quoted 2 lines
I've applied some of these, care to resend the rest, with the change I pointed out, and get the reviewed-by: lines correct.
Will do.
Thanks,
K. Y
Quoted 6 lines
thanks,
greg k-h