6 实际编程任务
本章介绍在示例程序中没有提到的实际编程任务,包括:
病毒特征扫描
创建虚拟磁盘
处理虚拟磁盘数据
管理子磁盘
RDM磁盘和虚拟的BIOS
VMware vSphere交互
病毒特征扫描
虚拟磁盘库用例中的一项任务就是针对VDDK进行病毒特征扫描。使用示例程序的框架,可以实现一个-virus命令行选项。示例6-1中的函数依赖一个已存在的库函数SecureVirusScan(),通常由防病毒软件厂商提供。像针对Email信息一样,这个库函数会扫描任意大小的缓存,以匹配厂商的最新病毒库,如果找到了病毒就会返回TRUE。
函数调用VixDiskLib_GetInfo()来获取磁盘中分配的扇区的个数。扇区个数存放在VixDiskLibDiskInfnoo结构中,但通常不在元数据中。如果是SPARSE类型的布局,数据可能存放在任何扇区上,所以这个函数读取所有扇区,不论是否填充了数据。VixDiskLib_Read()函数在遇到全是0的空扇区时会继续读取而不返回错误。
下面给出了在vixDiskLibSample.cpp中加入-virus选项,需要添加的剩余代码:
创建虚拟磁盘
这一节将讨论本地VMDK文件的类型,以及如何创建远程ESX/ESXi主机上的虚拟磁盘。
创建本地磁盘
第5章中的示例程序中创建了类型为单片稀疏型的虚拟磁盘,即非提前分配的大文件。这是默认的类型,因为现代的文件系统,尤其是NTFS,支持大于2GB的文件,且可以存储大于2GB的数据。在一些旧的文件系统中,如MS-DOS和早期Windows中FAT16,或者用于CD的ISO9660,或者NFS2,以及Linux内核2.4,不支持这种特性,每个卷只能限制为2GB大小。FAT和FAT32在NT3.51中扩展了可支持4GB文件。
但是,分割的虚拟磁盘可能比单片的虚拟磁盘更安全,因为如果底层主机文件系统发生故障,一些数据可以从未被损坏的2GB扩展中恢复出来。VMware产品尽力修复损坏的VMDK文件,但是分卷的VMDK文件增加了修复中获得数据的机会。缺点是分卷问加你增加了负载(更多的文件描述符),并增加了管理复杂性。
如果遇到FAT16或早期的Linux文件系统,你可以创建SPLIT_SPARSE虚拟磁盘。这个改变是简单的:下面粗线加亮的部分。示例程序可以进行扩展以提供这样的选项。
注意:你可以将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.connection和appGlobals.diskPath表示ESX/ESXi主机上的远程VMDK,而srcConection和appGlobals.srcPath表示本地VMDK。
4打开新的客户机系统,得到一个新的虚拟机。
在工作站上,VIX API中的VixVMPowerOn()函数实现这个功能。对于ESX/ESXi主机及,必须使用PowerOnVM_Task方法。使用这个方法的简单方式在VMware vSphere Perl开发包中,它包含PowerOnVM_Task()(非阻塞)和PowerOnVM()(同步)调用。
5在ESX/ESXi主机上发布新的虚拟机。
注意:无论在步骤1中创建什么类型的虚拟文件,在步骤3中它都将变成VIXDISKLIB_DISK_VMFS_FLAT类型。
处理虚拟磁盘数据
虚拟磁盘库按扇区读、写数据,不提供接口对字符或字节的I/O操作。
读、写本地磁盘
下面的代码从VMDK文件中读取一次读取一个扇区,如果找到包含“VmWare”的字符串,使用“VMware”替换它,并写回VMDK文件。
读写远程磁盘
读写ESX/ESXi主机上远程托管磁盘的DoEdit()函数是类似的,但是在之前你必须使用认证凭据调用VixDiskLib_Connect()函数,而不是传入NULL参数。
删除磁盘(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,
重新创建给定时间的数据
1找到对应日期的
2初始化虚拟磁盘库,打开重写日志,并得到它的父句柄。
3使用VixDiskLib_Create()创建一个子磁盘,然后附加到父磁盘上:
vixError =VixDiskLib_Attach(parent.Handle(), child.Handle());
4读、写附加的子虚拟磁盘。
这仅仅是一个例子。在托管磁盘上,考虑到性能因素,不建议创建多个虚拟机快照。vSphere备份软件创建一个快照,保存数据,然后删除快照。
快照中的虚拟磁盘
虚拟磁盘API提供以下功能来处理快照中的磁盘组件:
在磁盘链中附加一个子磁盘
只读打开虚拟磁盘
通过VMware vCenter打开ESX/ESXi主机上的快照磁盘
Windows2000只读文件系统
父子磁盘链的另外一个用处是为Windows2000提供只读的访问,因为Windows2000不能挂载一个只读的文件系统。在途6-1中,灰色的圆圈表示一个必须保持只读状态的虚拟磁盘,因为它有孩子节点。在这个例子中,你需要Windows2000使用这个磁盘,而不是使用新的C1和C2.创建一个新的子磁盘R0,并附加到灰色的虚拟磁盘上,并挂载R0作为Windows2000客户机系统的只读虚拟磁盘。
RDM磁盘和虚拟BIOS
本节描述一个低级的程序来还原原始设备映射(RDM)磁盘以及NVRAM。
还原RDM磁盘
备份和还原RDM磁盘遇到了不寻常的挑战。原来的RDM配置备份并不适用,并且可能是不恰当的,如果用户还原:
虚拟机到不同的主机或数据库。
一个已删除的虚拟机,它原来的映射RDM同样被删除了,或者包含的LUN被重写。
RDM到不同的虚拟机,尽管虚拟机在相同的主机和数据存储上。用户需要访问磁盘文件,或者测试还原。
当针对RDM磁盘执行一次代理备份时,你必须对ESXi主机和代理服务器呈现相同的LUN ID。(这个限制并不适用于VMFS限制,因为虚拟磁盘库读取VMFS头部并匹配UUID。但RDM需要主机和代理有相同的LUN ID。)
如果原始虚拟机的VMX文件盒磁盘映射不再可用,而包含RDM的LUN仍然可用,还原RDM磁盘就是适当的。在这种情况下,LUN上的RDM应该仍然有效,所以它不需要还原。这样的话,在还原过程中就不需要修改RDM配置。否则,按两步进行完全还原:
还原虚拟机配置(VMX)以及系统磁盘。这会还原虚拟机,但不还原RDM。
将RDM磁盘添加到虚拟机。之后,就可以在RDM磁盘上完成正常的还原操作。
另外,可以创建一个虚拟机包含RDM磁盘,并访问它的内容。创建虚拟机后,从备份中还原虚拟机配置(VMX),然后还原任何选择的磁盘。
还原虚拟BIOS或UEFI
虚拟机的BIOS或UEFI配置信息保存在.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++,Perl,Microsoft C# COM,VBScript以及Visual Basic的使用参考。大部分都包含有用的代码示例。另外,vix-api的Web手册中包含的示例有开机、关机,停止虚拟机,创建快照,客户系统操作,虚拟机发现,异步调用。
所有本地磁盘的病毒扫描
假设你要针对VMware工作站上的所有虚拟机进行病毒扫描,这里有一个基于VIX的高层的算法,可以扫描所有虚拟机的本地磁盘。
针对所有虚拟磁盘进行病毒扫描
1编写一个包含虚拟磁盘API和VIX 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使用Perl的system(@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 Guide”4.0版,点击“All Typeset”,查找VirtualDiskManager。