发布时间:2025-12-09 18:42:25 浏览次数:5
在KVM虚拟化环境中,当客户机的内核存储系统像在物理机上一样通过页缓存、文件系统、通用块设备层运行到实际设备驱动时,这时驱动对设备寄存器的访问会触发CPU从客户机代码切换到物理机内的KVM内核模块,进而这个I/O请求会被分发到对应的Qemu模拟的磁盘设备的代码(下面将会介绍的vhost-scsi除外)。在引入virtio-scsi之前,SCSI设备的模拟并不成熟,所以Qemu支持的磁盘接口类型主要包括IDE和Virtio[1]。
Virtio是一个通用的I/O虚拟化框架[2], 它可以有效地简化设备逻辑,从而大大减少虚拟机退出(VMEXit)次数,并且通过使用虚拟机和物理机共享的分散聚合(scatter gather)缓冲区,提高了数据传输效率。当然这需要运行在客户机内核中的前端驱动和运行在物理机中后端设备代码协作完成。在Linux上,Virtio的磁盘驱动是在通用块设备框架下实现的,当它接收到来自上层的I/O请求后,会把该请求加上Virtio块设备请求的描述信息,一起加入缓冲区,然后触发VMExit来通知后端服务代码。Qemu中的Virtio块设备的服务代码会解析缓冲区中的数据,得到块设备的操作指令和对象数据,然后调用Qemu中的块设备代码,进一步完成这个I/O请求。也就是说,Qemu中暴露给虚拟机的设备只负责处理设备逻辑,和客户机里对应的驱动共同把数据从客户机传输到物理机。
Qemu的块设备层会和后端存储交互,完成最终的I/O操作。后端存储也就是实际存储虚拟磁盘内容的地方。Qemu中支持的后端存储包括:
前端设备和后端存储的分离,可以从Qemu的命令行中看出:
-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x9,drive=drive-virtio-disk1,id=virtio-disk1
-drive file=/var/lib/libvirt/images/vm1.img,if=none,id=drive-virtio-disk2,format=qcow2
可以看到, 选项 '-device' 指定了前端的设备类型,而 '-drive' 选项定义了后端存储,并且通过设备的'drive'属性把设备和存储关联起来,就好像把盘片插入控制器。这样的设计,使得Qemu更容易利用到外部存储服务提供的高级特性,比如镜像和条带化I/O等。
后端存储的'format'选项表明该磁盘镜像使用的格式。Qemu支持的磁盘格式包括raw, qcow2, vdi, vmdk等。实际上,对于格式不是raw的磁盘镜像,Qemu的块设备层会先进入对应的格式驱动,这样才能实现它们所提供的高级特性,比如写时分配,快照等。
Virtio SCSI
virtio-blk设备提供了很好的性能,但仍然有一定的局限性:
Virtio SCSI的引入,很好的解决了上述问题。SCSI的initiator和Target之间可以使用多种传输协议中作为信道来传SCSI指令和应答数据。Virtio SCSI就是把virtio作为一种传输通道来传送SCSI指令。这样既可以保持virtio-blk设备具有的高性能,也解决了virtio-blk存在的局限性:
Virtio SCSI支持两种target,一种是在Qemu中模拟的,另外一种是在内核中模拟的。下面的Qemu命令行展示了怎样增加一个由Qemu模拟的virtio scsi设备
-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x8 -drive file=/var/lib/libvirt/image/scsi-disk1.img,if=none,id=drive-scsi0-0-0-0,format=raw -device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0对应的Libvirt XML描述如下:
<controller type='scsi' index='0' model='virtio-scsi'/> <disk type='file' device='disk'> <driver name='qemu' type='raw'/> <source file='/var/lib/libvirt/scsi-disk1.img'/> <target dev='sda' bus='scsi'/> <address type='drive' controller='0' bus='0' target='0' unit='0'/> </disk>而在内核中模拟的SCSI Target则是利用了LIO[5]的框架,通过使用vhost为LIO增加了一种基于Virtio的传输机制。这样Guest的SCSI指令就可以通过Virtio直接传送到
LIO的SCSI引擎中,然后交到它的后端存储中处理。LIO支持文件,块设备,内存磁盘,透传SCSI设备等后端。在内核中实现的SCSI target有以下优点:
和缺点:
下面的命令行展示了如何使用tagetcli[6]创建一个SCSI target,并把它作为一个SCSI设备增加到虚拟机中:
$ sudo targetcli targetcli shell version 2.1.fb30 Copyright 2011-2013 by Datera, Inc and others. For help on commands, type 'help'. /> ls o- / ......................................................................................................................... [...] o- backstores .............................................................................................................. [...] | o- block .................................................................................................. [Storage Objects: 0] | o- fileio ................................................................................................. [Storage Objects: 0] | o- pscsi .................................................................................................. [Storage Objects: 0] | o- ramdisk ................................................................................................ [Storage Objects: 0] o- iscsi ............................................................................................................ [Targets: 0] o- loopback ......................................................................................................... [Targets: 0] o- vhost ............................................................................................................ [Targets: 0] /> cd /backstores/ramdisk /backstores/ramdisk> create scsi-ramdisk1.img 100M Created ramdisk scsi-ramdisk1.img with size 100M. /backstores/ramdisk> cd ../../vhost /vhost> create Created target naa.50014058a9474085. Created TPG 1. /vhost> cd naa.50014058a9474085/tpg1/luns /vhost/naa.50...085/tpg1/luns> ls o- luns .................................................................................................................. [LUNs: 0] /vhost/naa.50...085/tpg1/luns> create /backstores/ramdisk/scsi-ramdisk1.img Created LUN 0.sudo ./x86_64-softmmu/qemu-system-x86_64 -m 1024 -enable-kvm --device vhost-scsi-pci,id=vhost-scsi0,wwpn=naa.naa.50014058a9474085 -cdrom ~/Downloads/software/Fedora-Live-Desktop-x86_64-19-1.iso
上面的命令使用了Fedora的LiveCD作为测试,也可以直接使用虚拟机的镜像文件。在虚拟机启动后,登录进入虚拟机,就可以通过lspci和lsscsi这样的命令来检查
[1] https://github.com/rustyrussell/virtio-spec
[2] http://www.ibm.com/developerworks/cn/linux/l-virtio/
[3] http://www.linux-kvm.org/wiki/images/f/f5/2011-forum-virtio-scsi.pdf
[4] http://events.linuxfoundation.org/sites/events/files/slides/MasakiKimura_LinuxConNorthAmerica2013_1.pdf
[5] http://linux-iscsi.org/wiki/Target
[6] http://linux-iscsi.org/wiki/Targetcli
转载于:https://www.cnblogs.com/allcloud/p/5626485.html