[libvirt] [PATCH V3 3/3] qemu: Add secondary-vga support

Wang Rui moon.wangrui at huawei.com
Thu Aug 14 12:43:55 UTC 2014


From: Zeng Junliang <zengjunliang at huawei.com>

Secondary-vga is supported by QEMU in currently master. Add it supported
in libvirt as qemu commandline show: '-device secondary-vga'. And it can
be used as secondary display device, like qxl. Also, add test cases and
descriptions for it.

Libvirt xml configuration sample:
<video>
  <model type='secondary' vgamem='16384' heads='1'/>
</video>

The resulting qemu command line change is the addition of:
-device secondary-vga,id=video0,vgamem_mb=16,bus=pci.0,addr=0x5

Signed-off-by: Zeng Junliang <zengjunliang at huawei.com>
Signed-off-by: Wang Rui <moon.wangrui at huawei.com>
---
 docs/formatdomain.html.in                          | 13 +++---
 docs/schemas/domaincommon.rng                      |  1 +
 src/conf/domain_conf.c                             |  9 ++--
 src/conf/domain_conf.h                             |  1 +
 src/qemu/qemu_capabilities.c                       |  2 +
 src/qemu/qemu_capabilities.h                       |  1 +
 src/qemu/qemu_command.c                            | 54 +++++++++++++++-------
 .../qemuxml2argv-graphics-vnc-secondary-vga.args   |  7 +++
 .../qemuxml2argv-graphics-vnc-secondary-vga.xml    | 39 ++++++++++++++++
 tests/qemuxml2argvtest.c                           |  4 ++
 tests/qemuxml2xmltest.c                            |  1 +
 11 files changed, 106 insertions(+), 26 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-secondary-vga.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-secondary-vga.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index a0d15c4..b1d8ad4 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4440,9 +4440,9 @@ qemu-kvm -net nic,model=? /dev/null
         device in domain xml is the primary one, but the optional attribute
         <code>primary</code> (<span class="since">since 1.0.2</span>) with
         value 'yes' can be used to mark the primary in cases of multiple video
-        device. The non-primary must be type of "qxl". The optional attribute
-        <code>ram</code> (<span class="since">since 1.0.2</span>) is allowed
-        for "qxl" type only and specifies the size of the primary bar,
+        device. The non-primary must be type of "qxl" or "secondary". The
+        optional attribute <code>ram</code> (<span class="since">since 1.0.2</span>)
+        is allowed for "qxl" type only and specifies the size of the primary bar,
         while <code>vram</code> specifies the secondary bar size.
         If "ram", "vram" or "vgamem" are not supplied a default value is used.
       </dd>
@@ -4451,8 +4451,9 @@ qemu-kvm -net nic,model=? /dev/null
       <dd>
         The <code>model</code> element has a mandatory <code>type</code>
         attribute which takes the value "vga", "cirrus", "vmvga", "xen",
-        "vbox", or "qxl" (<span class="since">since 0.8.6</span>)
-        depending on the hypervisor features available.
+        "vbox", "qxl" (<span class="since">since 0.8.6</span>) or
+        "secondary" (<span class="since">since 1.2.8</span>) depending
+        on the hypervisor features available.
         <p>
         <code>vram</code> attribute specifies the amount of video memory
         in kibibytes (blocks of 1024 bytes). For type of kvm, it is only
@@ -4462,7 +4463,7 @@ qemu-kvm -net nic,model=? /dev/null
         <code>vgamem</code> attribute <span class="since">since 1.2.8,
         QEMU and KVM only</span> specifies the size of the framebuffer
         portion of the "ram" region. And it is only valid for type of
-        "vga", "vmvga" and "qxl".
+        "vga", "vmvga", "qxl" and "secondary".
         </p>
         <p>
         <code>heads</code> attribute specifies the number of screen.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index b2cc218..db8dbde 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2768,6 +2768,7 @@
                 <value>vmvga</value>
                 <value>xen</value>
                 <value>vbox</value>
+                <value>secondary</value>
               </choice>
             </attribute>
             <group>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7097570..c7b9a5d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -490,7 +490,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
               "vmvga",
               "xen",
               "vbox",
-              "qxl")
+              "qxl",
+              "secondary")
 
 VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST,
               "mouse",
@@ -9646,7 +9647,8 @@ virDomainVideoDefaultVgamem(int type)
     case VIR_DOMAIN_VIDEO_TYPE_VGA:
     case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
     case VIR_DOMAIN_VIDEO_TYPE_QXL:
-        /* QEMU use 16M as default value for vga/vmvga/qxl device*/
+    case VIR_DOMAIN_VIDEO_TYPE_SECONDARY:
+        /* QEMU use 16M as default value for vga/vmvga/qxl/secondary device */
         return 16 * 1024;
 
     default:
@@ -9781,7 +9783,8 @@ virDomainVideoDefParseXML(xmlNodePtr node,
     if (vgamem) {
         if (def->type != VIR_DOMAIN_VIDEO_TYPE_VGA &&
             def->type != VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
-            def->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
+            def->type != VIR_DOMAIN_VIDEO_TYPE_QXL &&
+            def->type != VIR_DOMAIN_VIDEO_TYPE_SECONDARY) {
             virReportError(VIR_ERR_XML_ERROR,
                            _("Unsupported vgamem attribute for %s device"),
                              virDomainVideoTypeToString(def->type));
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d1ef6ec..9ead8a7 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1227,6 +1227,7 @@ typedef enum {
     VIR_DOMAIN_VIDEO_TYPE_XEN,
     VIR_DOMAIN_VIDEO_TYPE_VBOX,
     VIR_DOMAIN_VIDEO_TYPE_QXL,
+    VIR_DOMAIN_VIDEO_TYPE_SECONDARY,
 
     VIR_DOMAIN_VIDEO_TYPE_LAST
 } virDomainVideoType;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 146d67c..fed3244 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -269,6 +269,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
 
               "qxl-vgamem", /* 175 */
               "vmware-vgamem",
+              "secondary-vga",
     );
 
 
@@ -1470,6 +1471,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
     { "spicevmc", QEMU_CAPS_DEVICE_SPICEVMC },
     { "qxl-vga", QEMU_CAPS_DEVICE_QXL_VGA },
     { "qxl", QEMU_CAPS_DEVICE_QXL },
+    { "secondary-vga", QEMU_CAPS_DEVICE_SECONDARY_VGA },
     { "sga", QEMU_CAPS_SGA },
     { "scsi-block", QEMU_CAPS_SCSI_BLOCK },
     { "scsi-cd", QEMU_CAPS_SCSI_CD },
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index cdf6920..f6d158d 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -216,6 +216,7 @@ typedef enum {
     QEMU_CAPS_VGA_VGAMEM_MB      = 174, /* -global VGA.vgamem_mb */
     QEMU_CAPS_QXL_VGAMEM_MB      = 175, /* -global qxl-vga.vgamem_mb */
     QEMU_CAPS_VMWARE_VGAMEM_MB   = 176, /* -global vmware-svga.vgamem_mb */
+    QEMU_CAPS_DEVICE_SECONDARY_VGA = 177, /* -device secondary-vga */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c15099a..35ab29a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -109,7 +109,9 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
               "vmware",
               "", /* no arg needed for xen */
               "", /* don't support vbox */
-              "qxl");
+              "qxl",
+              ""); /* '-vga XXX' for secondary-vga device
+                    * is currently not supported with QEMU */
 
 VIR_ENUM_DECL(qemuDeviceVideo)
 
@@ -119,7 +121,8 @@ VIR_ENUM_IMPL(qemuDeviceVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
               "vmware-svga",
               "", /* no device for xen */
               "", /* don't support vbox */
-              "qxl-vga");
+              "qxl-vga",
+              "secondary-vga");
 
 VIR_ENUM_DECL(qemuSoundCodec)
 
@@ -2257,11 +2260,13 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
                                                flags) < 0)
             goto error;
     }
-    /* Further non-primary video cards which have to be qxl type */
+    /* Further non-primary video cards which have to be qxl or secondary */
     for (i = 1; i < def->nvideos; i++) {
-        if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
+        if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL &&
+            def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_SECONDARY) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("non-primary video device must be type of 'qxl'"));
+                           _("non-primary video device must be "
+                             "type of 'qxl' or 'secondary'"));
             goto error;
         }
         if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
@@ -4789,19 +4794,31 @@ qemuBuildDeviceVideoStr(virDomainDefPtr def,
             goto error;
         }
     } else {
-        if (video->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           "%s", _("non-primary video device must be type of 'qxl'"));
-            goto error;
-        }
-
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL)) {
+        switch (video->type) {
+        case VIR_DOMAIN_VIDEO_TYPE_QXL:
+            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("video type %s is not supported with QEMU"),
+                               virDomainVideoTypeToString(video->type));
+                goto error;
+            }
+            model = "qxl";
+            break;
+        case VIR_DOMAIN_VIDEO_TYPE_SECONDARY:
+            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SECONDARY_VGA)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("video type %s is not supported with QEMU"),
+                               virDomainVideoTypeToString(video->type));
+                goto error;
+            }
+            model = "secondary-vga";
+            break;
+        default:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           "%s", _("only one video card is currently supported"));
+                           "%s", _("non-primary video device must be "
+                           "type of 'qxl' or 'secondary'"));
             goto error;
         }
-
-        model = "qxl";
     }
 
     virBufferAsprintf(&buf, "%s,id=%s", model, video->info.alias);
@@ -8742,7 +8759,9 @@ qemuBuildCommandLine(virConnectPtr conn,
              (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
                  virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMWARE_SVGA)) ||
              (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL &&
-                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)))
+                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)) ||
+             (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_SECONDARY &&
+                 virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SECONDARY_VGA)))
            ) {
             for (i = 0; i < def->nvideos; i++) {
                 char *str;
@@ -8862,7 +8881,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
                     for (i = 1; i < def->nvideos; i++) {
                         char *str;
-                        if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
+                        if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL &&
+                            def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_SECONDARY) {
                             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                            _("video type %s is only valid as primary video card"),
                                            virDomainVideoTypeToString(def->videos[0]->type));
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-secondary-vga.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-secondary-vga.args
new file mode 100644
index 0000000..b5e075a
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-secondary-vga.args
@@ -0,0 +1,7 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M pc -m 214 -smp 1 -nodefaults -monitor unix:/tmp/test-monitor,\
+server,nowait -no-acpi -boot c -usb -hda /dev/HostVG/QEMUGuest1 \
+-vnc 127.0.0.1:3 \
+-device secondary-vga,id=video0,vgamem_mb=16,bus=pci.0,addr=0x2 \
+-device secondary-vga,id=video1,vgamem_mb=16,bus=pci.0,addr=0x4 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-secondary-vga.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-secondary-vga.xml
new file mode 100644
index 0000000..03b9154
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-secondary-vga.xml
@@ -0,0 +1,39 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'>
+      <listen type='address' address='127.0.0.1'/>
+    </graphics>
+    <video>
+      <model type='secondary' vgamem='16384' heads='1'/>
+    </video>
+    <video>
+      <model type='secondary' vgamem='16384' heads='1'/>
+    </video>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index a7cbb02..5eb5776 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -879,6 +879,10 @@ mymain(void)
             QEMU_CAPS_VNC, QEMU_CAPS_DEVICE,
             QEMU_CAPS_VGA, QEMU_CAPS_DEVICE_VMWARE_SVGA,
             QEMU_CAPS_VMWARE_VGAMEM_MB);
+    DO_TEST("graphics-vnc-secondary-vga",
+             QEMU_CAPS_VNC, QEMU_CAPS_DEVICE,
+             QEMU_CAPS_DEVICE_SECONDARY_VGA,
+             QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
 
     driver.config->vncSASL = 1;
     VIR_FREE(driver.config->vncSASLdir);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 720b058..1ab5f1d 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -240,6 +240,7 @@ mymain(void)
     DO_TEST("graphics-vnc-tls");
     DO_TEST("graphics-vnc-std-vga");
     DO_TEST("graphics-vnc-vmware-svga");
+    DO_TEST("graphics-vnc-secondary-vga");
     DO_TEST("graphics-sdl");
     DO_TEST("graphics-sdl-fullscreen");
     DO_TEST("graphics-spice");
-- 
1.7.12.4





More information about the libvir-list mailing list