[libvirt] [PATCHv5 13/13] qemu: format options for enforcing virtio revisions

Ján Tomko jtomko at redhat.com
Tue Aug 23 22:20:55 UTC 2016


https://bugzilla.redhat.com/show_bug.cgi?id=1227354

Translate the optional <driver compatibility> attributes to
disable-legacy=on/off and disable-modern=on/off options
for the following devices:

<memballoon>    virtio-balloon-pci
<disk>          virtio-blk-pci
<controller>    virtio-scsi-pci
                virtio-serial-pci
<filesystem>    virtio-9p-pci
<interface>     virtio-net-pci
<rng>           virtio-rng-pci
<video>         virtio-gpu-pci
<input>         virtio-input-host-pci
                virtio-keyboard-pci
                virtio-mouse-pci
                virtio-tablet-pci
---
 src/qemu/qemu_command.c                            | 70 ++++++++++++++++++++++
 .../qemuxml2argv-virtio-revision.args              | 62 +++++++++++++++++++
 tests/qemuxml2argvtest.c                           | 11 ++++
 3 files changed, 143 insertions(+)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-virtio-revision.args

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a6dea6a..470d84c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -378,6 +378,46 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
 }
 
 static int
+qemuBuildVirtioCompatibilityStr(virBufferPtr buf,
+                                virDomainDriverCompatibility compat,
+                                virDomainDeviceInfoPtr info,
+                                virQEMUCapsPtr qemuCaps)
+{
+    if (!compat)
+        return 0;
+
+    if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("setting the virtio revision is only supported "
+                         "for PCI devices"));
+        return -1;
+    }
+
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("setting the virtio revision is not supported with "
+                         "this QEMU binary"));
+        return -1;
+    }
+
+    switch (compat) {
+    case VIR_DOMAIN_DRIVER_COMPATIBILITY_LEGACY:
+        virBufferAddLit(buf, ",disable-legacy=off,disable-modern=on");
+        break;
+    case VIR_DOMAIN_DRIVER_COMPATIBILITY_TRANSITIONAL:
+        virBufferAddLit(buf, ",disable-legacy=off,disable-modern=off");
+        break;
+    case VIR_DOMAIN_DRIVER_COMPATIBILITY_MODERN:
+        virBufferAddLit(buf, ",disable-legacy=on,disable-modern=off");
+        break;
+    case VIR_DOMAIN_DRIVER_COMPATIBILITY_DEFAULT:
+    case VIR_DOMAIN_DRIVER_COMPATIBILITY_LAST:
+        break;
+    }
+    return 0;
+}
+
+static int
 qemuBuildRomStr(virBufferPtr buf,
                 virDomainDeviceInfoPtr info)
 {
@@ -1993,6 +2033,11 @@ qemuBuildDriveDevStr(const virDomainDef *def,
                               (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN)
                               ? "on" : "off");
         }
+
+        if (qemuBuildVirtioCompatibilityStr(&opt, disk->compatibility, &disk->info,
+                                       qemuCaps) < 0)
+            goto error;
+
         if (qemuBuildDeviceAddressStr(&opt, def, &disk->info, qemuCaps) < 0)
             goto error;
         break;
@@ -2314,6 +2359,8 @@ qemuBuildFSDevStr(const virDomainDef *def,
                       QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
     virBufferAsprintf(&opt, ",mount_tag=%s", fs->dst);
 
+    qemuBuildVirtioCompatibilityStr(&opt, fs->compatibility, &fs->info, qemuCaps);
+
     if (qemuBuildDeviceAddressStr(&opt, def, &fs->info, qemuCaps) < 0)
         goto error;
 
@@ -2569,6 +2616,9 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
                                       def->iothread);
                 }
             }
+            if (qemuBuildVirtioCompatibilityStr(&buf, def->compatibility, &def->info,
+                                           qemuCaps) < 0)
+                goto error;
             break;
         case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
             virBufferAddLit(&buf, "lsi");
@@ -2614,6 +2664,9 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef,
             virBufferAsprintf(&buf, ",vectors=%d",
                               def->opts.vioserial.vectors);
         }
+        if (qemuBuildVirtioCompatibilityStr(&buf, def->compatibility, &def->info,
+                                       qemuCaps) < 0)
+            goto error;
         break;
 
     case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
@@ -3560,12 +3613,16 @@ qemuBuildNicDevStr(virDomainDefPtr def,
     virBufferAsprintf(&buf, ",id=%s", net->info.alias);
     virBufferAsprintf(&buf, ",mac=%s",
                       virMacAddrFormat(&net->mac, macaddr));
+
     if (qemuBuildDeviceAddressStr(&buf, def, &net->info, qemuCaps) < 0)
         goto error;
     if (qemuBuildRomStr(&buf, &net->info) < 0)
         goto error;
     if (bootindex && virQEMUCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX))
         virBufferAsprintf(&buf, ",bootindex=%u", bootindex);
+    if (usingVirtio &&
+        qemuBuildVirtioCompatibilityStr(&buf, net->compatibility, &net->info, qemuCaps) < 0)
+        goto error;
 
     if (virBufferCheckError(&buf) < 0)
         goto error;
@@ -3830,6 +3887,10 @@ qemuBuildMemballoonCommandLine(virCommandPtr cmd,
                           virTristateSwitchTypeToString(def->memballoon->autodeflate));
     }
 
+    if (qemuBuildVirtioCompatibilityStr(&buf, def->memballoon->compatibility,
+                                   &def->memballoon->info, qemuCaps) < 0)
+        goto error;
+
     virCommandAddArg(cmd, "-device");
     virCommandAddArgBuffer(cmd, &buf);
     return 0;
@@ -3960,6 +4021,9 @@ qemuBuildVirtioInputDevStr(const virDomainDef *def,
     if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
         goto error;
 
+    if (qemuBuildVirtioCompatibilityStr(&buf, dev->compatibility, &dev->info, qemuCaps) < 0)
+        goto error;
+
     if (virBufferCheckError(&buf) < 0)
         goto error;
 
@@ -4323,6 +4387,9 @@ qemuBuildDeviceVideoStr(const virDomainDef *def,
     if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
         goto error;
 
+    if (qemuBuildVirtioCompatibilityStr(&buf, video->compatibility, &video->info, qemuCaps) < 0)
+        goto error;
+
     if (virBufferCheckError(&buf) < 0)
         goto error;
 
@@ -5569,6 +5636,9 @@ qemuBuildRNGDevStr(const virDomainDef *def,
             virBufferAddLit(&buf, ",period=1000");
     }
 
+    if (qemuBuildVirtioCompatibilityStr(&buf, dev->compatibility, &dev->info, qemuCaps) < 0)
+        goto error;
+
     if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
         goto error;
     if (virBufferCheckError(&buf) < 0)
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-revision.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-revision.args
new file mode 100644
index 0000000..4ef7663
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-revision.args
@@ -0,0 +1,62 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-name QEMUGuest1 \
+-S \
+-M pc \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-monitor unix:/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server,nowait \
+-no-acpi \
+-boot c \
+-device virtio-scsi-pci,disable-legacy=off,disable-modern=off,id=scsi0,\
+bus=pci.0,addr=0x8 \
+-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x9 \
+-usb \
+-drive file=/var/lib/libvirt/images/img1,format=raw,if=none,\
+id=drive-virtio-disk0 \
+-device virtio-blk-pci,disable-legacy=off,disable-modern=on,bus=pci.0,addr=0xa,\
+drive=drive-virtio-disk0,id=virtio-disk0 \
+-drive file=/var/lib/libvirt/images/img2,format=raw,if=none,\
+id=drive-virtio-disk1 \
+-device virtio-blk-pci,disable-legacy=on,disable-modern=off,bus=pci.0,addr=0xb,\
+drive=drive-virtio-disk1,id=virtio-disk1 \
+-drive file=/var/lib/libvirt/images/img3,format=raw,if=none,\
+id=drive-scsi0-0-0-0 \
+-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\
+drive=drive-scsi0-0-0-0,id=scsi0-0-0-0 \
+-fsdev local,security_model=passthrough,id=fsdev-fs0,path=/export/fs1 \
+-device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=fs1,disable-legacy=off,\
+disable-modern=on,bus=pci.0,addr=0x3 \
+-fsdev local,security_model=mapped,writeout=immediate,id=fsdev-fs1,\
+path=/export/fs2 \
+-device virtio-9p-pci,id=fs1,fsdev=fsdev-fs1,mount_tag=fs2,disable-legacy=on,\
+disable-modern=off,bus=pci.0,addr=0x4 \
+-device virtio-net-pci,vlan=0,id=net0,mac=52:54:56:58:5a:5c,bus=pci.0,addr=0x6,\
+disable-legacy=off,disable-modern=on \
+-net user,vlan=0,name=hostnet0 \
+-device virtio-net-pci,vlan=1,id=net1,mac=52:54:56:5a:5c:5e,bus=pci.0,addr=0x7,\
+disable-legacy=on,disable-modern=off \
+-net user,vlan=1,name=hostnet1 \
+-device virtio-mouse-pci,id=input0,bus=pci.0,addr=0xe,disable-legacy=on,\
+disable-modern=off \
+-device virtio-keyboard-pci,id=input1,bus=pci.0,addr=0x10,disable-legacy=on,\
+disable-modern=off \
+-device virtio-tablet-pci,id=input2,bus=pci.0,addr=0x11,disable-legacy=on,\
+disable-modern=off \
+-device virtio-input-host-pci,id=input3,evdev=/dev/input/event1234,bus=pci.0,\
+addr=0x12,disable-legacy=on,disable-modern=off \
+-device virtio-vga,id=video0,virgl=on,bus=pci.0,addr=0x2,disable-legacy=on,\
+disable-modern=off \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0xc,disable-legacy=off,\
+disable-modern=off \
+-object rng-random,id=objrng0,filename=/dev/random \
+-device virtio-rng-pci,rng=objrng0,id=rng0,disable-legacy=on,\
+disable-modern=off,bus=pci.0,addr=0xd
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index e8b8cb4..8a29427 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2106,6 +2106,17 @@ mymain(void)
     DO_TEST("intel-iommu", QEMU_CAPS_DEVICE_PCI_BRIDGE,
             QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_DEVICE_INTEL_IOMMU);
 
+    DO_TEST("virtio-revision", QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_VIRTIO_KEYBOARD,
+            QEMU_CAPS_VIRTIO_MOUSE, QEMU_CAPS_VIRTIO_TABLET,
+            QEMU_CAPS_VIRTIO_INPUT_HOST,
+            QEMU_CAPS_FSDEV, QEMU_CAPS_FSDEV_WRITEOUT,
+            QEMU_CAPS_DEVICE_VIRTIO_GPU,
+            QEMU_CAPS_DEVICE_VIRTIO_GPU_VIRGL,
+            QEMU_CAPS_DEVICE_VIRTIO_RNG,
+            QEMU_CAPS_OBJECT_RNG_RANDOM,
+            QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
+            QEMU_CAPS_VIRTIO_PCI_DISABLE_LEGACY);
+
     qemuTestDriverFree(&driver);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
-- 
2.7.3




More information about the libvir-list mailing list