Import HyperV Key-Value Pair (KVP) driver and daemon code by Microsoft,

many thanks for their continued support of FreeBSD.

While I'm there, also implement a new build knob, WITHOUT_HYPERV to
disable building and installing of the HyperV utilities when necessary.

The HyperV utilities are only built for i386 and amd64 targets.

This is a stable/10 candidate for inclusion with 10.1-RELEASE.

Submitted by:	Wei Hu <weh microsoft com>
MFC after:	1 week
This commit is contained in:
Xin LI 2014-09-13 02:15:31 +00:00
parent b75ac2ba76
commit e72055b7fe
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=271493
28 changed files with 3102 additions and 101 deletions

View file

@ -0,0 +1,68 @@
.\" Copyright (c) 2014 Microsoft Corp.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd September 10, 2013
.Dt HYPER-V 4
.Os
.Sh NAME
.Nm hv_kvp_daemon
.Nd Hyper-V Key Value Pair Daemon
.Sh SYNOPSIS
The \fBhv_kvp_daemon\fP daemon provides the ability to store, retrieve, modify and delete
Key Value pairs for FreeBSD guest partitions running on Hyper-V.
.Sh DESCRIPTION
Hyper-V allows administrators to store custom metadata in the form
of Key Value pairs inside the FreeBSD guest partition. Administrators can
use Windows Powershell scripts to add, read, modify and delete such
Key Value pairs.
The \fBhv_kvp_daemon\fP accepts Key Value pair management requests from the
\fBhv_utils\fP driver and performs the actual metadata management on the file-system.
The same daemon and driver combination is also used to set and get
IP addresses from a FreeBSD guest.
The set functionality is particularly
useful when the FreeBSD guest is assigned a static IP address and is failed
over from one Hyper-V host to another. After failover, Hyper-V uses the set IP
functionality to automatically
update the FreeBSD guest's IP address to its original static value.
On the other hand, the get IP functionality is used to update the guest IP
address in the Hyper-V management console window.
.Sh SEE ALSO
.Xr hv_vmbus 4 ,
.Xr hv_utils 4 ,
.Xr hv_netvsc 4 ,
.Xr hv_storvsc 4 ,
.Xr hv_ata_pci_disengage 4
.Sh HISTORY
Support for Hyper-V in the form of ports was first released in September 2013.
The daemon was developed through a joint effort between Citrix Inc.,
Microsoft Corp. and Network Appliance Inc..
.Sh AUTHORS
.An -nosplit
.Fx
support for \fBhv_kvp_daemon\fP was first added by
.An Microsoft BSD Integration Services Team Aq bsdic@microsoft.com .

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,24 @@
#!/bin/sh
# This is the script retrieves the DHCP state of a given interface.
# The kvp daemon code invokes this external script to gather
# DHCP setting for the specific interface.
#
# Input: Name of the interface
#
# Output: The script prints the string "Enabled" to stdout to indicate
# that DHCP is enabled on the interface. If DHCP is not enabled,
# the script prints the string "Disabled" to stdout.
#
. /etc/rc.subr
. /etc/network.subr
load_rc_config netif
if dhcpif hn0;
then
echo "Enabled"
else
echo "Disabled"
fi

View file

@ -0,0 +1,12 @@
#!/bin/sh
# This script parses /etc/resolv.conf to retrive DNS information.
# Khe kvp daemon code invokes this external script to gather
# DNS information.
# This script is expected to print the nameserver values to stdout.
#if test -r /etc/resolv.conf
#then
# awk -- '/^nameserver/ { print $2 }' /etc/resolv.conf
#fi
cat /etc/resolv.conf 2>/dev/null | awk '/^nameserver/ { print $2 }'

View file

@ -0,0 +1,73 @@
#!/bin/sh
# This script activates an interface based on the specified
# configuration. The kvp daemon code invokes this external script
# to configure the interface.
#
# The only argument to this script is the configuration file that is to
# be used to configure the interface.
#
# Here is the format of the ip configuration file:
#
# HWADDR=macaddr
# IF_NAME=interface name
# DHCP=yes (This is optional; if yes, DHCP is configured)
#
# IPADDR=ipaddr1
# IPADDR_1=ipaddr2
# IPADDR_x=ipaddry (where y = x + 1)
#
# NETMASK=netmask1
# NETMASK_x=netmasky (where y = x + 1)
#
# GATEWAY=ipaddr1
# GATEWAY_x=ipaddry (where y = x + 1)
#
# DNSx=ipaddrx (where first DNS address is tagged as DNS1 etc)
#
# IPV6 addresses will be tagged as IPV6ADDR, IPV6 gateway will be
# tagged as IPV6_DEFAULTGW and IPV6 NETMASK will be tagged as
# IPV6NETMASK.
#
# The host can specify multiple ipv4 and ipv6 addresses to be
# configured for the interface. Furthermore, the configuration
# needs to be persistent. A subsequent GET call on the interface
# is expected to return the configuration that is set via the SET
# call.
#
. $1
sed -i".bak" '/ifconfig_hn0="SYNCDHCP"/d' /etc/rc.conf
sed -i".bak" '/ifconfig_hn0="DHCP"/d' /etc/rc.conf
# MAC Address
ifconfig $IF_NAME ether $HWADDR
# IP and Subnet Mask
ifconfig $IF_NAME inet $IP_ADDR netmask $SUBNET
# DNS
sed -i".bak" '/nameserver/d' /etc/resolv.conf
echo "nameserver" $DNS >> /etc/resolv.conf
#Gateway
# Need to implment if Gateway is not present
route flush
route add default $GATEWAY
#route change default $GATEWAY
#/etc/rc.d/netif restart
#/etc/rc.d/routing restart
# DHCP
if [ $DHCP -eq 1 ]
then
echo ifconfig_hn0=\"DHCP\" >> /etc/rc.conf
echo Enabled
else
echo Disabled DHCP >> /var/log/messages
echo Disabled
fi
echo "Set IP-Injection Success"

View file

@ -108,6 +108,8 @@
..
bsdinstall
..
hyperv
..
lpr
ru
..

View file

@ -42,6 +42,8 @@
..
freebsd-update mode=0700
..
hyperv mode=0700
..
ipf mode=0700
..
pkg

View file

@ -57,6 +57,7 @@ FILES= DAEMON \
hostid \
hostid_save \
hostname \
${_hv_kvpd} \
inetd \
initrandom \
ip6addrctl \
@ -192,6 +193,10 @@ _ubthidhci= ubthidhci
_casperd= casperd
.endif
.if ${MK_HYPERV} != "no"
_hv_kvpd= hv_kvpd
.endif
.if ${MK_UNBOUND} != "no"
_unbound= local_unbound
.endif

15
etc/rc.d/hv_kvpd Normal file
View file

@ -0,0 +1,15 @@
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: hv_kvpd
. /etc/rc.subr
name="hv_kvp_daemon"
command="/usr/sbin/${name}"
required_dirs="/var/db/hyperv"
load_rc_config $name
run_rc_command "$1"

View file

@ -13,6 +13,7 @@ SUBDIR= ${_atf} \
fingerd \
ftpd \
getty \
${_hyperv} \
${_mail.local} \
${_mknetid} \
${_pppoed} \
@ -54,6 +55,10 @@ _dma= dma
_dma-mbox-create= dma-mbox-create
.endif
.if ${MK_HYPERV} != "no"
_hyperv= hyperv
.endif
.if ${MK_NIS} != "no"
_mknetid= mknetid
_ypxfr= ypxfr

10
libexec/hyperv/Makefile Normal file
View file

@ -0,0 +1,10 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../contrib/hyperv/tools/scripts
BINDIR= /usr/libexec/hyperv
SCRIPTS= hv_set_ifconfig hv_get_dns_info hv_get_dhcp_info
NO_OBJ=
.include <bsd.prog.mk>

View file

@ -212,6 +212,13 @@ __DEFAULT_NO_OPTIONS+=CLANG_IS_CC CLANG CLANG_BOOTSTRAP
__DEFAULT_YES_OPTIONS+=GCC GCC_BOOTSTRAP GNUCXX
.endif
# HyperV is only available for x86 and amd64.
.if ${__T} == "amd64" || ${__T} == "i386"
__DEFAULT_YES_OPTIONS+=HYPERV
.else
__DEFAULT_NO_OPTIONS+=HYPERV
.endif
.include <bsd.mkopt.mk>
#

View file

@ -223,6 +223,7 @@ dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv
dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv
dev/hyperv/stordisengage/hv_ata_pci_disengage.c optional hyperv
dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
dev/hyperv/utilities/hv_kvp.c optional hyperv
dev/hyperv/utilities/hv_util.c optional hyperv
dev/hyperv/vmbus/hv_channel.c optional hyperv
dev/hyperv/vmbus/hv_channel_mgmt.c optional hyperv

View file

@ -215,6 +215,7 @@ dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv
dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv
dev/hyperv/stordisengage/hv_ata_pci_disengage.c optional hyperv
dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
dev/hyperv/utilities/hv_kvp.c optional hyperv
dev/hyperv/utilities/hv_util.c optional hyperv
dev/hyperv/vmbus/hv_channel.c optional hyperv
dev/hyperv/vmbus/hv_channel_mgmt.c optional hyperv

View file

@ -795,5 +795,34 @@ hv_get_phys_addr(void *virt)
return (ret);
}
/**
* KVP related structures
*
*/
typedef struct hv_vmbus_service {
hv_guid guid; /* Hyper-V GUID */
char *name; /* name of service */
boolean_t enabled; /* service enabled */
hv_work_queue *work_queue; /* background work queue */
/*
* function to initialize service
*/
int (*init)(struct hv_vmbus_service *);
/*
* function to process Hyper-V messages
*/
void (*callback)(void *);
} hv_vmbus_service;
extern uint8_t* receive_buffer[];
extern hv_vmbus_service service_table[];
void hv_kvp_callback(void *context);
int hv_kvp_init(hv_vmbus_service *serv);
void hv_kvp_deinit(void);
#endif /* __HYPERV_H__ */

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,5 @@
/*-
* Copyright (c) 2009-2012 Microsoft Corp.
* Copyright (c) 2012 NetApp Inc.
* Copyright (c) 2012 Citrix Inc.
* Copyright (c) 2014 Microsoft Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,13 +22,15 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _KVP_H
#define _KVP_H
/*
* An implementation of HyperV key value pair (KVP) functionality for FreeBSD
* An implementation of HyperV key value pair (KVP) functionality for FreeBSD
*
*/
@ -53,15 +53,15 @@
/*
* bytes, including any null terminators
*/
#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048)
#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)
#define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512)
/*
* In FreeBSD, we implement the KVP functionality in two components:
@ -111,30 +111,20 @@
* (not supported), a NULL key string is returned.
*/
/*
* Registry value types.
*/
#define HV_REG_SZ 1
#define HV_REG_U32 4
#define HV_REG_U64 8
#define HV_REG_SZ 1
#define HV_REG_U32 4
#define HV_REG_U64 8
/*
* Daemon code not supporting IP injection (legacy daemon).
*/
#define HV_KVP_OP_REGISTER 4
/*
* 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.
*/
#define HV_KVP_OP_REGISTER 4
#define KVP_OP_REGISTER1 100
enum hv_kvp_exchg_op {
HV_KVP_OP_GET = 0,
@ -155,41 +145,41 @@ enum hv_kvp_exchg_pool {
HV_KVP_POOL_COUNT /* Number of pools, must be last. */
};
/*
* Some Hyper-V status codes.
*/
#define HV_KVP_S_OK 0x00000000
#define HV_KVP_E_FAIL 0x80004005
#define HV_KVP_S_CONT 0x80070103
#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_KVP_GUID_NOTFOUND 0x80041002
#define HV_KVP_S_OK 0x00000000
#define HV_KVP_E_FAIL 0x80004005
#define HV_KVP_S_CONT 0x80070103
#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_KVP_GUID_NOTFOUND 0x80041002
#define ADDR_FAMILY_NONE 0x00
#define ADDR_FAMILY_IPV4 0x01
#define ADDR_FAMILY_IPV6 0x02
#define ADDR_FAMILY_NONE 0x00
#define ADDR_FAMILY_IPV4 0x01
#define ADDR_FAMILY_IPV6 0x02
#define MAX_ADAPTER_ID_SIZE 128
#define MAX_IP_ADDR_SIZE 1024
#define MAX_GATEWAY_SIZE 512
#define MAX_ADAPTER_ID_SIZE 128
#define MAX_IP_ADDR_SIZE 1024
#define MAX_GATEWAY_SIZE 512
struct hv_kvp_ipaddr_value {
uint16_t adapter_id[MAX_ADAPTER_ID_SIZE];
uint8_t addr_family;
uint8_t dhcp_enabled;
uint16_t ip_addr[MAX_IP_ADDR_SIZE];
uint16_t sub_net[MAX_IP_ADDR_SIZE];
uint16_t gate_way[MAX_GATEWAY_SIZE];
uint16_t dns_addr[MAX_IP_ADDR_SIZE];
} __attribute__((packed));
uint16_t adapter_id[MAX_ADAPTER_ID_SIZE];
uint8_t addr_family;
uint8_t dhcp_enabled;
uint16_t ip_addr[MAX_IP_ADDR_SIZE];
uint16_t sub_net[MAX_IP_ADDR_SIZE];
uint16_t gate_way[MAX_GATEWAY_SIZE];
uint16_t dns_addr[MAX_IP_ADDR_SIZE];
}__attribute__((packed));
struct hv_kvp_hdr {
uint8_t operation;
uint8_t pool;
uint8_t operation;
uint8_t pool;
uint16_t pad;
} __attribute__((packed));
@ -197,9 +187,9 @@ struct hv_kvp_exchg_msg_value {
uint32_t value_type;
uint32_t key_size;
uint32_t value_size;
uint8_t key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
uint8_t key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
union {
uint8_t value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
uint8_t value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE];
uint32_t value_u32;
uint64_t value_u64;
} msg_value;
@ -229,16 +219,16 @@ struct hv_kvp_register {
struct hv_kvp_msg {
union {
struct hv_kvp_hdr kvp_hdr;
int error;
struct hv_kvp_hdr kvp_hdr;
uint32_t error;
} hdr;
union {
struct hv_kvp_msg_get kvp_get;
struct hv_kvp_msg_set kvp_set;
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_ipaddr_value kvp_ip_val;
struct hv_kvp_register kvp_register;
struct hv_kvp_ipaddr_value kvp_ip_val;
struct hv_kvp_register kvp_register;
} body;
} __attribute__((packed));
@ -248,38 +238,17 @@ struct hv_kvp_ip_msg {
struct hv_kvp_ipaddr_value kvp_ip_val;
} __attribute__((packed));
#define BSD_SOC_PATH "/etc/hyperv/socket"
#define HV_SHUT_DOWN 0
#define HV_TIME_SYNCH 1
#define HV_HEART_BEAT 2
#define HV_KVP 3
#define HV_MAX_UTIL_SERVICES 4
#define HV_SHUT_DOWN 0
#define HV_TIME_SYNCH 1
#define HV_HEART_BEAT 2
#define HV_KVP 3
#define HV_MAX_UTIL_SERVICES 4
#define HV_WLTIMEDELTA 116444736000000000L /* in 100ns unit */
#define HV_ICTIMESYNCFLAG_PROBE 0
#define HV_ICTIMESYNCFLAG_SYNC 1
#define HV_ICTIMESYNCFLAG_SAMPLE 2
#define HV_NANO_SEC_PER_SEC 1000000000
typedef struct hv_vmbus_service {
hv_guid guid; /* Hyper-V GUID */
char* name; /* name of service */
boolean_t enabled; /* service enabled */
hv_work_queue* work_queue; /* background work queue */
//
// function to initialize service
//
int (*init)(struct hv_vmbus_service *);
//
// function to process Hyper-V messages
//
void (*callback)(void *);
} hv_vmbus_service;
extern uint8_t* receive_buffer[];
extern hv_vmbus_service service_table[];
#define HV_WLTIMEDELTA 116444736000000000L /* in 100ns unit */
#define HV_ICTIMESYNCFLAG_PROBE 0
#define HV_ICTIMESYNCFLAG_SYNC 1
#define HV_ICTIMESYNCFLAG_SAMPLE 2
#define HV_NANO_SEC_PER_SEC 1000000000
#endif /* _KVP_H */

View file

@ -1,7 +1,5 @@
/*-
* Copyright (c) 2009-2012 Microsoft Corp.
* Copyright (c) 2012 NetApp Inc.
* Copyright (c) 2012 Citrix Inc.
* Copyright (c) 2014 Microsoft Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,9 +22,11 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
/**
/*
* A common driver for all hyper-V util services.
*/
@ -53,7 +53,7 @@ static void hv_timesync_cb(void *context);
static int hv_timesync_init(hv_vmbus_service *serv);
/**
/*
* Note: GUID codes below are predefined by the host hypervisor
* (Hyper-V and Azure)interface and required for correct operation.
*/
@ -80,7 +80,16 @@ hv_vmbus_service service_table[] = {
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d},
.name = "Hyper-V Heartbeat Service\n",
.enabled = TRUE,
.callback = hv_heartbeat_cb,
.callback = hv_heartbeat_cb,
},
/* KVP (Key Value Pair) Service */
{ .guid.data = {0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6},
.name = "Hyper-V KVP Service\n",
.enabled = TRUE,
.init = hv_kvp_init,
.callback = hv_kvp_callback,
},
};
@ -90,6 +99,8 @@ hv_vmbus_service service_table[] = {
*/
uint8_t *receive_buffer[HV_MAX_UTIL_SERVICES];
static boolean_t destroyed_kvp = FALSE;
struct hv_ictimesync_data {
uint64_t parenttime;
uint64_t childtime;
@ -143,7 +154,7 @@ hv_negotiate_version(
static void
hv_set_host_time(void *context)
{
time_sync_data *time_msg = context;
time_sync_data* time_msg = (time_sync_data*) context;
uint64_t hosttime = time_msg->data;
struct timespec guest_ts, host_ts;
uint64_t host_tns;
@ -253,12 +264,12 @@ hv_timesync_cb(void *context)
static void
hv_shutdown_cb(void *context)
{
uint8_t* buf;
uint8_t* buf;
hv_vmbus_channel* channel = context;
uint8_t execute_shutdown = 0;
uint8_t execute_shutdown = 0;
hv_vmbus_icmsg_hdr* icmsghdrp;
uint32_t recv_len;
uint64_t request_id;
uint32_t recv_len;
uint64_t request_id;
int ret;
hv_vmbus_shutdown_msg_data* shutdown_msg;
@ -421,6 +432,11 @@ hv_util_detach(device_t dev)
struct hv_vmbus_service* service;
size_t receive_buffer_offset;
if (!destroyed_kvp) {
hv_kvp_deinit();
destroyed_kvp = TRUE;
}
hv_dev = vmbus_get_devctx(dev);
hv_vmbus_channel_close(hv_dev->channel);
@ -432,21 +448,22 @@ hv_util_detach(device_t dev)
free(receive_buffer[receive_buffer_offset], M_DEVBUF);
receive_buffer[receive_buffer_offset] = NULL;
return (0);
}
static void hv_util_init(void)
static void
hv_util_init(void)
{
}
static int hv_util_modevent(module_t mod, int event, void *arg)
static int
hv_util_modevent(module_t mod, int event, void *arg)
{
switch (event) {
case MOD_LOAD:
break;
case MOD_UNLOAD:
break;
break;
default:
break;
}

View file

@ -0,0 +1,201 @@
/* $NetBSD: unicode.h,v 1.1.1.1 2007/03/06 00:10:39 dillo Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/types.h>
#define UNICODE_DECOMPOSE 0x01
#define UNICODE_PRECOMPOSE 0x02
#define UNICODE_UTF8_LATIN1_FALLBACK 0x03
size_t utf8_to_utf16(uint16_t *, size_t, const char *, size_t, int, int *);
size_t utf16_to_utf8(char *, size_t, const uint16_t *, size_t, int, int *);
size_t
utf8_to_utf16(uint16_t *dst, size_t dst_len,
const char *src, size_t src_len,
int flags, int *errp)
{
const unsigned char *s;
size_t spos, dpos;
int error;
uint16_t c;
#define IS_CONT(c) (((c)&0xc0) == 0x80)
error = 0;
s = (const unsigned char *)src;
spos = dpos = 0;
while (spos<src_len) {
if (s[spos] < 0x80)
c = s[spos++];
else if ((flags & UNICODE_UTF8_LATIN1_FALLBACK)
&& (spos >= src_len || !IS_CONT(s[spos+1]))
&& s[spos]>=0xa0) {
/* not valid UTF-8, assume ISO 8859-1 */
c = s[spos++];
}
else if (s[spos] < 0xc0 || s[spos] >= 0xf5) {
/* continuation byte without lead byte
or lead byte for codepoint above 0x10ffff */
error++;
spos++;
continue;
}
else if (s[spos] < 0xe0) {
if (spos >= src_len || !IS_CONT(s[spos+1])) {
spos++;
error++;
continue;
}
c = ((s[spos] & 0x3f) << 6) | (s[spos+1] & 0x3f);
spos += 2;
if (c < 0x80) {
/* overlong encoding */
error++;
continue;
}
}
else if (s[spos] < 0xf0) {
if (spos >= src_len-2
|| !IS_CONT(s[spos+1]) || !IS_CONT(s[spos+2])) {
spos++;
error++;
continue;
}
c = ((s[spos] & 0x0f) << 12) | ((s[spos+1] & 0x3f) << 6)
| (s[spos+2] & 0x3f);
spos += 3;
if (c < 0x800 || (c & 0xdf00) == 0xd800 ) {
/* overlong encoding or encoded surrogate */
error++;
continue;
}
}
else {
uint32_t cc;
/* UTF-16 surrogate pair */
if (spos >= src_len-3 || !IS_CONT(s[spos+1])
|| !IS_CONT(s[spos+2]) || !IS_CONT(s[spos+3])) {
spos++;
error++;
continue;
}
cc = ((s[spos] & 0x03) << 18) | ((s[spos+1] & 0x3f) << 12)
| ((s[spos+2] & 0x3f) << 6) | (s[spos+3] & 0x3f);
spos += 4;
if (cc < 0x10000) {
/* overlong encoding */
error++;
continue;
}
if (dst && dpos < dst_len)
dst[dpos] = (0xd800 | ((cc-0x10000)>>10));
dpos++;
c = 0xdc00 | ((cc-0x10000) & 0x3ffff);
}
if (dst && dpos < dst_len)
dst[dpos] = c;
dpos++;
}
if (errp)
*errp = error;
return dpos;
#undef IS_CONT
}
size_t
utf16_to_utf8(char *dst, size_t dst_len,
const uint16_t *src, size_t src_len,
int flags, int *errp)
{
uint16_t spos, dpos;
int error;
#define CHECK_LENGTH(l) (dpos > dst_len-(l) ? dst=NULL : NULL)
#define ADD_BYTE(b) (dst ? dst[dpos] = (b) : 0, dpos++)
error = 0;
dpos = 0;
for (spos=0; spos<src_len; spos++) {
if (src[spos] < 0x80) {
CHECK_LENGTH(1);
ADD_BYTE(src[spos]);
}
else if (src[spos] < 0x800) {
CHECK_LENGTH(2);
ADD_BYTE(0xc0 | (src[spos]>>6));
ADD_BYTE(0x80 | (src[spos] & 0x3f));
}
else if ((src[spos] & 0xdc00) == 0xd800) {
uint32_t c;
/* first surrogate */
if (spos == src_len - 1 || (src[spos] & 0xdc00) != 0xdc00) {
/* no second surrogate present */
error++;
continue;
}
spos++;
CHECK_LENGTH(4);
c = (((src[spos]&0x3ff) << 10) | (src[spos+1]&0x3ff)) + 0x10000;
ADD_BYTE(0xf0 | (c>>18));
ADD_BYTE(0x80 | ((c>>12) & 0x3f));
ADD_BYTE(0x80 | ((c>>6) & 0x3f));
ADD_BYTE(0x80 | (c & 0x3f));
}
else if ((src[spos] & 0xdc00) == 0xdc00) {
/* second surrogate without preceding first surrogate */
error++;
}
else {
CHECK_LENGTH(3);
ADD_BYTE(0xe0 | src[spos]>>12);
ADD_BYTE(0x80 | ((src[spos]>>6) & 0x3f));
ADD_BYTE(0x80 | (src[spos] & 0x3f));
}
}
if (errp)
*errp = error;
return dpos;
#undef ADD_BYTE
#undef CHECK_LENGTH
}

View file

@ -3,7 +3,7 @@
.PATH: ${.CURDIR}/../../../dev/hyperv/utilities
KMOD= hv_utils
SRCS= hv_util.c
SRCS= hv_util.c hv_kvp.c
SRCS+= bus_if.h device_if.h
CFLAGS+= -I${.CURDIR}/../../../dev/hyperv/include \

View file

@ -4766,3 +4766,11 @@ OLD_FILES+=usr/libexec/dma-mbox-create
OLD_FILES+=usr/share/man/man8/dma.8.gz
OLD_FILES+=usr/share/examples/dma/mailer.conf
.endif
.if ${MK_HYPERV} == no
OLD_FILES+=etc/rc.d/hv_kvpd
OLD_FILES+=usr/libexec/hyperv/hv_set_ifconfig
OLD_FILES+=usr/libexec/hyperv/hv_get_dns_info
OLD_FILES+=usr/libexec/hyperv/hv_get_dhcp_info
OLD_FILES+=usr/sbin/hv_kvpd
.endif

View file

@ -0,0 +1,2 @@
.\" $FreeBSD$
Set to not build or install HyperV utilities.

View file

@ -0,0 +1,2 @@
.\" $FreeBSD$
Set to build and install HyperV utilities.

View file

@ -18,6 +18,9 @@ SUBDIR+= boot0cfg
SUBDIR+= btxld
.endif
SUBDIR+= cpucontrol
.if ${MK_HYPERV} != "no"
SUBDIR+= hyperv
.endif
SUBDIR+= kgmon
SUBDIR+= lptcontrol
SUBDIR+= mount_smbfs

View file

@ -9,6 +9,9 @@ SUBDIR+= asf
SUBDIR+= btxld
.endif
SUBDIR+= cpucontrol
.if ${MK_HYPERV} != "no"
SUBDIR+= hyperv
.endif
SUBDIR+= kgmon
SUBDIR+= kgzip
SUBDIR+= lptcontrol

7
usr.sbin/hyperv/Makefile Normal file
View file

@ -0,0 +1,7 @@
# $FreeBSD$
.include <bsd.own.mk>
SUBDIR = tools
.include <bsd.subdir.mk>

View file

@ -0,0 +1,3 @@
# $FreeBSD$
.include "../Makefile.inc"

View file

@ -0,0 +1,13 @@
# $FreeBSD$
.include <bsd.own.mk>
HV_KVP_DAEMON_DISTDIR?= ${.CURDIR}/../../../contrib/hyperv/tools
.PATH: ${HV_KVP_DAEMON_DISTDIR}
PROG= hv_kvp_daemon
MAN= hv_kvp_daemon.8
CFLAGS+= -I${.CURDIR}/../../../sys/dev/hyperv/utilities
.include <bsd.prog.mk>