qemu-kvm ... -device virtio-scsi-pci,id=scsi \ -drive if=none,id=hda,file=<path>,cache=none,format=raw,serial=MPIO \ -device scsi-hd,drive=hda \ -drive if=none,id=hdb,file=<path>,cache=none,format=raw,serial=MPIO \ -device scsi-hd,drive=hdb"
- <path> should be replaced with a file or device path (the same for each)
- serial= specifies the SCSI logical unit serial number
Once booted, the SCSI devices for each corresponding path appear as sda and sdb, which are then detected as multipath enabled and subsequently mapped as dm-0:
Starting Device-Mapper Multipath Device Controller... [ OK ] Started Device-Mapper Multipath Device Controller. ... [ 1.329668] device-mapper: multipath service-time: version 0.3.0 loaded ... rapido1:/# multipath -ll 0QEMU_QEMU_HARDDISK_MPIO dm-0 QEMU,QEMU HARDDISK size=2.0G features='1 retain_attached_hw_handler' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=1 status=active | `- 0:0:0:0 sda 8:0 active ready running `-+- policy='service-time 0' prio=1 status=enabled `- 0:0:1:0 sdb 8:16 active ready running
QEMU additionally allows for virtual device hot(un)plug at runtime, which can be done from the QEMU monitor CLI (accessed via ctrl-a c) using the drive_del command. This can be used to trigger a multipath failover event:
rapido1:/# mkfs.xfs /dev/dm-0 meta-data=/dev/dm-0 isize=256 agcount=4, agsize=131072 blks = sectsz=512 attr=2, projid32bit=1 = crc=0 finobt=0, sparse=0 data = bsize=4096 blocks=524288, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 rapido1:/# mount /dev/dm-0 /mnt/ [ 96.846919] XFS (dm-0): Mounting V4 Filesystem [ 96.851383] XFS (dm-0): Ending clean mount rapido1:/# QEMU 2.6.2 monitor - type 'help' for more information (qemu) drive_del hda (qemu) rapido1:/# echo io-to-trigger-path-failure > /mnt/failover-trigger [ 190.926579] sd 0:0:0:0: [sda] tag#0 UNKNOWN(0x2003) Result: hostbyte=0x00 driverbyte=0x08 [ 190.926588] sd 0:0:0:0: [sda] tag#0 Sense Key : 0x2 [current] [ 190.926589] sd 0:0:0:0: [sda] tag#0 ASC=0x3a ASCQ=0x0 [ 190.926590] sd 0:0:0:0: [sda] tag#0 CDB: opcode=0x28 28 00 00 00 00 02 00 00 01 00 [ 190.926591] blk_update_request: I/O error, dev sda, sector 2 [ 190.926597] device-mapper: multipath: Failing path 8:0. rapido1:/# multipath -ll 0QEMU_QEMU_HARDDISK_MPIO dm-0 QEMU,QEMU HARDDISK size=2.0G features='1 retain_attached_hw_handler' hwhandler='0' wp=rw |-+- policy='service-time 0' prio=0 status=enabled | `- 0:0:0:0 sda 8:0 failed faulty running `-+- policy='service-time 0' prio=1 status=active `- 0:0:1:0 sdb 8:16 active ready running
The above procedure demonstrates cable-pull simulation while the broken path is used by the mounted dm-0 device. The subsequent I/O failure triggers multipath failover to the remaining good path.
I've added this functionality to Rapido (pull-request) so that multipath failover can be performed in a couple of minutes directly from kernel source. I encourage you to give it a try for yourself!