virtio-scsi和virtio-blk的理解
virtio-scsi和virtio-blk都是磁盘的半虚拟化驱动,virtio-scsi解决了virtio-blk的一些限制,来看看官网的介绍:
译文:
virtio scsi hba取代virtio blk,这是一种简单的高性能准虚拟化存储设备。然而,virtio blk的设计固有的局限性如下:
- •virtio blk的范围有限,这使得新的命令实现变得复杂。每次开发一个新命令时,virtio blk驱动程序都必须在每个客户机中更新。
- •virtio blk将PCI功能和存储设备映射为1:1,限制了可扩展性。
- •virtio blk不是真正的SCSI设备。这会导致一些应用程序在从物理机移动到虚拟机时中断。
virtio scsi是一种新的准虚拟化的scsi控制器设备。它提供了与virtio blk相同的性能,并增加了以下直接好处:
- •提高了可扩展性虚拟机可以连接到更多存储设备。
- •标准命令集virtio scsi使用标准scsi命令集,简化了新功能的添加。
- •标准设备命名virtio scsi磁盘使用与裸机系统相同的路径。这简化了物理到虚拟和虚拟到虚拟的迁移。
- •通过virtio scsi的scsi设备可以将物理存储设备直接呈现给客户机。
virtio-blk简介
virtio-blk是虚拟化KVM平台下虚拟磁盘的一种实现方式,也是存储虚拟化所研究的主要对象之一。在KVM平台下,qemu程序负责模拟一台PC的整个工作过程,是虚拟化技术的精髓所在。大家知道,在物理PC中,磁盘是必不可少的设备,系统、应用程序的安装和数据的存放都离不开磁盘。在虚拟化场景下,qemu自然也需要提供对磁盘的模拟。那qemu到底是如何模拟磁盘的?virtio-blk又是一种什么样的虚拟磁盘呢?
qemu对设备的模拟可以分成两类:全模拟和半模拟。全模拟即完全模拟物理设备的工作过程,使得运行在虚拟机上的软件完全感知不到自身运行环境的差异。例如qemu中实现了对IDE磁盘、LSI控制器(其上可接SCSI磁盘)等物理存储设备的模拟,原先运行在物理机上的IDE驱动、LSI驱动或应用程序不做任何改动即可运行在虚拟机中。因此,全模拟的优点比较明显,即不用提供专门针对虚拟化场景的设备驱动,完全可以复用物理环境下的驱动程序。那么全模拟有何缺点呢?全模拟时,虚拟机内部驱动会频繁访问虚拟机IO端口,KVM平台下会导致大量的陷入和陷出操作;另外虚拟机内外数据传输时只能通过以字节为单位的拷贝方式进行,无法直接采用共享内存的方式,因此存在较大的访问性能问题。
为解决全虚拟化在性能上的问题,半模拟技术应运而生。它构造了一种虚拟化环境所独有的存储设备,因此半虚拟化需要在虚拟机内部安装特定的驱动程序才能正常驱使该设备进行工作。通常我们称虚拟机内部的驱动为前端驱动,称负责实现其功能模拟的程序(KVM平台下即为qemu程序)为后端程序,半模拟技术也常常被叫做前后端技术。采用半摸拟技术后,配合前端驱动,虚拟化设备完全可以采用全新的事件通知和数据传递机制进而大幅提升性能, 例如在virtio-blk磁盘中,采用io_event_fd进行前端到后端通知,采用中断注入方式实现后端到前端的通知,并通过IO环(vring)进行数据的共享。至此,主要说明了virtio-blk产生的背景及其价值。附上qemu所模拟的PC(基于intel i440fx主板架构)的组成结构图,以作为后续深入分析的基础。
qemu模拟实现的virtio-blk设备的组成结构如下图所示:
从图中可见,virtio-blk设备“内嵌”在一块PCI设备板(即virtio-blk-pci设备)上,其内部通过一条virtio总线连接PCI接口和virtio-blk设备。为何要将virtio-blk设备设计成这样呢?
qemu模拟的所有设备都通过总线相连,总线下可挂接若干设备,桥接设备又可生成子总线;整个PC只有一条总线(即Main System Bus,对应前端总线FSB)。因此,qemu内模拟的所有设备构成一棵总线与设备交替衍生的树。virito-blk是一种什么样的设备?又该连接在什么总线上呢?虽然virtio-blk仅在虚拟化环境下存在,但如果完全凭空创造一种新的设备类型,那前端驱动开发将是一个很大的挑战。PCI设备是PC中最为常见的一种设备类别,且有较为完善的规范说明,因此可将virtio-blk设备模拟成一种PCI设备,这样可复用虚拟机内部已有的PCI驱动。
virtio-blk设备从功能上来看,核心功能就是实现虚拟机内外的事件通知和数据传递:虚拟机内部的前端驱动准备好待处理的IO请求和数据存放空间并通知后端;虚拟机外部的后端程序获取待处理的请求并交给真正的IO子系统处理,完成后将处理结果通知前端。实际上,除了虚拟磁盘,虚拟网卡也完全可以复用这套机制,从而实现半模拟的网络前后端(virtio-net)。如果将virtio-blk或virtio-net设计成不同类型的PCI设备,那么前端驱动中会存在大量关于事件通知和数据传递的重复代码。
综上分析,virtio-blk首先是PCI设备;其次为了复用半模拟中通用的事件通知和数据传递机制,抽象出一类virtio-pci设备,其内部通过virtio总线连接不同的virtio设备。这样virtio-blk设备就通过virtio总线连接到virtio-blk-pci设备的PCI接口上,virtio-net也通过virtio总线连接到virtio-net-pci设备的PCI接口上。可能有的人会问,为何通过设备的抽象就能复用前端驱动的代码?在virtio-blk-pci或virtio-net-pci前端驱动加载时,最初识别到的都是virtio-pci设备,这样都可调用virtio-pci驱动进行事件通知和数据传递的初始化,后续也可使用virtio-pci中相关函数进行事件通知和数据传递。
因此virtio-blk完全是基于通用的virtio框架实现的磁盘前后端,virtio框架中最为核心的就是事件通知和数据传递机制。
使用VIRTIO_BLK (半虚拟化磁盘)
virtio_blk驱动使用Virtio API为客户机的提供了一个高效访问块设备I/O的方法。在QEMU/KVM对块设备使用virtio,需要两方面的配置:客户机中的前端驱动模块virtio_blk和宿主机中的QEMU提供后端处理程序。目前比较流行的Linux发行版一般都将virtio_blk编译为内核模块了,可以作为客户机直接使用virtio_blk,而windows中virtio驱动的安装方法已在5.1.2节中做了介绍。并且较新的qemu-kvm都是支持virtio block设备的后端处理程序的。
启动一个使用virtio_blk作为磁盘驱动的客户机,其qemu-kvm命令行如下。
[root@jay-linux kvm_demo]# qemu-system-x86_64 -smp 2 -m 1024 -net nic -net tap –drive file=rhel6u3.img,if=virtio
VNC server running on `::1:5900'
在客户机中,查看virtio_blk生效的情况如下所示。
[root@kvm-guest ~]# grep VIRTIO_BLK \ /boot/config-2.6.32-279.el6.x86_64
CONFIG_VIRTIO_BLK=m
root@virtio-scsi-nodiscard-ceph-sas:~# lsmod | grep virtio
virtio_balloon 16384 0
virtio_console 24576 1
virtio_scsi 20480 2
virtio_net 28672 0
virtio_pci 24576 0
virtio_ring 24576 5 virtio_net,virtio_scsi,virtio_balloon,virtio_console,virtio_pci
virtio 16384 5 virtio_net,virtio_scsi,virtio_balloon,virtio_console,virtio_pci
scsi_mod 225280 6 sd_mod,virtio_scsi,libata,scsi_transport_spi,sg,sym53c8xx
[root@kvm-guest ~]# lspci | grep -i block
00:04.0 SCSI storage controller: Red Hat, Inc Virtio block device
[root@kvm-guest ~]# lspci -vv -s 00:04.0
00:04.0 SCSI storage controller: Red Hat, Inc Virtio block device
Subsystem: Red Hat, Inc Device 0002
Physical Slot: 4
Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin A routed to IRQ 11
Region 0: I/O ports at c100 [size=64]
Region 1: Memory at febf2000 (32-bit, non-prefetchable) [size=4K]
Capabilities: [40] MSI-X: Enable+ Count=2 Masked-
Vector table: BAR=1 offset=00000000
PBA: BAR=1 offset=00000800
Kernel driver in use: virtio-pci
Kernel modules: virtio_pci
[root@kvm-guest ~]# fdisk -l
Disk /dev/vda: 8589 MB, 8589934592 bytes
16 heads, 63 sectors/track, 16644 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000726b0
Device Boot Start End Blocks Id System
/dev/vda1 * 3 14826 7471104 83 Linux
/dev/vda2 14826 16645 916480 82 Linux swap / Solaris
可知客户机中已经加载virtio_blk等驱动,SCSI磁盘设备是使用virtio_blk驱动(上面查询结果中显示为virtio_pci,因为它是作为任意virtio的PCI设备的一个基础、必备的驱动)。使用virtio_blk驱动的磁盘显示为“/dev/vda”,使用virtio_scsi驱动的磁盘显示为“/dev/sda”,这不同于IDE硬盘的“/dev/hda”或者SATA硬盘的“/dev/sda”这样的显示标识。
而“/dev/vd*”这样的磁盘设备名称可能会导致从前分配在磁盘上的swap分区失效,因为有些客户机系统中记录文件系统信息的“/etc/fstab”文件中有类似如下的对swap分区的写法。
/dev/sda2 swap swap defaults 0 0
或 /dev/hda2 swap swap defaults 0 0
原因就是换为“/dev/vda2”这样的磁盘分区名称未被正确识别,解决这个问题的方法就很简单了,只需要修改它为如下的形式并保存“/etc/fstab”文件,然后重启客户机系统即可。
/dev/vda2 swap swap defaults 0 0
如果启动的是已安装virtio驱动的Windows客户机,则在客户机的“设备管理器”中的“存储控制器”中看到的是正在使用“Red Hat VirtIO SCSI Controller”设备作为磁盘。
Related Posts:
- (KVM连载) 5.1.3 使用virtio_balloon(KVM中的Ballooning)(下)
- 如何挂载qcow2格式的镜像文件(how to mount a qcow2 image)
- (KVM连载) 5.1.4 使用virtio_net (半虚拟化网卡)
- virtio-blk-data-plane的配置使用
参考:
(KVM连载) 5.1.5 使用VIRTIO_BLK (半虚拟化磁盘)http://smilejay.com/2012/11/kvm-virtio-block/
https://lingxiankong.github.io/2014-11-17-virtio-blk.html
virtio-blk的影响
virtio scsi相比较virtio blk的强的地方
virtio-scsi功能是一种新的半虚拟化SCSI控制器设备。它是替代virtio-blk并改进其功能的KVM Virtualization存储堆栈的替代存储实现的基础。它提供与virtio-blk相同的性能,并增加了以下直接好处:
- 改进的可伸缩性 - 虚拟机可以连接到更多存储设备(virtio-scsi可以处理每个虚拟SCSI适配器的多个块设备)。
- 标准命令set-virtio-scsi使用标准SCSI命令集,简化了新功能的添加。
- 标准设备naming-virtio-scsi磁盘使用与裸机系统相同的路径。这简化了物理到虚拟和虚拟到虚拟的迁移。
- SCSI设备passthrough-virtio-scsi可以直接向guest虚拟机提供物理存储设备。
- 与virtio-blk相比,Virtio-SCSI能够直接连接到SCSI LUN并显着提高可扩展性。
virtio-SCSI的优势在于它能够处理数百个设备,而virtio-blk只能处理大约30个设备并耗尽PCI插槽。virtio-scsi旨在取代virtio-blk,保留了virtio-blk的性能优势,同时提高了存储可扩展性,允许通过单个控制器访问多个存储设备,并支持重用客户操作系统的SCSI堆栈。
virtio scsi的磁盘的命名为 /dev/sda,一般的命名为/dev/vda
virtio scsi的配置:对centos这个镜像执行以下操作:
# glance image-update --property hw_disk_bus=scsi centos
# glance image-update --property hw_scsi_model=virtio-scsi centos
创建好的虚机使用命令 lsblk查看
root@virtio-blk-test:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 254:0 0 20G 0 disk
└─vda1 254:1 0 20G 0 part /
vdb 254:16 0 64M 1 disk
vdc 254:32 0 200G 0 disk /home/cloud-disk
root@virtio-scsi-nodiscard-ceph-sas:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 20G 0 disk
└─sda1 8:1 0 20G 0 part /
sdb 8:16 0 200G 0 disk /home/cloud-disk
sdc 8:32 0 64M 1 disk
参考硬盘的接口方式:硬盘基础知识(HDD、SSD、IDE、PATA、SATA、SCSI、SAS)https://blog.csdn.net/u013721086/article/details/83933461
配置virtio-scsi:https://blog.csdn.net/zihulidejia/article/details/47953027
配置SCSI:virtio是一套半虚拟化驱动,包括网络、磁盘等。virtio-scsi和virtio-blk都是磁盘的半虚拟化驱动,virtio-scsi解决了virtio-blk的一些限制
查看内核是否支持配置SCSI
(my_new_env) likailiang@pubbeta1-nova10:~$ grep "VIRTIO" /boot/config-3.2.0-4-amd64
CONFIG_NET_9P_VIRTIO=m
CONFIG_VIRTIO_BLK=m
CONFIG_SCSI_VIRTIO=m
CONFIG_VIRTIO_NET=m
CONFIG_VIRTIO_CONSOLE=m
CONFIG_HW_RANDOM_VIRTIO=m
CONFIG_VIRTIO=m
CONFIG_VIRTIO_RING=m
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_BALLOON=m
# CONFIG_VIRTIO_MMIO is not set
(my_new_env) likailiang@pubbeta1-nova10:~$ grep "VIRTIO" /boot/config-3.10.45-openstack-amd64
CONFIG_NET_9P_VIRTIO=m
CONFIG_VIRTIO_BLK=m
CONFIG_SCSI_VIRTIO=m
CONFIG_VIRTIO_NET=m
CONFIG_VIRTIO_CONSOLE=m
CONFIG_HW_RANDOM_VIRTIO=m
CONFIG_VIRTIO=m
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_BALLOON=m
# CONFIG_VIRTIO_MMIO is not set
Centos6下Virtio-SCSI(multi-queues)/Virtio-SCSI/Virtio-blk性能对比:https://blog.csdn.net/bobpen/article/details/41515119