QEMU monitor有一个命令pci_add,用来hotadd pci 设备。启动 qemu的时候加入参数 -monitor stdio.
QEMU 1.1.90 monitor - type 'help' for more information (qemu) help pci_add pci_add auto|[[<domain>:]<bus>:]<slot> nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]... -- hot-add PCI device
增加一个disk
hot-add个disk意味着 hot-add 个PCI设备,所以想正常工作需要在guest中加入PCI hotplug的支持。
下面的命令会在guest中加入一个scsi磁盘:
* pci_add auto storage file=/home/sina/work/system/empty.img,if=scsi也可依用if=virtio来替换 if=scsi,但是IDE不是hotpluggable
00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02) 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II] 00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II] 00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03) 00:02.0 VGA compatible controller: Cirrus Logic GD 5446 00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 03)
00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02) 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II] 00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II] 00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03) 00:02.0 VGA compatible controller: Cirrus Logic GD 5446 00:03.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 03) 00:04.0 SCSI storage controller: LSI Logic / Symbios Logic 53c895a
[ 93.533872] ACPI: PCI Interrupt Link [LNKD] enabled at IRQ 10 [ 93.533951] sym53c8xx 0000:00:04.0: PCI INT A -> Link[LNKD] -> GSI 10 (level, high) -> IRQ 10 [ 93.537031] sym0: <895a> rev 0x0 at pci 0000:00:04.0 irq 10 [ 93.539563] sym0: No NVRAM, ID 7, Fast-40, LVD, parity checking [ 93.540029] sym0: SCSI BUS has been reset. [ 93.554166] scsi2 : sym-2.2.3 [ 96.556817] sym0: unknown interrupt(s) ignored, ISTAT=0x5 DSTAT=0x80 SIST=0x0 [ 96.556981] scsi 2:0:0:0: Direct-Access QEMU QEMU HARDDISK 1.1. PQ: 0 ANSI: 5 [ 96.557004] scsi target2:0:0: tagged command queuing enabled, command queue depth 16. [ 96.557021] scsi target2:0:0: Beginning Domain Validation [ 96.559328] scsi target2:0:0: Domain Validation skipping write tests [ 96.559335] scsi target2:0:0: Ending Domain Validation [ 96.578176] sd 2:0:0:0: [sdb] 1048576 512-byte logical blocks: (536 MB/512 MiB) [ 96.578647] sd 2:0:0:0: [sdb] Write Protect is off [ 96.578651] sd 2:0:0:0: [sdb] Mode Sense: 63 00 00 08 [ 96.579001] sd 2:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA [ 96.583432] sd 2:0:0:0: Attached scsi generic sg2 type 0 [ 96.585323] sdb: unknown partition table [ 96.586613] sd 2:0:0:0: [sdb] Attached SCSI disk
增加NIC设备
pci_add auto nic model=e1000
可以用 model=rtl8139, model=virtio, or model=ne2k_pci 来替换model=e1000。
(qemu) pci_add auto nic model=e1000
( 注意 测试时用户空间的程序应使用 qemu-kvm ,而不是qemu)
在monitor 中拔除pci设备:
(qemu)pci_del slot_num
其中slot_num为pci_add成功时所提示的slot号。
2、代码跟踪:
使用gdb对qemu的pci_add后执行的代码进行跟踪以便动态地分析QEMU的热插拔机制:
pci_device_hot_add 函数将会被调用,该函数首先获得pci_add的参数:
PCIDevice *dev = NULL; const char *pci_addr = qdict_get_str(qdict, "pci_addr"); const char *type = qdict_get_str(qdict, "type"); const char *opts = qdict_get_try_str(qdict, "opts");对于我们上面执行的pci_add命令,解析后:
if (strcmp(type, "nic") == 0) { dev = qemu_pci_hot_add_nic(mon, pci_addr, opts); } else if (strcmp(type, "storage") == 0) { dev = qemu_pci_hot_add_storage(mon, pci_addr, opts); } else { monitor_printf(mon, "invalid type: %s\n", type); }进入 qemu_pci_hot_add_storage(mon,pci_addr,opts) 函数,该函数需要返回一个PCIDevice的指针。