[kernel] r19194 - in dists/sid/linux-tools/debian: . build/tools build/tools/hv patches patches/hyperv-backport templates

Ben Hutchings benh at alioth.debian.org
Sun Jun 24 06:21:09 UTC 2012


Author: benh
Date: Sun Jun 24 06:21:06 2012
New Revision: 19194

Log:
[x86] Build hyperv-services package containing the Hyper-V Key Value Pair daemon

Added:
   dists/sid/linux-tools/debian/build/tools/hv/   (props changed)
   dists/sid/linux-tools/debian/build/tools/hv/Makefile
   dists/sid/linux-tools/debian/hyperv-services.hv_kvp_daemon.init
   dists/sid/linux-tools/debian/patches/hyperv-backport/
   dists/sid/linux-tools/debian/patches/hyperv-backport/0035-net-hyperv-Add-support-for-jumbo-frame-up-to-64KB.patch
   dists/sid/linux-tools/debian/patches/hyperv-backport/0042-net-hyperv-Fix-the-page-buffer-when-an-RNDIS-message.patch
   dists/sid/linux-tools/debian/patches/hyperv-backport/0043-drivers-hv-kvp-Add-cleanup-connector-defines.patch
   dists/sid/linux-tools/debian/patches/hyperv-backport/0044-drivers-hv-kvp-Move-the-contents-of-hv_kvp.h-to-hype.patch
   dists/sid/linux-tools/debian/patches/hyperv-backport/0063-drivers-hv-Cleanup-the-kvp-related-state-in-hyperv.h.patch
   dists/sid/linux-tools/debian/patches/hyperv-backport/0064-tools-hv-Use-hyperv.h-to-get-the-KVP-definitions.patch
   dists/sid/linux-tools/debian/patches/hyperv-backport/0065-drivers-hv-kvp-Cleanup-the-kernel-user-protocol.patch
   dists/sid/linux-tools/debian/patches/hyperv-backport/0071-Drivers-hv-Add-new-message-types-to-enhance-KVP.patch
   dists/sid/linux-tools/debian/patches/hyperv-backport/0073-Drivers-hv-Support-the-newly-introduced-KVP-messages.patch
   dists/sid/linux-tools/debian/patches/hyperv-backport/0074-Tools-hv-Fully-support-the-new-KVP-verbs-in-the-user.patch
   dists/sid/linux-tools/debian/patches/hyperv-backport/0075-Tools-hv-Support-enumeration-from-all-the-pools.patch
   dists/sid/linux-tools/debian/patches/tools-hv-add-basic-manual-pages.patch
   dists/sid/linux-tools/debian/patches/tools-hv-check-for-read-write-errors.patch
   dists/sid/linux-tools/debian/patches/tools-hv-fix-exit-error-code.patch
   dists/sid/linux-tools/debian/patches/tools-hv-fix-file-handle-leak.patch
   dists/sid/linux-tools/debian/patches/tools-hv-fix-permissions.patch
   dists/sid/linux-tools/debian/patches/tools-hv-fix-string-types.patch
   dists/sid/linux-tools/debian/patches/tools-hv-fix-var-subdirectory.patch
   dists/sid/linux-tools/debian/patches/tools-hv-parse-etc-os-release.patch
   dists/sid/linux-tools/debian/patches/tools-hv-remove-unused-variables.patch
   dists/sid/linux-tools/debian/patches/tools-hv-verify-origin-of-netlink-connector-message.patch
Modified:
   dists/sid/linux-tools/debian/build/tools/Makefile
   dists/sid/linux-tools/debian/changelog
   dists/sid/linux-tools/debian/patches/series
   dists/sid/linux-tools/debian/rules.real
   dists/sid/linux-tools/debian/templates/control.main.in

Modified: dists/sid/linux-tools/debian/build/tools/Makefile
==============================================================================
--- dists/sid/linux-tools/debian/build/tools/Makefile	Sun Jun 24 02:23:10 2012	(r19193)
+++ dists/sid/linux-tools/debian/build/tools/Makefile	Sun Jun 24 06:21:06 2012	(r19194)
@@ -1,4 +1,5 @@
 SUBDIRS = \
+	hv \
 	perf
 
 include ../Makefile.inc

Added: dists/sid/linux-tools/debian/build/tools/hv/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/build/tools/hv/Makefile	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,28 @@
+OUTDIR = tools/hv
+
+include ../../Makefile.inc
+
+DEB_HOST_ARCH_CPU := $(shell dpkg-architecture -qDEB_HOST_ARCH_CPU)
+
+ifneq ($(filter amd64 i386,$(DEB_HOST_ARCH_CPU)),)
+
+all: hv_kvp_daemon
+hv_kvp_daemon: $(top_srcdir)/tools/hv/hv_kvp_daemon.c
+	$(CC) $(CFLAGS) -I$(top_srcdir)/include $(LDFLAGS) $< -o $@
+
+install:
+	install -D hv_kvp_daemon $(DESTDIR)/usr/sbin/hv_kvp_daemon
+	install -D -m 644 $(top_srcdir)/tools/hv/hv_kvp_daemon.8 \
+		$(DESTDIR)/usr/share/man/man8/hv_kvp_daemon.8
+	install -d $(DESTDIR)/var/lib/hyperv
+
+clean:
+	rm -f hv_kvp_daemon
+
+else
+
+all:
+install:
+clean:
+
+endif

Modified: dists/sid/linux-tools/debian/changelog
==============================================================================
--- dists/sid/linux-tools/debian/changelog	Sun Jun 24 02:23:10 2012	(r19193)
+++ dists/sid/linux-tools/debian/changelog	Sun Jun 24 06:21:06 2012	(r19194)
@@ -1,3 +1,10 @@
+linux-tools (3.2.17-2) UNRELEASED; urgency=low
+
+  * [x86] Build hyperv-services package containing the Hyper-V
+    Key Value Pair daemon
+
+ -- Ben Hutchings <ben at decadent.org.uk>  Sun, 24 Jun 2012 06:20:33 +0100
+
 linux-tools (3.2.17-1) unstable; urgency=low
 
   * New upstream stable updates:

Added: dists/sid/linux-tools/debian/hyperv-services.hv_kvp_daemon.init
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/hyperv-services.hv_kvp_daemon.init	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,83 @@
+#!/bin/sh
+#
+### BEGIN INIT INFO
+# Provides:          hv_kvp_daemon
+# Required-Start:    $null
+# Should-Start:      $syslog $remote_fs $time
+# Required-Stop:     $null
+# Should-Stop:       $syslog $remote_fs $time
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: hv_kvp_daemon provides info to the host
+# Description:       Start hv_kvp_daemon to allow the host to query this guest
+### END INIT INFO
+
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+DESC="Hyper-V KVP daemon"
+NAME=hv_kvp_daemon
+DAEMON=/usr/sbin/$NAME
+SCRIPTNAME=/etc/init.d/$NAME
+
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
+
+. /lib/lsb/init-functions
+
+do_start()
+{
+	start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
+		|| return 1
+	start-stop-daemon --start --quiet --exec $DAEMON \
+		|| return 2
+}
+
+do_stop()
+{
+	start-stop-daemon --stop --quiet --exec $DAEMON --retry=TERM/30/KILL/5
+}
+
+case "$1" in
+  start)
+	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
+	do_start
+	case "$?" in
+		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+	esac
+	;;
+  stop)
+	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
+	do_stop
+	case "$?" in
+		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+	esac
+	;;
+  status)
+	status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
+	;;
+  restart|force-reload)
+	log_daemon_msg "Restarting $DESC" "$NAME"
+	do_stop
+	case "$?" in
+	  0|1)
+		do_start
+		case "$?" in
+			0) log_end_msg 0 ;;
+			1) log_end_msg 1 ;; # Old process is still running
+			*) log_end_msg 1 ;; # Failed to start
+		esac
+		;;
+	  *)
+		# Failed to stop
+		log_end_msg 1
+		;;
+	esac
+	;;
+  *)
+	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
+	exit 3
+	;;
+esac
+
+:

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0035-net-hyperv-Add-support-for-jumbo-frame-up-to-64KB.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0035-net-hyperv-Add-support-for-jumbo-frame-up-to-64KB.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,25 @@
+From: Haiyang Zhang <haiyangz at microsoft.com>
+Date: Thu, 15 Dec 2011 13:45:17 -0800
+Subject: [PATCH 35/77] net/hyperv: Add support for jumbo frame up to 64KB
+
+commit 4d447c9a6ebc0142d320f075c5bac6d202a79fd4 upstream.
+
+Allow the user set the MTU up to 65536 for Linux guests running on
+Hyper-V 2008 R2 or later.
+
+Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+[bwh: Restrict to include/]
+---
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -35,7 +35,7 @@
+ #include <linux/mod_devicetable.h>
+ 
+ 
+-#define MAX_PAGE_BUFFER_COUNT				16
++#define MAX_PAGE_BUFFER_COUNT				18
+ #define MAX_MULTIPAGE_BUFFER_COUNT			32 /* 128K */
+ 
+ #pragma pack(push, 1)

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0042-net-hyperv-Fix-the-page-buffer-when-an-RNDIS-message.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0042-net-hyperv-Fix-the-page-buffer-when-an-RNDIS-message.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,26 @@
+From: Haiyang Zhang <haiyangz at microsoft.com>
+Date: Thu, 2 Feb 2012 07:18:00 +0000
+Subject: [PATCH 42/77] net/hyperv: Fix the page buffer when an RNDIS message
+ goes beyond page boundary
+
+commit c31c151b1c4a29da4dc92212aa8648fb4f8557b9 upstream.
+
+There is a possible data corruption if an RNDIS message goes beyond page
+boundary in the sending code path. This patch fixes the problem.
+
+Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+[bwh: Restrict to include/]
+---
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -35,7 +35,7 @@
+ #include <linux/mod_devicetable.h>
+ 
+ 
+-#define MAX_PAGE_BUFFER_COUNT				18
++#define MAX_PAGE_BUFFER_COUNT				19
+ #define MAX_MULTIPAGE_BUFFER_COUNT			32 /* 128K */
+ 
+ #pragma pack(push, 1)

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0043-drivers-hv-kvp-Add-cleanup-connector-defines.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0043-drivers-hv-kvp-Add-cleanup-connector-defines.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,43 @@
+From: "K. Y. Srinivasan" <kys at microsoft.com>
+Date: Fri, 27 Jan 2012 15:55:57 -0800
+Subject: [PATCH 43/77] drivers: hv: kvp: Add/cleanup connector defines
+
+commit 4f03a2c934894f30a64d397df8c7c4de129c5b30 upstream.
+
+The current KVP code carries some private connector related defines.
+Update connector.h to have all the KVP defines. As part of this patch
+get rid of some unused defines.
+
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+[bwh: Restrict to include/, tools/]
+---
+--- a/include/linux/connector.h
++++ b/include/linux/connector.h
+@@ -43,6 +43,7 @@
+ #define CN_IDX_DRBD			0x8
+ #define CN_VAL_DRBD			0x1
+ #define CN_KVP_IDX			0x9	/* HyperV KVP */
++#define CN_KVP_VAL			0x1	/* queries from the kernel */
+ 
+ #define CN_NETLINK_USERS		10	/* Highest index + 1 */
+ 
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -40,15 +40,11 @@
+ #include <syslog.h>
+ 
+ /*
+- * KYS: TODO. Need to register these in the kernel.
+  *
+  * The following definitions are shared with the in-kernel component; do not
+  * change any of this without making the corresponding changes in
+  * the KVP kernel component.
+  */
+-#define CN_KVP_IDX		0x9     /* MSFT KVP functionality */
+-#define CN_KVP_VAL		0x1 /* This supports queries from the kernel */
+-#define CN_KVP_USER_VAL		0x2 /* This supports queries from the user  */
+ 
+ /*
+  * KVP protocol: The user mode component first registers with the

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0044-drivers-hv-kvp-Move-the-contents-of-hv_kvp.h-to-hype.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0044-drivers-hv-kvp-Move-the-contents-of-hv_kvp.h-to-hype.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,195 @@
+From: "K. Y. Srinivasan" <kys at microsoft.com>
+Date: Fri, 27 Jan 2012 15:55:58 -0800
+Subject: [PATCH 44/77] drivers: hv: kvp: Move the contents of hv_kvp.h to
+ hyperv.h
+
+commit 2939437ce8f2de07237eb2bcce29b6a699bfe799 upstream.
+
+In preparation for consolidating all KVP related defines into a single header file
+that both the kernel and user level components can use, move the contents of
+hv_kvp.h into hyperv.h.
+
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+[bwh: Restrict to include/]
+---
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -25,6 +25,166 @@
+ #ifndef _HYPERV_H
+ #define _HYPERV_H
+ 
++#include <linux/types.h>
++
++/*
++ * An implementation of HyperV key value pair (KVP) functionality for Linux.
++ *
++ *
++ * Copyright (C) 2010, Novell, Inc.
++ * Author : K. Y. Srinivasan <ksrinivasan at novell.com>
++ *
++ */
++
++/*
++ * Maximum value size - used for both key names and value data, and includes
++ * any applicable NULL terminators.
++ *
++ * Note:  This limit is somewhat arbitrary, but falls easily within what is
++ * supported for all native guests (back to Win 2000) and what is reasonable
++ * for the IC KVP exchange functionality.  Note that Windows Me/98/95 are
++ * limited to 255 character key names.
++ *
++ * MSDN recommends not storing data values larger than 2048 bytes in the
++ * registry.
++ *
++ * Note:  This value is used in defining the KVP exchange message - this value
++ * cannot be modified without affecting the message size and compatibility.
++ */
++
++/*
++ * bytes, including any null terminators
++ */
++#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE          (2048)
++
++
++/*
++ * Maximum key size - the registry limit for the length of an entry name
++ * is 256 characters, including the null terminator
++ */
++
++#define HV_KVP_EXCHANGE_MAX_KEY_SIZE            (512)
++
++/*
++ * In Linux, we implement the KVP functionality in two components:
++ * 1) The kernel component which is packaged as part of the hv_utils driver
++ * is responsible for communicating with the host and responsible for
++ * implementing the host/guest protocol. 2) A user level daemon that is
++ * responsible for data gathering.
++ *
++ * Host/Guest Protocol: The host iterates over an index and expects the guest
++ * to assign a key name to the index and also return the value corresponding to
++ * the key. The host will have atmost one KVP transaction outstanding at any
++ * given point in time. The host side iteration stops when the guest returns
++ * an error. Microsoft has specified the following mapping of key names to
++ * host specified index:
++ *
++ *	Index		Key Name
++ *	0		FullyQualifiedDomainName
++ *	1		IntegrationServicesVersion
++ *	2		NetworkAddressIPv4
++ *	3		NetworkAddressIPv6
++ *	4		OSBuildNumber
++ *	5		OSName
++ *	6		OSMajorVersion
++ *	7		OSMinorVersion
++ *	8		OSVersion
++ *	9		ProcessorArchitecture
++ *
++ * The Windows host expects the Key Name and Key Value to be encoded in utf16.
++ *
++ * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the
++ * data gathering functionality in a user mode daemon. The user level daemon
++ * is also responsible for binding the key name to the index as well. The
++ * kernel and user-level daemon communicate using a connector channel.
++ *
++ * The user mode component first registers with the
++ * the kernel component. Subsequently, the kernel component requests, data
++ * for the specified keys. In response to this message the user mode component
++ * fills in the value corresponding to the specified key. We overload the
++ * sequence field in the cn_msg header to define our KVP message types.
++ *
++ *
++ * The kernel component simply acts as a conduit for communication between the
++ * Windows host and the user-level daemon. The kernel component passes up the
++ * index received from the Host to the user-level daemon. If the index is
++ * valid (supported), the corresponding key as well as its
++ * value (both are strings) is returned. If the index is invalid
++ * (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 */
++};
++
++
++
++
++#ifdef __KERNEL__
++
++/*
++ * Registry value types.
++ */
++
++#define REG_SZ 1
++
++enum hv_kvp_exchg_op {
++	KVP_OP_GET = 0,
++	KVP_OP_SET,
++	KVP_OP_DELETE,
++	KVP_OP_ENUMERATE,
++	KVP_OP_COUNT /* Number of operations, must be last. */
++};
++
++enum hv_kvp_exchg_pool {
++	KVP_POOL_EXTERNAL = 0,
++	KVP_POOL_GUEST,
++	KVP_POOL_AUTO,
++	KVP_POOL_AUTO_EXTERNAL,
++	KVP_POOL_AUTO_INTERNAL,
++	KVP_POOL_COUNT /* Number of pools, must be last. */
++};
++
++struct hv_kvp_hdr {
++	u8 operation;
++	u8 pool;
++};
++
++struct hv_kvp_exchg_msg_value {
++	u32 value_type;
++	u32 key_size;
++	u32 value_size;
++	u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
++	u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
++};
++
++struct hv_kvp_msg_enumerate {
++	u32 index;
++	struct hv_kvp_exchg_msg_value data;
++};
++
++struct hv_kvp_msg {
++	struct hv_kvp_hdr	kvp_hdr;
++	struct hv_kvp_msg_enumerate	kvp_data;
++};
++
+ #include <linux/scatterlist.h>
+ #include <linux/list.h>
+ #include <linux/uuid.h>
+@@ -870,4 +1030,9 @@ struct hyperv_service_callback {
+ extern void vmbus_prep_negotiate_resp(struct icmsg_hdr *,
+ 				      struct icmsg_negotiate *, u8 *);
+ 
++int hv_kvp_init(struct hv_util_service *);
++void hv_kvp_deinit(void);
++void hv_kvp_onchannelcallback(void *);
++
++#endif /* __KERNEL__ */
+ #endif /* _HYPERV_H */

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0063-drivers-hv-Cleanup-the-kvp-related-state-in-hyperv.h.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0063-drivers-hv-Cleanup-the-kvp-related-state-in-hyperv.h.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,73 @@
+From: "K. Y. Srinivasan" <kys at microsoft.com>
+Date: Thu, 2 Feb 2012 16:56:48 -0800
+Subject: [PATCH 63/77] drivers: hv: Cleanup the kvp related state in hyperv.h
+
+commit 59a084a70afa0678bda2a23a7bc7cc59664945c7 upstream.
+
+Now cleanup the hyperv.h with regards to KVP definitions.
+
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ include/linux/hyperv.h |   27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index c445ead..dd0e3ee 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -137,7 +137,6 @@ struct hv_ku_msg {
+ 
+ 
+ 
+-#ifdef __KERNEL__
+ 
+ /*
+  * Registry value types.
+@@ -163,28 +162,30 @@ enum hv_kvp_exchg_pool {
+ };
+ 
+ struct hv_kvp_hdr {
+-	u8 operation;
+-	u8 pool;
+-};
++	__u8 operation;
++	__u8 pool;
++	__u16 pad;
++} __attribute__((packed));
+ 
+ struct hv_kvp_exchg_msg_value {
+-	u32 value_type;
+-	u32 key_size;
+-	u32 value_size;
+-	u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
+-	u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
+-};
++	__u32 value_type;
++	__u32 key_size;
++	__u32 value_size;
++	__u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
++	__u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
++} __attribute__((packed));
+ 
+ struct hv_kvp_msg_enumerate {
+-	u32 index;
++	__u32 index;
+ 	struct hv_kvp_exchg_msg_value data;
+-};
++} __attribute__((packed));
+ 
+ struct hv_kvp_msg {
+ 	struct hv_kvp_hdr	kvp_hdr;
+ 	struct hv_kvp_msg_enumerate	kvp_data;
+-};
++} __attribute__((packed));
+ 
++#ifdef __KERNEL__
+ #include <linux/scatterlist.h>
+ #include <linux/list.h>
+ #include <linux/uuid.h>
+-- 
+1.7.9.5
+

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0064-tools-hv-Use-hyperv.h-to-get-the-KVP-definitions.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0064-tools-hv-Use-hyperv.h-to-get-the-KVP-definitions.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,78 @@
+From: "K. Y. Srinivasan" <kys at microsoft.com>
+Date: Thu, 2 Feb 2012 16:56:49 -0800
+Subject: [PATCH 64/77] tools: hv: Use hyperv.h to get the KVP definitions
+
+commit eab6af71f0b83a7f62b9c48be5b2c0a82a86fad3 upstream.
+
+Now use hyperv.h to get the KVP defines in the KVP user-mode code.
+
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ tools/hv/hv_kvp_daemon.c |   28 +---------------------------
+ 1 file changed, 1 insertion(+), 27 deletions(-)
+
+diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
+index 2b6a2d9..b75523c 100644
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -34,17 +34,12 @@
+ #include <errno.h>
+ #include <arpa/inet.h>
+ #include <linux/connector.h>
++#include <linux/hyperv.h>
+ #include <linux/netlink.h>
+ #include <ifaddrs.h>
+ #include <netdb.h>
+ #include <syslog.h>
+ 
+-/*
+- *
+- * The following definitions are shared with the in-kernel component; do not
+- * change any of this without making the corresponding changes in
+- * the KVP kernel component.
+- */
+ 
+ /*
+  * KVP protocol: The user mode component first registers with the
+@@ -56,25 +51,8 @@
+  * We use this infrastructure for also supporting queries from user mode
+  * application for state that may be maintained in the KVP kernel component.
+  *
+- * XXXKYS: Have a shared header file between the user and kernel (TODO)
+  */
+ 
+-enum kvp_op {
+-	KVP_REGISTER = 0, /* Register the user mode component*/
+-	KVP_KERNEL_GET, /*Kernel is requesting the value for the specified key*/
+-	KVP_KERNEL_SET, /*Kernel is providing the value for the specified key*/
+-	KVP_USER_GET, /*User is requesting the value for the specified key*/
+-	KVP_USER_SET /*User is providing the value for the specified key*/
+-};
+-
+-#define HV_KVP_EXCHANGE_MAX_KEY_SIZE	512
+-#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE	2048
+-
+-struct hv_ku_msg {
+-	__u32	kvp_index;
+-	__u8  kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */
+-	__u8  kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key  value */
+-};
+ 
+ enum key_index {
+ 	FullyQualifiedDomainName = 0,
+@@ -89,10 +67,6 @@ enum key_index {
+ 	ProcessorArchitecture
+ };
+ 
+-/*
+- * End of shared definitions.
+- */
+-
+ static char kvp_send_buffer[4096];
+ static char kvp_recv_buffer[4096];
+ static struct sockaddr_nl addr;
+-- 
+1.7.9.5
+

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0065-drivers-hv-kvp-Cleanup-the-kernel-user-protocol.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0065-drivers-hv-kvp-Cleanup-the-kernel-user-protocol.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,145 @@
+From: "K. Y. Srinivasan" <kys at microsoft.com>
+Date: Thu, 2 Feb 2012 16:56:50 -0800
+Subject: [PATCH 65/77] drivers: hv: kvp: Cleanup the kernel/user protocol
+
+commit 2640335438ca4d7b139e114dae5f0d80e740e106 upstream.
+
+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 at microsoft.com>
+Signed-off-by: Haiyang Zhang <haiyangz at microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+[bwh: Restrict to include/, tools/]
+---
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -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__
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -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) {

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0071-Drivers-hv-Add-new-message-types-to-enhance-KVP.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0071-Drivers-hv-Add-new-message-types-to-enhance-KVP.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,75 @@
+From: "K. Y. Srinivasan" <kys at microsoft.com>
+Date: Sat, 10 Mar 2012 15:32:08 -0800
+Subject: [PATCH 71/77] Drivers: hv: Add new message types to enhance KVP
+
+commit e485ceac9ebd43901ef0ce13622385d509e072e7 upstream.
+
+Add additional KVP (Key Value Pair) protocol  messages to
+enhance KVP functionality for Linux guests on Hyper-V. As part of this,
+patch define an explicit version negoitiation message.
+
+Reviewed-by: Haiyang Zhang <haiyangz at microsoft.com>
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+[bwh: Restrict to include/, tools/]
+---
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -149,7 +149,11 @@ struct hv_kvp_exchg_msg_value {
+ 	__u32 key_size;
+ 	__u32 value_size;
+ 	__u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
+-	__u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
++	union {
++		__u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
++		__u32 value_u32;
++		__u64 value_u64;
++	};
+ } __attribute__((packed));
+ 
+ struct hv_kvp_msg_enumerate {
+@@ -157,11 +161,31 @@ struct hv_kvp_msg_enumerate {
+ 	struct hv_kvp_exchg_msg_value data;
+ } __attribute__((packed));
+ 
++struct hv_kvp_msg_get {
++	struct hv_kvp_exchg_msg_value data;
++};
++
++struct hv_kvp_msg_set {
++	struct hv_kvp_exchg_msg_value data;
++};
++
++struct hv_kvp_msg_delete {
++	__u32 key_size;
++	__u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
++};
++
++struct hv_kvp_register {
++	__u8 version[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
++};
++
+ struct hv_kvp_msg {
+ 	struct hv_kvp_hdr	kvp_hdr;
+ 	union {
+-		struct hv_kvp_msg_enumerate     kvp_enum_data;
+-		char    kvp_version[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
++		struct hv_kvp_msg_get		kvp_get;
++		struct hv_kvp_msg_set		kvp_set;
++		struct hv_kvp_msg_delete	kvp_delete;
++		struct hv_kvp_msg_enumerate	kvp_enum_data;
++		struct hv_kvp_register		kvp_register;
+ 	} body;
+ } __attribute__((packed));
+ 
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -378,7 +378,7 @@ int main(void)
+ 			 * Driver is registering with us; stash away the version
+ 			 * information.
+ 			 */
+-			p = (char *)hv_msg->body.kvp_version;
++			p = (char *)hv_msg->body.kvp_register.version;
+ 			lic_version = malloc(strlen(p) + 1);
+ 			if (lic_version) {
+ 				strcpy(lic_version, p);

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0073-Drivers-hv-Support-the-newly-introduced-KVP-messages.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0073-Drivers-hv-Support-the-newly-introduced-KVP-messages.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,58 @@
+From: "K. Y. Srinivasan" <kys at microsoft.com>
+Date: Fri, 16 Mar 2012 08:02:25 -0700
+Subject: [PATCH 73/77] Drivers: hv: Support the newly introduced KVP messages
+ in the driver
+
+commit fa3d5b85c681518b6e4ec515814dcb2d5b702b89 upstream.
+
+Support the newly defined KVP message types. It turns out that the host
+pushes a set of standard key value pairs as soon as the guest opens the KVP channel.
+Since we cannot handle these tuples until the user level daemon loads up, defer
+reading the KVP channel until the user level daemon is launched.
+
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Reviewed-by: Haiyang Zhang <haiyangz at microsoft.com>
+Reviewed-by: Dan Carpenter <dan.carpenter at oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+[bwh: Restrict to include/, tools/]
+---
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -119,6 +119,8 @@
+  */
+ 
+ #define REG_SZ 1
++#define REG_U32 4
++#define REG_U64 8
+ 
+ enum hv_kvp_exchg_op {
+ 	KVP_OP_GET = 0,
+diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
+index 00d3f7c..a98878c 100644
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -389,10 +389,16 @@ int main(void)
+ 			}
+ 			continue;
+ 
++		case KVP_OP_SET:
++		case KVP_OP_GET:
++		case KVP_OP_DELETE:
+ 		default:
+ 			break;
+ 		}
+ 
++		if (hv_msg->kvp_hdr.operation != KVP_OP_ENUMERATE)
++			goto kvp_done;
++
+ 		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;
+@@ -454,6 +460,7 @@ int main(void)
+ 		 * already in the receive buffer. Update the cn_msg header to
+ 		 * reflect the key value that has been added to the message
+ 		 */
++kvp_done:
+ 
+ 		incoming_cn_msg->id.idx = CN_KVP_IDX;
+ 		incoming_cn_msg->id.val = CN_KVP_VAL;

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0074-Tools-hv-Fully-support-the-new-KVP-verbs-in-the-user.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0074-Tools-hv-Fully-support-the-new-KVP-verbs-in-the-user.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,339 @@
+From: "K. Y. Srinivasan" <kys at microsoft.com>
+Date: Fri, 16 Mar 2012 08:02:26 -0700
+Subject: [PATCH 74/77] Tools: hv: Fully support the new KVP verbs in the user
+ level daemon
+
+commit db425334e5bb7fa65bbbd7bea9d79842f65bcf45 upstream.
+
+Now fully support the new KVP messages in the user level daemon. Hyper-V defines
+multiple persistent pools to which the host can write/read/modify KVP tuples.
+In this patch we implement a file for each specified pool, where the KVP tuples
+will be stored in the guest.
+
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Reviewed-by: Haiyang Zhang <haiyangz at microsoft.com>
+Reviewed-by: Dan Carpenter <dan.carpenter at oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ tools/hv/hv_kvp_daemon.c |  281 +++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 280 insertions(+), 1 deletion(-)
+
+diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
+index a98878c..2fb9c3d 100644
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -39,7 +39,8 @@
+ #include <ifaddrs.h>
+ #include <netdb.h>
+ #include <syslog.h>
+-
++#include <sys/stat.h>
++#include <fcntl.h>
+ 
+ /*
+  * KVP protocol: The user mode component first registers with the
+@@ -79,6 +80,250 @@ static char *os_build;
+ static char *lic_version;
+ static struct utsname uts_buf;
+ 
++
++#define MAX_FILE_NAME 100
++#define ENTRIES_PER_BLOCK 50
++
++struct kvp_record {
++	__u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
++	__u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
++};
++
++struct kvp_file_state {
++	int fd;
++	int num_blocks;
++	struct kvp_record *records;
++	int num_records;
++	__u8 fname[MAX_FILE_NAME];
++};
++
++static struct kvp_file_state kvp_file_info[KVP_POOL_COUNT];
++
++static void kvp_acquire_lock(int pool)
++{
++	struct flock fl = {F_WRLCK, SEEK_SET, 0, 0, 0};
++	fl.l_pid = getpid();
++
++	if (fcntl(kvp_file_info[pool].fd, F_SETLKW, &fl) == -1) {
++		syslog(LOG_ERR, "Failed to acquire the lock pool: %d", pool);
++		exit(-1);
++	}
++}
++
++static void kvp_release_lock(int pool)
++{
++	struct flock fl = {F_UNLCK, SEEK_SET, 0, 0, 0};
++	fl.l_pid = getpid();
++
++	if (fcntl(kvp_file_info[pool].fd, F_SETLK, &fl) == -1) {
++		perror("fcntl");
++		syslog(LOG_ERR, "Failed to release the lock pool: %d", pool);
++		exit(-1);
++	}
++}
++
++static void kvp_update_file(int pool)
++{
++	FILE *filep;
++	size_t bytes_written;
++
++	/*
++	 * We are going to write our in-memory registry out to
++	 * disk; acquire the lock first.
++	 */
++	kvp_acquire_lock(pool);
++
++	filep = fopen(kvp_file_info[pool].fname, "w");
++	if (!filep) {
++		kvp_release_lock(pool);
++		syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
++		exit(-1);
++	}
++
++	bytes_written = fwrite(kvp_file_info[pool].records,
++				sizeof(struct kvp_record),
++				kvp_file_info[pool].num_records, filep);
++
++	fflush(filep);
++	kvp_release_lock(pool);
++}
++
++static int kvp_file_init(void)
++{
++	int ret, fd;
++	FILE *filep;
++	size_t records_read;
++	__u8 *fname;
++	struct kvp_record *record;
++	struct kvp_record *readp;
++	int num_blocks;
++	int i;
++	int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK;
++
++	if (access("/var/opt/hyperv", F_OK)) {
++		if (mkdir("/var/opt/hyperv", S_IRUSR | S_IWUSR | S_IROTH)) {
++			syslog(LOG_ERR, " Failed to create /var/opt/hyperv");
++			exit(-1);
++		}
++	}
++
++	for (i = 0; i < KVP_POOL_COUNT; i++) {
++		fname = kvp_file_info[i].fname;
++		records_read = 0;
++		num_blocks = 1;
++		sprintf(fname, "/var/opt/hyperv/.kvp_pool_%d", i);
++		fd = open(fname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IROTH);
++
++		if (fd == -1)
++			return 1;
++
++
++		filep = fopen(fname, "r");
++		if (!filep)
++			return 1;
++
++		record = malloc(alloc_unit * num_blocks);
++		if (record == NULL) {
++			fclose(filep);
++			return 1;
++		}
++		while (!feof(filep)) {
++			readp = &record[records_read];
++			records_read += fread(readp, sizeof(struct kvp_record),
++					ENTRIES_PER_BLOCK,
++					filep);
++
++			if (!feof(filep)) {
++				/*
++				 * We have more data to read.
++				 */
++				num_blocks++;
++				record = realloc(record, alloc_unit *
++						num_blocks);
++				if (record == NULL) {
++					fclose(filep);
++					return 1;
++				}
++				continue;
++			}
++			break;
++		}
++		kvp_file_info[i].fd = fd;
++		kvp_file_info[i].num_blocks = num_blocks;
++		kvp_file_info[i].records = record;
++		kvp_file_info[i].num_records = records_read;
++		fclose(filep);
++
++	}
++
++	return 0;
++}
++
++static int kvp_key_delete(int pool, __u8 *key, int key_size)
++{
++	int i;
++	int j, k;
++	int num_records = kvp_file_info[pool].num_records;
++	struct kvp_record *record = kvp_file_info[pool].records;
++
++	for (i = 0; i < num_records; i++) {
++		if (memcmp(key, record[i].key, key_size))
++			continue;
++		/*
++		 * Found a match; just move the remaining
++		 * entries up.
++		 */
++		if (i == num_records) {
++			kvp_file_info[pool].num_records--;
++			kvp_update_file(pool);
++			return 0;
++		}
++
++		j = i;
++		k = j + 1;
++		for (; k < num_records; k++) {
++			strcpy(record[j].key, record[k].key);
++			strcpy(record[j].value, record[k].value);
++			j++;
++		}
++
++		kvp_file_info[pool].num_records--;
++		kvp_update_file(pool);
++		return 0;
++	}
++	return 1;
++}
++
++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 = kvp_file_info[pool].num_records;
++	struct kvp_record *record = kvp_file_info[pool].records;
++	int num_blocks = kvp_file_info[pool].num_blocks;
++
++	if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) ||
++		(value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE))
++		return 1;
++
++	for (i = 0; i < num_records; i++) {
++		if (memcmp(key, record[i].key, key_size))
++			continue;
++		/*
++		 * Found a match; just update the value -
++		 * this is the modify case.
++		 */
++		memcpy(record[i].value, value, value_size);
++		kvp_update_file(pool);
++		return 0;
++	}
++
++	/*
++	 * Need to add a new entry;
++	 */
++	if (num_records == (ENTRIES_PER_BLOCK * num_blocks)) {
++		/* Need to allocate a larger array for reg entries. */
++		record = realloc(record, sizeof(struct kvp_record) *
++			 ENTRIES_PER_BLOCK * (num_blocks + 1));
++
++		if (record == NULL)
++			return 1;
++		kvp_file_info[pool].num_blocks++;
++
++	}
++	memcpy(record[i].value, value, value_size);
++	memcpy(record[i].key, key, key_size);
++	kvp_file_info[pool].records = record;
++	kvp_file_info[pool].num_records++;
++	kvp_update_file(pool);
++	return 0;
++}
++
++static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
++			int value_size)
++{
++	int i;
++	int num_records = kvp_file_info[pool].num_records;
++	struct kvp_record *record = kvp_file_info[pool].records;
++
++	if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) ||
++		(value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE))
++		return 1;
++
++	for (i = 0; i < num_records; i++) {
++		if (memcmp(key, record[i].key, key_size))
++			continue;
++		/*
++		 * Found a match; just copy the value out.
++		 */
++		memcpy(value, record[i].value, value_size);
++		return 0;
++	}
++
++	return 1;
++}
++
+ void kvp_get_os_info(void)
+ {
+ 	FILE	*file;
+@@ -315,6 +560,11 @@ int main(void)
+ 	 */
+ 	kvp_get_os_info();
+ 
++	if (kvp_file_init()) {
++		syslog(LOG_ERR, "Failed to initialize the pools");
++		exit(-1);
++	}
++
+ 	fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
+ 	if (fd < 0) {
+ 		syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd);
+@@ -389,9 +639,38 @@ int main(void)
+ 			}
+ 			continue;
+ 
++		/*
++		 * The current protocol with the kernel component uses a
++		 * NULL key name to pass an error condition.
++		 * For the SET, GET and DELETE operations,
++		 * use the existing protocol to pass back error.
++		 */
++
+ 		case KVP_OP_SET:
++			if (kvp_key_add_or_modify(hv_msg->kvp_hdr.pool,
++					hv_msg->body.kvp_set.data.key,
++					hv_msg->body.kvp_set.data.key_size,
++					hv_msg->body.kvp_set.data.value,
++					hv_msg->body.kvp_set.data.value_size))
++				strcpy(hv_msg->body.kvp_set.data.key, "");
++			break;
++
+ 		case KVP_OP_GET:
++			if (kvp_get_value(hv_msg->kvp_hdr.pool,
++					hv_msg->body.kvp_set.data.key,
++					hv_msg->body.kvp_set.data.key_size,
++					hv_msg->body.kvp_set.data.value,
++					hv_msg->body.kvp_set.data.value_size))
++				strcpy(hv_msg->body.kvp_set.data.key, "");
++			break;
++
+ 		case KVP_OP_DELETE:
++			if (kvp_key_delete(hv_msg->kvp_hdr.pool,
++					hv_msg->body.kvp_delete.key,
++					hv_msg->body.kvp_delete.key_size))
++				strcpy(hv_msg->body.kvp_delete.key, "");
++			break;
++
+ 		default:
+ 			break;
+ 		}
+-- 
+1.7.9.5
+

Added: dists/sid/linux-tools/debian/patches/hyperv-backport/0075-Tools-hv-Support-enumeration-from-all-the-pools.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/hyperv-backport/0075-Tools-hv-Support-enumeration-from-all-the-pools.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,203 @@
+From: "K. Y. Srinivasan" <kys at microsoft.com>
+Date: Fri, 16 Mar 2012 08:02:27 -0700
+Subject: [PATCH 75/77] Tools: hv: Support enumeration from all the pools
+
+commit adc80ae60eae24a43a357bf5b30fb496f34aa605 upstream.
+
+We have only supported enumeration only from the AUTO pool. Now support
+enumeration from all the available pools.
+
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Reviewed-by: Haiyang Zhang <haiyangz at microsoft.com>
+Reviewed-by: Dan Carpenter <dan.carpenter at oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+[bwh: Restrict to include/, tools/]
+---
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -952,6 +952,7 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver);
+ 
+ #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
+ 
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -148,6 +148,51 @@ static void kvp_update_file(int pool)
+ 	kvp_release_lock(pool);
+ }
+ 
++static void kvp_update_mem_state(int pool)
++{
++	FILE *filep;
++	size_t records_read = 0;
++	struct kvp_record *record = kvp_file_info[pool].records;
++	struct kvp_record *readp;
++	int num_blocks = kvp_file_info[pool].num_blocks;
++	int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK;
++
++	kvp_acquire_lock(pool);
++
++	filep = fopen(kvp_file_info[pool].fname, "r");
++	if (!filep) {
++		kvp_release_lock(pool);
++		syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
++		exit(-1);
++	}
++	while (!feof(filep)) {
++		readp = &record[records_read];
++		records_read += fread(readp, sizeof(struct kvp_record),
++					ENTRIES_PER_BLOCK * num_blocks,
++					filep);
++
++		if (!feof(filep)) {
++			/*
++			 * We have more data to read.
++			 */
++			num_blocks++;
++			record = realloc(record, alloc_unit * num_blocks);
++
++			if (record == NULL) {
++				syslog(LOG_ERR, "malloc failed");
++				exit(-1);
++			}
++			continue;
++		}
++		break;
++	}
++
++	kvp_file_info[pool].num_blocks = num_blocks;
++	kvp_file_info[pool].records = record;
++	kvp_file_info[pool].num_records = records_read;
++
++	kvp_release_lock(pool);
++}
+ static int kvp_file_init(void)
+ {
+ 	int ret, fd;
+@@ -223,8 +268,16 @@ static int kvp_key_delete(int pool, __u8 *key, int key_size)
+ {
+ 	int i;
+ 	int j, k;
+-	int num_records = kvp_file_info[pool].num_records;
+-	struct kvp_record *record = kvp_file_info[pool].records;
++	int num_records;
++	struct kvp_record *record;
++
++	/*
++	 * First update the in-memory state.
++	 */
++	kvp_update_mem_state(pool);
++
++	num_records = kvp_file_info[pool].num_records;
++	record = kvp_file_info[pool].records;
+ 
+ 	for (i = 0; i < num_records; i++) {
+ 		if (memcmp(key, record[i].key, key_size))
+@@ -259,14 +312,23 @@ static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value,
+ {
+ 	int i;
+ 	int j, k;
+-	int num_records = kvp_file_info[pool].num_records;
+-	struct kvp_record *record = kvp_file_info[pool].records;
+-	int num_blocks = kvp_file_info[pool].num_blocks;
++	int num_records;
++	struct kvp_record *record;
++	int num_blocks;
+ 
+ 	if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) ||
+ 		(value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE))
+ 		return 1;
+ 
++	/*
++	 * First update the in-memory state.
++	 */
++	kvp_update_mem_state(pool);
++
++	num_records = kvp_file_info[pool].num_records;
++	record = kvp_file_info[pool].records;
++	num_blocks = kvp_file_info[pool].num_blocks;
++
+ 	for (i = 0; i < num_records; i++) {
+ 		if (memcmp(key, record[i].key, key_size))
+ 			continue;
+@@ -304,13 +366,21 @@ static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
+ 			int value_size)
+ {
+ 	int i;
+-	int num_records = kvp_file_info[pool].num_records;
+-	struct kvp_record *record = kvp_file_info[pool].records;
++	int num_records;
++	struct kvp_record *record;
+ 
+ 	if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) ||
+ 		(value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE))
+ 		return 1;
+ 
++	/*
++	 * First update the in-memory state.
++	 */
++	kvp_update_mem_state(pool);
++
++	num_records = kvp_file_info[pool].num_records;
++	record = kvp_file_info[pool].records;
++
+ 	for (i = 0; i < num_records; i++) {
+ 		if (memcmp(key, record[i].key, key_size))
+ 			continue;
+@@ -324,6 +394,31 @@ static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
+ 	return 1;
+ }
+ 
++static void kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
++				__u8 *value, int value_size)
++{
++	struct kvp_record *record;
++
++	/*
++	 * First update our in-memory database.
++	 */
++	kvp_update_mem_state(pool);
++	record = kvp_file_info[pool].records;
++
++	if (index >= kvp_file_info[pool].num_records) {
++		/*
++		 * This is an invalid index; terminate enumeration;
++		 * - a NULL value will do the trick.
++		 */
++		strcpy(value, "");
++		return;
++	}
++
++	memcpy(key, record[index].key, key_size);
++	memcpy(value, record[index].value, value_size);
++}
++
++
+ void kvp_get_os_info(void)
+ {
+ 	FILE	*file;
+@@ -678,6 +773,21 @@ int main(void)
+ 		if (hv_msg->kvp_hdr.operation != KVP_OP_ENUMERATE)
+ 			goto kvp_done;
+ 
++		/*
++		 * If the pool is KVP_POOL_AUTO, dynamically generate
++		 * both the key and the value; if not read from the
++		 * appropriate pool.
++		 */
++		if (hv_msg->kvp_hdr.pool != KVP_POOL_AUTO) {
++			kvp_pool_enumerate(hv_msg->kvp_hdr.pool,
++					hv_msg->body.kvp_enum_data.index,
++					hv_msg->body.kvp_enum_data.data.key,
++					HV_KVP_EXCHANGE_MAX_KEY_SIZE,
++					hv_msg->body.kvp_enum_data.data.value,
++					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
++			goto kvp_done;
++		}
++
+ 		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;

Modified: dists/sid/linux-tools/debian/patches/series
==============================================================================
--- dists/sid/linux-tools/debian/patches/series	Sun Jun 24 02:23:10 2012	(r19193)
+++ dists/sid/linux-tools/debian/patches/series	Sun Jun 24 06:21:06 2012	(r19194)
@@ -4,3 +4,24 @@
 usbip-update-man-pages.patch
 usbip-fix-explicit-configure-with-tcp-wrappers.patch
 usbip-document-tcp-wrappers.patch
+hyperv-backport/0035-net-hyperv-Add-support-for-jumbo-frame-up-to-64KB.patch
+hyperv-backport/0042-net-hyperv-Fix-the-page-buffer-when-an-RNDIS-message.patch
+hyperv-backport/0043-drivers-hv-kvp-Add-cleanup-connector-defines.patch
+hyperv-backport/0044-drivers-hv-kvp-Move-the-contents-of-hv_kvp.h-to-hype.patch
+hyperv-backport/0063-drivers-hv-Cleanup-the-kvp-related-state-in-hyperv.h.patch
+hyperv-backport/0064-tools-hv-Use-hyperv.h-to-get-the-KVP-definitions.patch
+hyperv-backport/0065-drivers-hv-kvp-Cleanup-the-kernel-user-protocol.patch
+hyperv-backport/0071-Drivers-hv-Add-new-message-types-to-enhance-KVP.patch
+hyperv-backport/0073-Drivers-hv-Support-the-newly-introduced-KVP-messages.patch
+hyperv-backport/0074-Tools-hv-Fully-support-the-new-KVP-verbs-in-the-user.patch
+hyperv-backport/0075-Tools-hv-Support-enumeration-from-all-the-pools.patch
+tools-hv-add-basic-manual-pages.patch
+tools-hv-fix-file-handle-leak.patch
+tools-hv-fix-exit-error-code.patch
+tools-hv-check-for-read-write-errors.patch
+tools-hv-fix-var-subdirectory.patch
+tools-hv-parse-etc-os-release.patch
+tools-hv-fix-string-types.patch
+tools-hv-remove-unused-variables.patch
+tools-hv-fix-permissions.patch
+tools-hv-verify-origin-of-netlink-connector-message.patch

Added: dists/sid/linux-tools/debian/patches/tools-hv-add-basic-manual-pages.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/tools-hv-add-basic-manual-pages.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,51 @@
+From fd95cbb27426acaa4dff3c91606dfd9c173172f3 Mon Sep 17 00:00:00 2001
+From: Andy Whitcroft <apw at canonical.com>
+Date: Fri, 6 Apr 2012 18:52:42 +0100
+Subject: [PATCH 2/2] UBUNTU: tools/hv: add basic manual pages
+
+BugLink: http://bugs.launchpad.net/bugs/977246
+
+Signed-off-by: Andy Whitcroft <apw at canonical.com>
+Acked-by: Leann Ogasawara <leann.ogasawara at canonical.com>
+Acked-by: Brad Figg <brad.figg at canonical.com>
+Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
+---
+ tools/hv/hv_kvp_daemon.8 |   26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+ create mode 100644 tools/hv/hv_kvp_daemon.8
+
+diff --git a/tools/hv/hv_kvp_daemon.8 b/tools/hv/hv_kvp_daemon.8
+new file mode 100644
+index 0000000..0fb4577
+--- /dev/null
++++ b/tools/hv/hv_kvp_daemon.8
+@@ -0,0 +1,26 @@
++.\"  This page Copyright (C) 2012 Andy Whitcroft <apw at canonical.com>
++.\"  Distributed under the GPL v2 or later.
++.TH HV_KVP_DAEMON 8
++.SH NAME
++hv_kvp_daemon \- Hyper-V Key Value Pair daemon
++.SH SYNOPSIS
++.ft B
++.B hv_kvp_daemon
++.br
++.SH DESCRIPTION
++\fBhv_kvp_daemon\fP
++is the userspace component of the Hyper-V key value pair functionality,
++communicating via a netlink socket with the kernel HV-KVP driver.
++This pairing allows the Hyper-V host to pass configuration information
++(such as IP addresses) to the guest and allows the host to obtain guest
++version information.
++
++.SH FILES
++.ta
++.nf
++/var/opt/hyperv/.kvp_pool_*
++.fi
++
++.SH AUTHORS
++.nf
++Written by K. Y. Srinivasan <ksrinivasan at novell.com>
+-- 
+1.7.10
+

Added: dists/sid/linux-tools/debian/patches/tools-hv-check-for-read-write-errors.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/tools-hv-check-for-read-write-errors.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,64 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Subject: tools/hv: Check for read/write errors
+
+hv_kvp_daemon currently does not check whether fread() or fwrite()
+succeed.  Add the necessary checks.  Also, remove the incorrect use of
+feof() before fread().
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -144,7 +144,12 @@
+ 				sizeof(struct kvp_record),
+ 				kvp_file_info[pool].num_records, filep);
+ 
+-	fclose(filep);
++	if (ferror(filep) || fclose(filep)) {
++		kvp_release_lock(pool);
++		syslog(LOG_ERR, "Failed to write file, pool: %d", pool);
++		exit(EXIT_FAILURE);
++	}
++
+ 	kvp_release_lock(pool);
+ }
+ 
+@@ -165,12 +170,17 @@
+ 		syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
+ 		exit(EXIT_FAILURE);
+ 	}
+-	while (!feof(filep)) {
++	for (;;) {
+ 		readp = &record[records_read];
+ 		records_read += fread(readp, sizeof(struct kvp_record),
+ 					ENTRIES_PER_BLOCK * num_blocks,
+ 					filep);
+ 
++		if (ferror(filep)) {
++			syslog(LOG_ERR, "Failed to read file, pool: %d", pool);
++			exit(EXIT_FAILURE);
++		}
++
+ 		if (!feof(filep)) {
+ 			/*
+ 			 * We have more data to read.
+@@ -233,12 +243,18 @@
+ 			fclose(filep);
+ 			return 1;
+ 		}
+-		while (!feof(filep)) {
++		for (;;) {
+ 			readp = &record[records_read];
+ 			records_read += fread(readp, sizeof(struct kvp_record),
+ 					ENTRIES_PER_BLOCK,
+ 					filep);
+ 
++			if (ferror(filep)) {
++				syslog(LOG_ERR, "Failed to read file, pool: %d",
++				       i);
++				exit(EXIT_FAILURE);
++			}
++
+ 			if (!feof(filep)) {
+ 				/*
+ 				 * We have more data to read.

Added: dists/sid/linux-tools/debian/patches/tools-hv-fix-exit-error-code.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/tools-hv-fix-exit-error-code.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,109 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Subject: tools/hv: Fix exit() error code
+
+Linux native exit codes are 8-bit unsigned values.  exit(-1) results
+in an exit code of 255, which is usually reserved for shells reporting
+'command not found'.  Use the portable value EXIT_FAILURE.  (Not that
+this matters much for a daemon.)
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -106,7 +106,7 @@
+ 
+ 	if (fcntl(kvp_file_info[pool].fd, F_SETLKW, &fl) == -1) {
+ 		syslog(LOG_ERR, "Failed to acquire the lock pool: %d", pool);
+-		exit(-1);
++		exit(EXIT_FAILURE);
+ 	}
+ }
+ 
+@@ -118,7 +118,7 @@
+ 	if (fcntl(kvp_file_info[pool].fd, F_SETLK, &fl) == -1) {
+ 		perror("fcntl");
+ 		syslog(LOG_ERR, "Failed to release the lock pool: %d", pool);
+-		exit(-1);
++		exit(EXIT_FAILURE);
+ 	}
+ }
+ 
+@@ -137,7 +137,7 @@
+ 	if (!filep) {
+ 		kvp_release_lock(pool);
+ 		syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
+-		exit(-1);
++		exit(EXIT_FAILURE);
+ 	}
+ 
+ 	bytes_written = fwrite(kvp_file_info[pool].records,
+@@ -163,7 +163,7 @@
+ 	if (!filep) {
+ 		kvp_release_lock(pool);
+ 		syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
+-		exit(-1);
++		exit(EXIT_FAILURE);
+ 	}
+ 	while (!feof(filep)) {
+ 		readp = &record[records_read];
+@@ -180,7 +180,7 @@
+ 
+ 			if (record == NULL) {
+ 				syslog(LOG_ERR, "malloc failed");
+-				exit(-1);
++				exit(EXIT_FAILURE);
+ 			}
+ 			continue;
+ 		}
+@@ -209,7 +209,7 @@
+ 	if (access("/var/opt/hyperv", F_OK)) {
+ 		if (mkdir("/var/opt/hyperv", S_IRUSR | S_IWUSR | S_IROTH)) {
+ 			syslog(LOG_ERR, " Failed to create /var/opt/hyperv");
+-			exit(-1);
++			exit(EXIT_FAILURE);
+ 		}
+ 	}
+ 
+@@ -658,13 +658,13 @@
+ 
+ 	if (kvp_file_init()) {
+ 		syslog(LOG_ERR, "Failed to initialize the pools");
+-		exit(-1);
++		exit(EXIT_FAILURE);
+ 	}
+ 
+ 	fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
+ 	if (fd < 0) {
+ 		syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd);
+-		exit(-1);
++		exit(EXIT_FAILURE);
+ 	}
+ 	addr.nl_family = AF_NETLINK;
+ 	addr.nl_pad = 0;
+@@ -676,7 +676,7 @@
+ 	if (error < 0) {
+ 		syslog(LOG_ERR, "bind failed; error:%d", error);
+ 		close(fd);
+-		exit(-1);
++		exit(EXIT_FAILURE);
+ 	}
+ 	sock_opt = addr.nl_groups;
+ 	setsockopt(fd, 270, 1, &sock_opt, sizeof(sock_opt));
+@@ -696,7 +696,7 @@
+ 	if (len < 0) {
+ 		syslog(LOG_ERR, "netlink_send failed; error:%d", len);
+ 		close(fd);
+-		exit(-1);
++		exit(EXIT_FAILURE);
+ 	}
+ 
+ 	pfd.fd = fd;
+@@ -860,7 +860,7 @@
+ 		len = netlink_send(fd, incoming_cn_msg);
+ 		if (len < 0) {
+ 			syslog(LOG_ERR, "net_link send failed; error:%d", len);
+-			exit(-1);
++			exit(EXIT_FAILURE);
+ 		}
+ 	}
+ 

Added: dists/sid/linux-tools/debian/patches/tools-hv-fix-file-handle-leak.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/tools-hv-fix-file-handle-leak.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,26 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Subject: tools/hv: Fix file handle leak
+
+Match up each fopen() with an fclose().
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -144,7 +144,7 @@
+ 				sizeof(struct kvp_record),
+ 				kvp_file_info[pool].num_records, filep);
+ 
+-	fflush(filep);
++	fclose(filep);
+ 	kvp_release_lock(pool);
+ }
+ 
+@@ -191,6 +191,7 @@
+ 	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)

Added: dists/sid/linux-tools/debian/patches/tools-hv-fix-permissions.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/tools-hv-fix-permissions.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,31 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Subject: tools/hv: Fix permissions of created directory and files
+
+It's silly to create directories without execute permission, or to
+give permissions to 'other' but not the group-owner.
+
+Write the permissions in octal and 'ls -l' format since these are much
+easier to read than the named macros.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -215,7 +215,7 @@
+ 	int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK;
+ 
+ 	if (access("/var/lib/hyperv", F_OK)) {
+-		if (mkdir("/var/lib/hyperv", S_IRUSR | S_IWUSR | S_IROTH)) {
++		if (mkdir("/var/lib/hyperv", 0755 /* rwxr-xr-x */)) {
+ 			syslog(LOG_ERR, " Failed to create /var/lib/hyperv");
+ 			exit(EXIT_FAILURE);
+ 		}
+@@ -226,7 +226,7 @@
+ 		records_read = 0;
+ 		num_blocks = 1;
+ 		sprintf(fname, "/var/lib/hyperv/.kvp_pool_%d", i);
+-		fd = open(fname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IROTH);
++		fd = open(fname, O_RDWR | O_CREAT, 0644 /* rw-r--r-- */);
+ 
+ 		if (fd == -1)
+ 			return 1;

Added: dists/sid/linux-tools/debian/patches/tools-hv-fix-string-types.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/tools-hv-fix-string-types.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,130 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Subject: tools/hv: Fix string types
+
+Standard C strings are arrays of char, not __u8 (unsigned char).
+Declare variables and parameters accordingly, and add the necessary
+casts.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -85,8 +85,8 @@
+ #define ENTRIES_PER_BLOCK 50
+ 
+ struct 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 {
+@@ -94,7 +94,7 @@
+ 	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];
+@@ -209,7 +209,7 @@
+ 	int ret, fd;
+ 	FILE *filep;
+ 	size_t records_read;
+-	__u8 *fname;
++	char *fname;
+ 	struct kvp_record *record;
+ 	struct kvp_record *readp;
+ 	int num_blocks;
+@@ -281,7 +281,7 @@
+ 	return 0;
+ }
+ 
+-static int kvp_key_delete(int pool, __u8 *key, int key_size)
++static int kvp_key_delete(int pool, const char *key, int key_size)
+ {
+ 	int i;
+ 	int j, k;
+@@ -324,8 +324,8 @@
+ 	return 1;
+ }
+ 
+-static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value,
+-			int value_size)
++static int kvp_key_add_or_modify(int pool, const char *key, int key_size,
++				 const char *value, int value_size)
+ {
+ 	int i;
+ 	int j, k;
+@@ -379,8 +379,8 @@
+ 	return 0;
+ }
+ 
+-static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
+-			int value_size)
++static int kvp_get_value(int pool, const char *key, int key_size,
++			 char *value, int value_size)
+ {
+ 	int i;
+ 	int num_records;
+@@ -411,8 +411,8 @@
+ 	return 1;
+ }
+ 
+-static void kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
+-				__u8 *value, int value_size)
++static void kvp_pool_enumerate(int pool, int index, char *key, int key_size,
++			       char *value, int value_size)
+ {
+ 	struct kvp_record *record;
+ 
+@@ -804,27 +804,27 @@
+ 
+ 		case KVP_OP_SET:
+ 			if (kvp_key_add_or_modify(hv_msg->kvp_hdr.pool,
+-					hv_msg->body.kvp_set.data.key,
++					(const char *)hv_msg->body.kvp_set.data.key,
+ 					hv_msg->body.kvp_set.data.key_size,
+-					hv_msg->body.kvp_set.data.value,
++					(const char *)hv_msg->body.kvp_set.data.value,
+ 					hv_msg->body.kvp_set.data.value_size))
+-				strcpy(hv_msg->body.kvp_set.data.key, "");
++				hv_msg->body.kvp_set.data.key[0] = 0;
+ 			break;
+ 
+ 		case KVP_OP_GET:
+ 			if (kvp_get_value(hv_msg->kvp_hdr.pool,
+-					hv_msg->body.kvp_set.data.key,
++					(const char *)hv_msg->body.kvp_set.data.key,
+ 					hv_msg->body.kvp_set.data.key_size,
+-					hv_msg->body.kvp_set.data.value,
++					(char *)hv_msg->body.kvp_set.data.value,
+ 					hv_msg->body.kvp_set.data.value_size))
+-				strcpy(hv_msg->body.kvp_set.data.key, "");
++				hv_msg->body.kvp_set.data.key[0] = 0;
+ 			break;
+ 
+ 		case KVP_OP_DELETE:
+ 			if (kvp_key_delete(hv_msg->kvp_hdr.pool,
+-					hv_msg->body.kvp_delete.key,
++					(const char *)hv_msg->body.kvp_delete.key,
+ 					hv_msg->body.kvp_delete.key_size))
+-				strcpy(hv_msg->body.kvp_delete.key, "");
++				hv_msg->body.kvp_delete.key[0] = 0;
+ 			break;
+ 
+ 		default:
+@@ -842,9 +842,9 @@
+ 		if (hv_msg->kvp_hdr.pool != KVP_POOL_AUTO) {
+ 			kvp_pool_enumerate(hv_msg->kvp_hdr.pool,
+ 					hv_msg->body.kvp_enum_data.index,
+-					hv_msg->body.kvp_enum_data.data.key,
++					(char *)hv_msg->body.kvp_enum_data.data.key,
+ 					HV_KVP_EXCHANGE_MAX_KEY_SIZE,
+-					hv_msg->body.kvp_enum_data.data.value,
++					(char *)hv_msg->body.kvp_enum_data.data.value,
+ 					HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
+ 			goto kvp_done;
+ 		}

Added: dists/sid/linux-tools/debian/patches/tools-hv-fix-var-subdirectory.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/tools-hv-fix-var-subdirectory.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,43 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Subject: tools/hv: Fix /var subdirectory
+
+We will install this in /usr, so it must use /var/lib for its state.
+Only programs installed under /opt should use /var/opt.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+--- a/tools/hv/hv_kvp_daemon.8
++++ b/tools/hv/hv_kvp_daemon.8
+@@ -18,7 +18,7 @@
+ .SH FILES
+ .ta
+ .nf
+-/var/opt/hyperv/.kvp_pool_*
++/var/lib/hyperv/.kvp_pool_*
+ .fi
+ 
+ .SH AUTHORS
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -216,9 +216,9 @@
+ 	int i;
+ 	int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK;
+ 
+-	if (access("/var/opt/hyperv", F_OK)) {
+-		if (mkdir("/var/opt/hyperv", S_IRUSR | S_IWUSR | S_IROTH)) {
+-			syslog(LOG_ERR, " Failed to create /var/opt/hyperv");
++	if (access("/var/lib/hyperv", F_OK)) {
++		if (mkdir("/var/lib/hyperv", S_IRUSR | S_IWUSR | S_IROTH)) {
++			syslog(LOG_ERR, " Failed to create /var/lib/hyperv");
+ 			exit(EXIT_FAILURE);
+ 		}
+ 	}
+@@ -227,7 +227,7 @@
+ 		fname = kvp_file_info[i].fname;
+ 		records_read = 0;
+ 		num_blocks = 1;
+-		sprintf(fname, "/var/opt/hyperv/.kvp_pool_%d", i);
++		sprintf(fname, "/var/lib/hyperv/.kvp_pool_%d", i);
+ 		fd = open(fname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IROTH);
+ 
+ 		if (fd == -1)

Added: dists/sid/linux-tools/debian/patches/tools-hv-parse-etc-os-release.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/tools-hv-parse-etc-os-release.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,74 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Subject: tools/hv: Parse /etc/os-release
+
+There is a new convention, used by systemd and supported by most
+distributions, to put basic OS release information in /etc/os-release.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -454,15 +454,59 @@
+ 	if (p)
+ 		*p = '\0';
+ 
++	/*
++	 * Parse the /etc/os-release file if present:
++	 * http://www.freedesktop.org/software/systemd/man/os-release.html
++	 */
++	file = fopen("/etc/os-release", "r");
++	if (file != NULL) {
++		while (fgets(buf, sizeof(buf), file)) {
++			char *value, *q;
++
++			/* Ignore comments */
++			if (buf[0] == '#')
++				continue;
++
++			/* Split into name=value */
++			p = strchr(buf, '=');
++			if (!p)
++				continue;
++			*p++ = 0;
++
++			/* Remove quotes and newline; un-escape */
++			value = p;
++			q = p;
++			while (*p) {
++				if (*p == '\\') {
++					++p;
++					if (!*p)
++						break;
++					*q++ = *p++;
++				} else if (*p == '\'' || *p == '"' ||
++					   *p == '\n') {
++					++p;
++				} else {
++					*q++ = *p++;
++				}
++			}
++			*q = 0;
++
++			if (!strcmp(buf, "NAME"))
++				os_name = strdup(value);
++			else if (!strcmp(buf, "VERSION_ID"))
++				os_major = strdup(value);
++		}
++		fclose(file);
++		return;
++	}
++
++	/* Fallback for older RH/SUSE releases */
+ 	file = fopen("/etc/SuSE-release", "r");
+ 	if (file != NULL)
+ 		goto kvp_osinfo_found;
+ 	file  = fopen("/etc/redhat-release", "r");
+ 	if (file != NULL)
+ 		goto kvp_osinfo_found;
+-	/*
+-	 * Add code for other supported platforms.
+-	 */
+ 
+ 	/*
+ 	 * We don't have information about the os.

Added: dists/sid/linux-tools/debian/patches/tools-hv-remove-unused-variables.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/tools-hv-remove-unused-variables.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,49 @@
+From: Ben Hutchings <ben at decadent.org.uk>
+Subject: tools/hv: Remove unused variables
+
+Several local variables are unused and appear to be copy-pasta.
+In kvp_update_file(), bytes_written is assigned but otherwise
+unused.  We use ferror() to check for write errors, so this is
+unneeded.
+
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -125,7 +125,6 @@
+ static void kvp_update_file(int pool)
+ {
+ 	FILE *filep;
+-	size_t bytes_written;
+ 
+ 	/*
+ 	 * We are going to write our in-memory registry out to
+@@ -140,9 +139,8 @@
+ 		exit(EXIT_FAILURE);
+ 	}
+ 
+-	bytes_written = fwrite(kvp_file_info[pool].records,
+-				sizeof(struct kvp_record),
+-				kvp_file_info[pool].num_records, filep);
++	fwrite(kvp_file_info[pool].records, sizeof(struct kvp_record),
++	       kvp_file_info[pool].num_records, filep);
+ 
+ 	if (ferror(filep) || fclose(filep)) {
+ 		kvp_release_lock(pool);
+@@ -206,7 +204,7 @@
+ }
+ static int kvp_file_init(void)
+ {
+-	int ret, fd;
++	int fd;
+ 	FILE *filep;
+ 	size_t records_read;
+ 	char *fname;
+@@ -328,7 +326,6 @@
+ 				 const char *value, int value_size)
+ {
+ 	int i;
+-	int j, k;
+ 	int num_records;
+ 	struct kvp_record *record;
+ 	int num_blocks;

Added: dists/sid/linux-tools/debian/patches/tools-hv-verify-origin-of-netlink-connector-message.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-tools/debian/patches/tools-hv-verify-origin-of-netlink-connector-message.patch	Sun Jun 24 06:21:06 2012	(r19194)
@@ -0,0 +1,47 @@
+From: Olaf Hering <olaf at aepfle.de>
+Date: Thu, 31 May 2012 16:40:06 +0200
+Subject: Tools: hv: verify origin of netlink connector message
+
+commit bcc2c9c3fff859e0eb019fe6fec26f9b8eba795c upstream.
+
+The SuSE security team suggested to use recvfrom instead of recv to be
+certain that the connector message is originated from kernel.
+
+CVE-2012-2669
+
+Signed-off-by: Olaf Hering <olaf at aepfle.de>
+Signed-off-by: Marcus Meissner <meissner at suse.de>
+Signed-off-by: Sebastian Krahmer <krahmer at suse.de>
+Signed-off-by: K. Y. Srinivasan <kys at microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
+---
+ tools/hv/hv_kvp_daemon.c |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
+index 146fd61..d9834b3 100644
+--- a/tools/hv/hv_kvp_daemon.c
++++ b/tools/hv/hv_kvp_daemon.c
+@@ -701,14 +701,18 @@ int main(void)
+ 	pfd.fd = fd;
+ 
+ 	while (1) {
++		struct sockaddr *addr_p = (struct sockaddr *) &addr;
++		socklen_t addr_l = sizeof(addr);
+ 		pfd.events = POLLIN;
+ 		pfd.revents = 0;
+ 		poll(&pfd, 1, -1);
+ 
+-		len = recv(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0);
++		len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0,
++				addr_p, &addr_l);
+ 
+-		if (len < 0) {
+-			syslog(LOG_ERR, "recv failed; error:%d", len);
++		if (len < 0 || addr.nl_pid) {
++			syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s",
++					addr.nl_pid, errno, strerror(errno));
+ 			close(fd);
+ 			return -1;
+ 		}

Modified: dists/sid/linux-tools/debian/rules.real
==============================================================================
--- dists/sid/linux-tools/debian/rules.real	Sun Jun 24 02:23:10 2012	(r19193)
+++ dists/sid/linux-tools/debian/rules.real	Sun Jun 24 06:21:06 2012	(r19194)
@@ -8,6 +8,9 @@
 ifneq ($(filter alpha amd64 armel armhf hppa i386 powerpc ppc64 s390 s390x sh4 sparc sparc64,$(DEB_BUILD_ARCH)),)
   binary-arch: install-tools
 endif
+ifneq ($(filter amd64 i386,$(DEB_BUILD_ARCH)),)
+  binary-arch: install-hyperv
+endif
 
 build: $(STAMPS_DIR)/build
 
@@ -43,7 +46,7 @@
 	dh_testdir
 	dh_testroot
 	dh_clean -k -d
-	$(MAKE) -C $(BUILD_DIR)/tools install top_srcdir=$(CURDIR) DESTDIR=$(DIR)
+	$(MAKE) -C $(BUILD_DIR)/tools/perf install top_srcdir=$(CURDIR) DESTDIR=$(DIR)
 	dh_perl /usr/share/perf_$(VERSION)-core/scripts/perl/Perf-Trace-Util/lib/
 	dh_python2 /usr/share/perf_$(VERSION)-core/scripts/python/Perf-Trace-Util/lib/
 	dh_installchangelogs
@@ -78,3 +81,23 @@
 	dh_gencontrol -- -v$(VERSION)+$(VERSION_DEBIAN)
 	dh_md5sums
 	dh_builddeb
+
+install-hyperv: PACKAGE_NAME = hyperv-services
+install-hyperv: DH_OPTIONS = -p$(PACKAGE_NAME)
+install-hyperv: DIR = $(CURDIR)/debian/$(PACKAGE_NAME)
+install-hyperv: $(STAMPS_DIR)/build
+	dh_testdir
+	dh_testroot
+	dh_clean -k -d
+	$(MAKE) -C $(BUILD_DIR)/tools/hv install top_srcdir=$(CURDIR) DESTDIR=$(DIR)
+	dh_installinit --name=hv_kvp_daemon
+	dh_installchangelogs
+	dh_installdocs
+	dh_strip
+	dh_compress
+	dh_fixperms
+	dh_installdeb
+	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb

Modified: dists/sid/linux-tools/debian/templates/control.main.in
==============================================================================
--- dists/sid/linux-tools/debian/templates/control.main.in	Sun Jun 24 02:23:10 2012	(r19193)
+++ dists/sid/linux-tools/debian/templates/control.main.in	Sun Jun 24 06:21:06 2012	(r19194)
@@ -47,3 +47,12 @@
  .
  This package provides the server component 'usbipd' and the
  client tool 'usbip'.
+
+Package: hyperv-services
+Architecture: amd64 i386
+Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base (>= 3.2-14)
+Description: Hyper-V Key Value Pair daemon
+ This package contains the Hyper-V Key Value Pair daemon, part of
+ Linux Integration Services for Hyper-V.  When installed on a guest
+ virtual machine, this allows the host to read the guest OS version
+ and network configuration, and to store information in the guest.



More information about the Kernel-svn-changes mailing list