0

Hyper-V 包含一个 KVP 组件,可在主机和来宾 VM 之间传输键/值对。

用于发送和接收值的代码示例可用于WMI中PowerShell中的 Windows 来宾。

但是,我的客人正在使用此服务的 Linux 版本

在哪里可以找到查询此服务以获取键/值对的示例 Linux 脚本?

4

3 回答 3

1

我写的一篇博客文章中的关键细节涵盖了这个问题。(我在别处找不到答案):

首先,确保您已安装 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
于 2013-09-11T23:50:55.140 回答
0

这是一个 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
于 2020-11-10T08:13:20.807 回答
-1

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)
   {
   }
 }
于 2015-02-05T12:59:49.003 回答