Hyper-V 包含一个 KVP 组件,可在主机和来宾 VM 之间传输键/值对。
用于发送和接收值的代码示例可用于WMI中PowerShell中的 Windows 来宾。
但是,我的客人正在使用此服务的 Linux 版本。
在哪里可以找到查询此服务以获取键/值对的示例 Linux 脚本?
Hyper-V 包含一个 KVP 组件,可在主机和来宾 VM 之间传输键/值对。
用于发送和接收值的代码示例可用于WMI中PowerShell中的 Windows 来宾。
但是,我的客人正在使用此服务的 Linux 版本。
在哪里可以找到查询此服务以获取键/值对的示例 Linux 脚本?
我写的一篇博客文章中的关键细节涵盖了这个问题。(我在别处找不到答案):
首先,确保您已安装 KVP 服务。
KVP 数据通过内核驱动程序和用户模式守护程序的协作传输到 Linux 文件系统。
[KVP 驱动程序代码] hv_kvp.c被编译到 hv_util 内核模块Source中)。由于驱动程序是 Linux 内核代码的一部分,因此默认情况下它是由最新版本的常见 Linux 发行版提供的。例如
[root@centos6-4-hv ~]# cat /etc/*-release
CentOS release 6.4 (Final)
CentOS release 6.4 (Final)
CentOS release 6.4 (Final)
[root@centos6-4-hv ~]# modinfo -F filename hv_utils
/lib/modules/2.6.32-358.el6.i686/kernel/drivers/hv/hv_utils.ko
但是,将 KVP 数据复制到系统的是用户模式守护进程 hv_kvp_daemon。启动时,hv_kvp_daemon 创建文件以在 /var/lib/hyperv ( source ) 下存储 kvp 数据。每个文件称为“池”,每个数据池都有一个文件。例如
[root@centos6-4-hv hyperv]# ls -al /var/lib/hyperv/
total 36
drwxr-xr-x. 2 root root 4096 Sep 11 21:33 .
drwxr-xr-x. 16 root root 4096 Sep 10 13:59 ..
-rw-r--r--. 1 root root 2560 Sep 10 17:05 .kvp_pool_0
-rw-r--r--. 1 root root 0 Sep 10 14:02 .kvp_pool_1
-rw-r--r--. 1 root root 0 Sep 10 14:02 .kvp_pool_2
-rw-r--r--. 1 root root 28160 Sep 10 14:02 .kvp_pool_3
-rw-r--r--. 1 root root 0 Sep 10 14:02 .kvp_pool_4
每个文件的前缀是池号。这对应于 KVP 源。例如,还记得源“0”用于将数据从主机传输到客户机吗?这意味着我们的 KVP 数据在 /var/lib/hyperv/.kvp_pool_0 中。例如
[root@centos6-4-hv hyperv]# cat /var/lib/hyperv/.kvp_pool_0
cloudstack-vm-userdatausername=root;password=1pass@word1[root@centos6-4-hv hyperv]#
这些 KVP 数据文件包含一组键/值对。每个都是固定大小的字节数组。(来源)
/*
* 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)
/*
* bytes, including any null terminators
*/
#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048)
字节数组包含一个 UTF-8 编码的字符串,它用空字符填充到最大大小。但是,不能保证空字符串终止(请参阅kvp_send_key)。
如果只有一个密钥并且密钥名称已知,解析文件的最简单方法是使用 sed。要删除我们示例中使用的空字符和键名,您将使用以下内容:
[root@centos6-4-hv hyperv]# cat /var/lib/hyperv/.kvp_pool_0 | sed 's/\x0//g' | sed 's/cloudstack-vm-userdata//g' > userdata
[root@centos6-4-hv hyperv]# more userdata
username=root;password=1pass@word1
这是一个 bash 脚本,用于读取给定文件的键值对:
#!/bin/bash
fname=$1
echo "Reading $fname"
nb=$(wc -c < $1)
nkv=$(( nb / (512+2048) ))
for n in $(seq 0 $(( $nkv - 1 )) ); do
offset=$(( $n * (512 + 2048) ))
k=$(dd if=$fname count=512 bs=1 skip=$offset status=none | sed 's/\x0.*//g')
v=$(dd if=$fname count=2048 bs=1 skip=$(( $offset + 512 )) status=none | sed 's/\x0.*//g')
echo "$k = $v"
done
java中的相同功能:
String guest_param_file="/var/lib/hyperv/.kvp_pool_3";
if (new File(guest_param_file).exists())
{
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(guest_param_file),"UTF-8"));
char [] ckey=new char[512] ;
char [] cvalue=new char[2048] ;
while (true)
{
int charcount=br.read(ckey);
if (charcount==-1)
{
break;
}
br.read(cvalue);
String key=new String(ckey).trim();
String value=new String(cvalue).trim();
System.out.println( key+" = "+value);
}
br.close();
}
catch (UnsupportedEncodingException ex)
{
}
catch (FileNotFoundException ex)
{
}
catch (IOException ex)
{
}
}