(转) 经过UUID在vSphere虚拟机内外识别硬盘

转自:http://ju.outofmemory.cn/entry/28398node

 

简单介绍下应用场景:开发基于虚拟化IaaS的一些应用就免不了要跟虚拟机(VM)打交道,由于VM逻辑上独立于宿主机(host),二者之间的交互就成了一个问题,本文介绍的就是在vSphere环境下VM和host之间如何准确识别硬盘,但愿能对一样基于VMware vSphere平台作开发的朋友们一点帮助和启发。linux

如何标识硬盘

在物理机上咱们把硬盘插在一条条数据线上,数据线被接到控制器总线上。IaaS这一层把对基础硬件这一层给池化,所以也提供了一系列对硬件操做的API,增长/删除设备等等。和在物理环境下同样,增长虚拟硬盘也须要指定对应的总线号和在总线上的位置,看起来这个总线号(相似X:Y,X是总线编号,Y是在总线上的unit号)能够成为内外部统一的标识符了。不过,不要too young too simple的觉得真相会是那么简单哟。shell

在Linux中使用总线编号来查询磁盘主要有两种方法:ide

  1. 在/sys/class/scsi_disk下面有诸如2:0:1:0之类的地址,见下图。
  2. 在/dev/disk/by-path下有一堆名字包含总线地址的符号连接。

让咱们来看看使用总线位置标识X:Y来识别硬盘的问题:在Linux里,总线编号X其实取决于kernel module加载的顺序。使用dmesg命令查看日志能够发现,对应的总线控制器驱动的行为是:每一个驱动在初始化的时候会扫描总线,看看有哪一个总线是匹配的,而后拿到一个bus id来标识这条总线,这个bus id也就是咱们的总线编号X。若是IDE总线驱动第一个被加载,而后再加载SCSI总线驱动,那么IDE总线就会拿到bus id 0,而SCSI总线就只能从1开始了。并且在虚拟化环境里SCSI总线也有不一样的类别(LSIlogic,PVSCI等),对应不一样的kernel module,所以不一样类型的SCSI总线之间也会产生总线编号不肯定的问题。学习

那是否是能够经过控制kernel module的方法来人为干预SCSI总线号呢?楼主用实践证实了这是个不靠谱stupid idea,有以下几个缘由:优化

  1. 每一个发行版修改kernel module加载顺序的方法不尽相同,RHEL 5.x就比较容易,从新编译下initrd,使用mkinitrd的–with参数定义module加载顺序就能够了。而RHEL 6.x因为使用了initramfs用老方法就不顶用了,尝试了好久发现有一个hack的方法:修改grub.conf,使用内核参数rdloaddriver(强制加载)和rdblacklist(强制不加载)来控制启动顺序,固然这是很不推荐的作法。
  2. 对于某些奇葩的系统,好比RHEL 6.0/Oracle Linux 6.0,即便修改grub.conf也不顶用,启动的时候module加载顺序会突变,暂时还不清楚突变的根本缘由,但多是一个bug,毕竟在以后的系统中都没有这个问题。

那听上去是否是没有什么好办法了?要没有好办法楼主也不会废话那么多失败的例子了。目前看来靠谱的方法是使用UUID来在虚拟机内外惟一标识磁盘,用法也很简单。ui

  1. Disk UUID在vSphere上默认是关闭的,须要经过在VM上设置参数disk.enableUUID=TRUE打开,以下图所示,注意由于configuration parameters其实是被写入vmx文件的,故没法在开机状况下修改。理论上应该也能够经过修改host上面的/etc/vmware/config来实现host level全局的修改,这样就无需一个一个VM单独进行设置了。
  2. 在目标机器上安装VMware Tools。
  3. 在VM外可使用vSphere的MBO(Managed Object Browser)来查看磁盘的UUID,找到VM->config->hardware->device->#DEVICE_KEY#->backing,以下图所示。固然经过API也能够查询甚至修改磁盘的UUID。
  4. 启用disk UUID而且安装了VMware Tools以后,能够在VM里面根据UUID来查询了。
    a) Linux能够在/dev/disk/by-id下找到一系列名字包含UUID的符号连接,target就是device node,相似/dev/sda,/dev/sdb之类的,可使用readlink命令来获得符号连接的target。注意这里是by-id不是by-uuid,by-id这个目录只有在设置了disk.enableUUID以后才会出现。以下图所示,能够看到有by-id/by-path/by-uuid三个目录,by-path对应的就是上文介绍的使用SCSI总线地址来进行磁盘查找的方法。

    b) Windows可使用Powershell命令:Get-WmiObject Win32_PhysicalMedia | where {$_.serialNumber -eq ‘#UUID#’} 来查询对应的磁盘,查到是第几块磁盘以后就可使用diskpart来进行磁盘初始化。以下图所示,PHYSICALDRIVE0就是指第0块硬盘。
  5. 注意作Linked Clone也不会改变磁盘的UUID,这个UUID是记录在root vmdk文件中的,登陆到ESXi上去能够用vi打开vmdk描述文件查看到。

开机状态检测磁盘的增长/变动

虚拟化环境拥有不少物理环境中作不到或者是很难作到的功能,好比在开机状态下热增长磁盘,计算资源(参考VMware vSphere hot-add CPU/memory学习笔记)等,算是先天优点而不是屌丝逆袭。如今各类操做系统也针对虚拟化环境作了很多优化,好比在Windows中热增长的磁盘能直接被识别出来。而Linux下就须要执行下面命令来从新扫描某个SCSI总线上的磁盘设备:idea


# {scsi_host_id}是系统上识别出来的bus id 
echo "- - -" > /sys/class/scsi_host/host{scsi_host_id}/scan 

操作系统

若是只是在外部修改磁盘大小,在Linux下也须要执行命令才可以使得guest系统正确识别新的size:日志

# {device_name}是逻辑设备号,好比sda,sdb。。。 echo 1 > /sys/block/{device_name}/device/rescan # 而后你能够决定是否用resize2fs来调整文件系统大小 resize2fs /dev/{device_name} 

相关文章
相关标签/搜索