6 实际编程任务

本章介绍在示例程序中没有提到的实际编程任务,包括:

  • 病毒特征扫描

  • 创建虚拟磁盘

  • 处理虚拟磁盘数据

  • 管理子磁盘

  • RDM磁盘和虚拟的BIOS

  • VMware vSphere交互

病毒特征扫描

虚拟磁盘库用例中的一项任务就是针对VDDK进行病毒特征扫描。使用示例程序的框架,可以实现一个-virus命令行选项。示例6-1中的函数依赖一个已存在的库函数SecureVirusScan(),通常由防病毒软件厂商提供。像针对Email信息一样,这个库函数会扫描任意大小的缓存,以匹配厂商的最新病毒库,如果找到了病毒就会返回TRUE

                             wKiom1POBKPQicAJAAFOlWhdWlc756.jpg

函数调用VixDiskLib_GetInfo()来获取磁盘中分配的扇区的个数。扇区个数存放在VixDiskLibDiskInfnoo结构中,但通常不在元数据中。如果是SPARSE类型的布局,数据可能存放在任何扇区上,所以这个函数读取所有扇区,不论是否填充了数据。VixDiskLib_Read()函数在遇到全是0的空扇区时会继续读取而不返回错误。

下面给出了在vixDiskLibSample.cpp中加入-virus选项,需要添加的剩余代码:

wKioL1POCDmhEqqGAAB1Zag1oaE030.jpg

创建虚拟磁盘

这一节将讨论本地VMDK文件的类型,以及如何创建远程ESX/ESXi主机上的虚拟磁盘。

创建本地磁盘

5章中的示例程序中创建了类型为单片稀疏型的虚拟磁盘,即非提前分配的大文件。这是默认的类型,因为现代的文件系统,尤其是NTFS,支持大于2GB的文件,且可以存储大于2GB的数据。在一些旧的文件系统中,如MS-DOS和早期WindowsFAT16,或者用于CDISO9660,或者NFS2,以及Linux内核2.4,不支持这种特性,每个卷只能限制为2GB大小。FATFAT32NT3.51中扩展了可支持4GB文件。

但是,分割的虚拟磁盘可能比单片的虚拟磁盘更安全,因为如果底层主机文件系统发生故障,一些数据可以从未被损坏的2GB扩展中恢复出来。VMware产品尽力修复损坏的VMDK文件,但是分卷的VMDK文件增加了修复中获得数据的机会。缺点是分卷问加你增加了负载(更多的文件描述符),并增加了管理复杂性。

如果遇到FAT16或早期的Linux文件系统,你可以创建SPLIT_SPARSE虚拟磁盘。这个改变是简单的:下面粗线加亮的部分。示例程序可以进行扩展以提供这样的选项。

wKiom1POB3SBgbOLAAC8b81QBZs909.jpg

注意:你可以将VMDK文件的分卷大小设置为小于2GB,但是创建的文件名称依然遵从表3-1所示的规则。

针对DoCrate()的一行改变,将创建200MB的分卷VMDK文件,除非你通过-cap选项指定其他大小。

创建远程磁盘

VixDiskLib_Create()不支持创建托管磁盘。为了在远程ESX/ESXi主机上创建托管磁盘,首先要在本地工作站上创建一个本地磁盘,然后使用VixDiskLib_Clone()经过网络将本地磁盘转换为托管磁盘。

要使用示例程序创建远程托管磁盘,使用如下命令:

vix-disklib-sample–create –cap 1000000 virtdisk.vmdk

vix-disklib-sample–clone virtdisk.vmdk –host esx3i –user root –password secret vmfsdisk.vmdk

可以编写一个虚拟机应用程序来执行如下操作:

1使用VixDiskLib_Create()创建一个2GB大小的本地VMDK磁盘。

2使用VixDiskLib_Write()将客户机系统的镜像和应用软件写入VMDK

3将本地的VMDK磁盘克隆岛ESX/ESXi主机的VMFS文件系统上。

vixError= VixDiskLib_Clone(appGlobals.connection, appGlobals.diskPath, srcConnection,appGlobals.srcPath, &createParam, CloneProgressFunc, NULL, TRUE);

在这个调用中,appGlloobals.connectionappGlobals.diskPath表示ESX/ESXi主机上的远程VMDK,而srcConectionappGlobals.srcPath表示本地VMDK

4打开新的客户机系统,得到一个新的虚拟机。

在工作站上,VIX API中的VixVMPowerOn()函数实现这个功能。对于ESX/ESXi主机及,必须使用PowerOnVM_Task方法。使用这个方法的简单方式在VMware vSphere Perl开发包中,它包含PowerOnVM_Task()(非阻塞)PowerOnVM()(同步)调用。

5ESX/ESXi主机上发布新的虚拟机。

注意:无论在步骤1中创建什么类型的虚拟文件,在步骤3中它都将变成VIXDISKLIB_DISK_VMFS_FLAT类型。

处理虚拟磁盘数据

虚拟磁盘库按扇区读、写数据,不提供接口对字符或字节的I/O操作。

读、写本地磁盘

下面的代码从VMDK文件中读取一次读取一个扇区,如果找到包含“VmWare”的字符串,使用“VMware”替换它,并写回VMDK文件。

wKiom1POB7TyRvAmAAD0HsxUHZM406.jpg

读写远程磁盘

读写ESX/ESXi主机上远程托管磁盘的DoEdit()函数是类似的,但是在之前你必须使用认证凭据调用VixDiskLib_Connect()函数,而不是传入NULL参数。

wKioL1POCP3CafctAADMGqclEPQ781.jpg

删除磁盘(UnLink)

VixDiskLib_Unlink()函数扇区虚拟磁盘文件。它有两个参数:连接和VMDK文件名称。

vixError= VixDiskLib_Unlink(appGlobals.connection, appGlobals.diskPath);

删除虚拟磁盘的影响

删除一个VMDK后,它包含的所有信息都将丢失。大多数情况下,如果虚拟机正在运行,宿主操作系统将会阻止你删除文件。然而,如果你删除一个关机的虚拟机的VMDK文件,这个客户系统将无法启动。

修改磁盘名称

VixDiskLib_Rename()函数对虚拟磁盘进行重命名,它有两参数:旧的和新的VMDK文件名称。

vixError= VixDiskLib_Rename(oldGlobals.diskpath, newGlobals.diskpath);

重命名虚拟磁盘的影响

服务器希望客户机虚拟机系统的VMDK文件存放在一个可预见的位置。在重命名期间的任何文件访问都有可能造成I/O失败,或导致客户系统故障。

处理磁盘元数据

ESX/ESXi主机上VMFS文件系统上,磁盘元数据项很重要,因为它们存储了关于所包含的文件系统的磁盘映射和交互的信息。

处理子磁盘

在虚拟磁盘API中,重写日志由父-子磁盘链进行管理,每一个孩子成为从开始时磁盘改变的重写日志。创建一个子磁盘后,再尝试写父磁盘将会出错,库要求写子磁盘。

创建重写日志

通过创建一个虚拟机快照可生成一个重写日志,这个快照包含磁盘数据和虚拟机状态。仅仅在本地磁盘上,可以不需要创建虚拟机快照,而通过VixDiskLib_CreateChild()创建一个重写日志。

你可以写一个简单的应用程序在晚上3:00创建一个重写日志,或者托管磁盘的快照(尽管多个快照会影响性能)。当你在虚拟机正在运行时创建一个快照时,VMware主机会重新组织文件指针,主VMDK持续跟踪磁盘链中重写日志(the VMware host re-arranges filepointers so the primary VMDK, <vmname>.vmdk for example, keep track ofredo logs in the disk chain)。使用这个磁盘链,可以重新创建任何一天的数据。

重新创建给定时间的数据

1找到对应日期的<vmname>-<NNN>.vmdk重写日志。<NNN>是一个序列号。你可以通过时间戳来标识重写日志或快照。

2初始化虚拟磁盘库,打开重写日志,并得到它的父句柄。

3使用VixDiskLib_Create()创建一个子磁盘,然后附加到父磁盘上:

    vixError =VixDiskLib_Attach(parent.Handle(), child.Handle());

4读、写附加的子虚拟磁盘。

这仅仅是一个例子。在托管磁盘上,考虑到性能因素,不建议创建多个虚拟机快照。vSphere备份软件创建一个快照,保存数据,然后删除快照。

快照中的虚拟磁盘

虚拟磁盘API提供以下功能来处理快照中的磁盘组件:

  • 在磁盘链中附加一个子磁盘

  • 只读打开虚拟磁盘

  • 通过VMware vCenter打开ESX/ESXi主机上的快照磁盘

Windows2000只读文件系统

父子磁盘链的另外一个用处是为Windows2000提供只读的访问,因为Windows2000不能挂载一个只读的文件系统。在途6-1中,灰色的圆圈表示一个必须保持只读状态的虚拟磁盘,因为它有孩子节点。在这个例子中,你需要Windows2000使用这个磁盘,而不是使用新的C1C2.创建一个新的子磁盘R0,并附加到灰色的虚拟磁盘上,并挂载R0作为Windows2000客户机系统的只读虚拟磁盘。

wKiom1POCDGhRegCAAB571HTap0943.jpg

RDM磁盘和虚拟BIOS

本节描述一个低级的程序来还原原始设备映射(RDM)磁盘以及NVRAM

还原RDM磁盘

备份和还原RDM磁盘遇到了不寻常的挑战。原来的RDM配置备份并不适用,并且可能是不恰当的,如果用户还原:

  • 虚拟机到不同的主机或数据库。

  • 一个已删除的虚拟机,它原来的映射RDM同样被删除了,或者包含的LUN被重写。

  • RDM到不同的虚拟机,尽管虚拟机在相同的主机和数据存储上。用户需要访问磁盘文件,或者测试还原。

当针对RDM磁盘执行一次代理备份时,你必须对ESXi主机和代理服务器呈现相同的LUN ID(这个限制并不适用于VMFS限制,因为虚拟磁盘库读取VMFS头部并匹配UUID。但RDM需要主机和代理有相同的LUN ID)

如果原始虚拟机的VMX文件盒磁盘映射不再可用,而包含RDMLUN仍然可用,还原RDM磁盘就是适当的。在这种情况下,LUN上的RDM应该仍然有效,所以它不需要还原。这样的话,在还原过程中就不需要修改RDM配置。否则,按两步进行完全还原:

  • 还原虚拟机配置(VMX)以及系统磁盘。这会还原虚拟机,但不还原RDM

  • RDM磁盘添加到虚拟机。之后,就可以在RDM磁盘上完成正常的还原操作。

另外,可以创建一个虚拟机包含RDM磁盘,并访问它的内容。创建虚拟机后,从备份中还原虚拟机配置(VMX),然后还原任何选择的磁盘。

还原虚拟BIOSUEFI

虚拟机的BIOSUEFI配置信息保存在.nvram文件中。通常该文件中唯一重要的是启动磁盘设置和启动顺序(多虚拟磁盘时)

在新发布的vSphere中可以使用扩展的属性设置来改变启动顺序,所以启动顺序不再必须保存在.nvram文件中。然而一些用户想要保留虚拟机的串口设置或其他项目,所以应用程序还是应该备份和还原这些信息。

备份和还原NVRAM

1对每一个虚拟机,生成.nvram文件的一个单独拷贝。

2使用标准方法备份每个虚拟机。

3如果需要,使用标准方法还原虚拟机。

4使用保存的原始的.nvram文件副本覆盖虚拟机的.nvram文件。

重要VMware现在建议将.nvram文件作为虚拟机备份的一部分保存起来,这是从vSphere4.1开始的变化。

VMware vSphere交互

本节讲述其他vSphere编程接口。

VIX API

VIXAPI是一个针对VMware工作站,其他主机产品以及ESX/ESXi的流行、简单易用的开发者接口。查看VMware开发者文档获取关于VIX API的信息:

http://www.vmware.com/support/developer/vix-api

VIXAPI手册包含C++PerlMicrosoft C# COMVBScript以及Visual Basic的使用参考。大部分都包含有用的代码示例。另外,vix-apiWeb手册中包含的示例有开机、关机,停止虚拟机,创建快照,客户系统操作,虚拟机发现,异步调用。

所有本地磁盘的病毒扫描

假设你要针对VMware工作站上的所有虚拟机进行病毒扫描,这里有一个基于VIX的高层的算法,可以扫描所有虚拟机的本地磁盘。

针对所有虚拟磁盘进行病毒扫描

1编写一个包含虚拟磁盘APIVIX API的应用程序。

2使用VixDiskLib_Init()初始化虚拟磁盘库。

3使用VixHost_Connect()连接VIX到工作站主机。

4使用VIX_FIND_RUNNING_VMS作为查找类型(第二个参数)调用VixHost_FindItems()。这会通过回调函数(第五个参数)返回每个虚拟机的名称。要获得每个虚拟机的磁盘,可以再虚拟机名称后加“.vmdk”后缀。

5编写一个回调函数来打开虚拟机的VMDK。你的回调函数必须和VixDiscoveryProc()回调函数类似,它出现在VIX API参考手册中VixHost_FindItems()页的示例程序中。

6使用“病毒特征扫描”一节中的DoVirusScan()函数替换回调函数中的打印虚拟机名称部分。

7处理病毒扫描定位到的任何感染的扇区。

vSphere Web Services API

VMwarevSphere Web Services (WS) API是一个针对ESX/ESXi主机和vCenter服务器的开发者接口。查看开发者文档以获取更多关于vSphere WS API的信息:

http://www.vmware.com/support/developer/vc-sdk

VMwarevSphere WS SDK的开发者安装手册中,有一章描述了如何建立Microsoft C#Java的开发环境。一些信息同样适用于C++

vSphere的编程手册包含的一些示例代码是用C#编写的,但是大部分的示例都是用Java写的,并且给予JAX-WS开发框架。

ESX/ESXi主机和VMware vSphere WS接口使用一种基于Web服务的编程模型。客户端生成Web服务描述语言(WSDL)请求,通过简单对象访问协议(SOAP)封装成XML消息,传递到网络上。在ESX/ESXi主机或vCenter服务器上,vSphere层应答客户端的请求,通常还会返回SOAP响应。这是同C++VIX API的面向对象的函数调用不同的一种编程模型。

所有托管磁盘的病毒扫描

假设你想要对ESX/ESXi主机上的所有虚拟机进行病毒扫描,这里的VMware vSphere解决方案的高层算法,能够扫描所有虚拟机的托管磁盘。

扫描所有托管磁盘

1使用VMware vSphere Perl工具包,编写Perl脚本,连接到指定的ESX/ESXi主机上。

2调用Vim::find_entity_views()找到每个虚拟机的清单(inventory)

3调用Vim::get_inventory_path()获得在相应资源中的虚拟磁盘名称。VMDK的文件名称可以通过GuestDiskInfo数据对象的diskPath属性获得。

4使用Perlsystem(@cmd)调用,运行扩展的vixDiskLibSample.exe程序,并使用-virus选项。对于ESX/ESXi主机,还需要提供-host-user-password参数。

5清除所有被标记为病毒感染的扇区。

使用vSphere WS API读写VMDK

VMwarevSphere API 2.5及以后版本中,包含了一些有用的方法来管理VMDK文件。可以查看VirtualDiskManager托管对象类型,它包含十多种类似于虚拟磁盘API的方法。

如果你有兴趣,打开Web上的VMware InfrastructureSDK,点击“VI API ReferenceGuide 2.5版,或者“VMware vSphere WS APIReference Guide4.0版,点击“All Typeset”,查找VirtualDiskManager