[libvirt] [PATCH V2 2/6] qemu: Introduce vgamem attribute for video model

Wang Rui moon.wangrui at huawei.com
Mon Jul 14 11:20:44 UTC 2014


From: Zeng Junliang <zengjunliang at huawei.com>

This patch introduces vgamem attribute for video model, and sets
its default value as qemu used. Parse it in two ways accroding to
qemu startup parameters supported: -device or -vga.

Signed-off-by: Zeng Junliang <zengjunliang at huawei.com>
Signed-off-by: Wang Rui <moon.wangrui at huawei.com>
---
 src/conf/domain_conf.c   | 48 ++++++++++++++++++++++++++++++-
 src/conf/domain_conf.h   |  3 +-
 src/libvirt_private.syms |  1 +
 src/qemu/qemu_command.c  | 75 ++++++++++++++++++++++++++++++++----------------
 4 files changed, 101 insertions(+), 26 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 63d97ec..d5a65c3 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9328,6 +9328,20 @@ virDomainVideoDefaultRAM(const virDomainDef *def,
     }
 }
 
+int
+virDomainVideoDefaultVgamem(int type)
+{
+    switch (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*/
+        return 16 * 1024;
+
+    default:
+        return 0;
+    }
+}
 
 int
 virDomainVideoDefaultType(const virDomainDef *def)
@@ -9413,6 +9427,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
     char *type = NULL;
     char *heads = NULL;
     char *vram = NULL;
+    char *vgamem = NULL;
     char *ram = NULL;
     char *primary = NULL;
 
@@ -9422,11 +9437,12 @@ virDomainVideoDefParseXML(xmlNodePtr node,
     cur = node->children;
     while (cur != NULL) {
         if (cur->type == XML_ELEMENT_NODE) {
-            if (!type && !vram && !ram && !heads &&
+            if (!type && !vram && !ram && !heads && !vgamem &&
                 xmlStrEqual(cur->name, BAD_CAST "model")) {
                 type = virXMLPropString(cur, "type");
                 ram = virXMLPropString(cur, "ram");
                 vram = virXMLPropString(cur, "vram");
+                vgamem = virXMLPropString(cur, "vgamem");
                 heads = virXMLPropString(cur, "heads");
 
                 if ((primary = virXMLPropString(cur, "primary")) != NULL) {
@@ -9490,6 +9506,24 @@ virDomainVideoDefParseXML(xmlNodePtr node,
         def->vram = virDomainVideoDefaultRAM(dom, def->type);
     }
 
+    if (vgamem) {
+        if (def->type != VIR_DOMAIN_VIDEO_TYPE_VGA &&
+            def->type != VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
+            def->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("vgamem attribute only supported "
+                             "for type of vga, vmvga and qxl"));
+            goto error;
+        }      
+        if (virStrToLong_ui(vgamem, NULL, 10, &def->vgamem) < 0) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("cannot parse video vgamem '%s'"), vgamem);
+            goto error;
+        }
+    } else {
+        def->vgamem = virDomainVideoDefaultVgamem(def->type);
+    }  
+
     if (heads) {
         if (virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -9506,6 +9540,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
     VIR_FREE(type);
     VIR_FREE(ram);
     VIR_FREE(vram);
+    VIR_FREE(vgamem);
     VIR_FREE(heads);
 
     return def;
@@ -9515,6 +9550,7 @@ virDomainVideoDefParseXML(xmlNodePtr node,
     VIR_FREE(type);
     VIR_FREE(ram);
     VIR_FREE(vram);
+    VIR_FREE(vgamem);
     VIR_FREE(heads);
     return NULL;
 }
@@ -12636,6 +12672,7 @@ virDomainDefParseXML(xmlDocPtr xml,
             VIR_FREE(video);
             goto error;
         }
+        video->vgamem = virDomainVideoDefaultVgamem(video->type);
         video->vram = virDomainVideoDefaultRAM(def, video->type);
         video->heads = 1;
         if (VIR_ALLOC_N(def->videos, 1) < 0) {
@@ -13558,6 +13595,13 @@ virDomainVideoDefCheckABIStability(virDomainVideoDefPtr src,
         return false;
     }
 
+    if (src->vgamem!= dst->vgamem) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target video card vgamem %u does not match source %u"),
+                       dst->vgamem, src->vgamem);
+        return false;
+    }
+
     if (src->heads != dst->heads) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Target video card heads %u does not match source %u"),
@@ -16532,6 +16576,8 @@ virDomainVideoDefFormat(virBufferPtr buf,
         virBufferAsprintf(buf, " ram='%u'", def->ram);
     if (def->vram)
         virBufferAsprintf(buf, " vram='%u'", def->vram);
+    if (def->vgamem)
+        virBufferAsprintf(buf, " vgamem='%u'", def->vgamem);
     if (def->heads)
         virBufferAsprintf(buf, " heads='%u'", def->heads);
     if (def->primary)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 32674e0..a63ec84 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1216,6 +1216,7 @@ struct _virDomainVideoDef {
     int type;
     unsigned int ram;  /* kibibytes (multiples of 1024) */
     unsigned int vram; /* kibibytes (multiples of 1024) */
+    unsigned int vgamem; /* kibibytes (multiples of 1024) */
     unsigned int heads;
     bool primary;
     virDomainVideoAccelDefPtr accel;
@@ -2459,7 +2460,7 @@ virDomainFSDefPtr virDomainFSRemove(virDomainDefPtr def, size_t i);
 
 int virDomainVideoDefaultType(const virDomainDef *def);
 int virDomainVideoDefaultRAM(const virDomainDef *def, int type);
-
+int virDomainVideoDefaultVgamem(int type);
 int virDomainObjListNumOfDomains(virDomainObjListPtr doms,
                                  bool active,
                                  virDomainObjListFilter filter,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index e59ea4c..18d5c17 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -434,6 +434,7 @@ virDomainVcpuPinDel;
 virDomainVcpuPinFindByVcpu;
 virDomainVcpuPinIsDuplicate;
 virDomainVideoDefaultRAM;
+virDomainVideoDefaultVgamem;
 virDomainVideoDefaultType;
 virDomainVideoDefFree;
 virDomainVideoTypeFromString;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2185ef4..cb6d6e2 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4812,6 +4812,13 @@ qemuBuildDeviceVideoStr(virDomainDefPtr def,
         virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024);
     }
 
+    /* 1. Ignore cirrus-vga as guests would not use it anyway.
+     * 2. QEMU accepts MByte for vgamem_mb and ensure its value
+     * a power of two and range: 1 MB -> 256 MB */
+    if (video->type != VIR_DOMAIN_VIDEO_TYPE_CIRRUS) {
+        virBufferAsprintf(&buf, ",vgamem_mb=%u", video->vgamem / 1024);
+    }
+
     if (qemuBuildDeviceAddressStr(&buf, def, &video->info, qemuCaps) < 0)
         goto error;
 
@@ -8499,36 +8506,55 @@ qemuBuildCommandLine(virConnectPtr conn,
 
                 virCommandAddArgList(cmd, "-vga", vgastr, NULL);
 
-                if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL &&
-                    (def->videos[0]->vram || def->videos[0]->ram) &&
-                    virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
-                    const char *dev = (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)
-                                       ? "qxl-vga" : "qxl");
+                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
+                    const char *dev = NULL;
                     int ram = def->videos[0]->ram;
                     int vram = def->videos[0]->vram;
+                    switch (primaryVideoType) {
+                    case VIR_DOMAIN_VIDEO_TYPE_VGA:
+                        dev = (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VGA)
+                                   ? "VGA" : NULL);
+                        break;
+                    case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
+                        dev = (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMWARE_SVGA)
+                                   ? "vmware-svga" : NULL);
+                        break;
+                    case VIR_DOMAIN_VIDEO_TYPE_QXL:
+                        dev = (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QXL_VGA)
+                                   ? "qxl-vga" : "qxl");
+                        if (vram > (UINT_MAX / 1024)) {
+                            virReportError(VIR_ERR_OVERFLOW,
+                                   _("value for 'vram' must be less than '%u'"),
+                                           UINT_MAX / 1024);
+                            goto error;
+                        }
+                        if (ram > (UINT_MAX / 1024)) {
+                            virReportError(VIR_ERR_OVERFLOW,
+                                   _("value for 'ram' must be less than '%u'"),
+                                           UINT_MAX / 1024);
+                            goto error;
+                        }
 
-                    if (vram > (UINT_MAX / 1024)) {
-                        virReportError(VIR_ERR_OVERFLOW,
-                               _("value for 'vram' must be less than '%u'"),
-                                       UINT_MAX / 1024);
-                        goto error;
-                    }
-                    if (ram > (UINT_MAX / 1024)) {
-                        virReportError(VIR_ERR_OVERFLOW,
-                           _("value for 'ram' must be less than '%u'"),
-                                       UINT_MAX / 1024);
-                        goto error;
-                    }
+                        if (ram) {
+                            virCommandAddArg(cmd, "-global");
+                            virCommandAddArgFormat(cmd, "%s.ram_size=%u",
+                                                   dev, ram * 1024);
+                        }
+                        if (vram) {
+                            virCommandAddArg(cmd, "-global");
+                            virCommandAddArgFormat(cmd, "%s.vram_size=%u",
+                                                   dev, vram * 1024);
+                        }
 
-                    if (ram) {
-                        virCommandAddArg(cmd, "-global");
-                        virCommandAddArgFormat(cmd, "%s.ram_size=%u",
-                                               dev, ram * 1024);
+                        break;
                     }
-                    if (vram) {
+
+                    if (dev) {
+                        /* QEMU accepts MByte for vgamem_mb and ensure its value
+                         * a power of two and range: 1 MB -> 256 MB */
                         virCommandAddArg(cmd, "-global");
-                        virCommandAddArgFormat(cmd, "%s.vram_size=%u",
-                                               dev, vram * 1024);
+                        virCommandAddArgFormat(cmd, "%s.vgamem_mb=%u",
+                                               dev, def->videos[0]->vgamem / 1024);
                     }
                 }
             }
@@ -11497,6 +11523,7 @@ qemuParseCommandLine(virCapsPtr qemuCaps,
             vid->type = VIR_DOMAIN_VIDEO_TYPE_XEN;
         else
             vid->type = video;
+        vid->vgamem = virDomainVideoDefaultVgamem(vid->type);
         vid->vram = virDomainVideoDefaultRAM(def, vid->type);
         vid->ram = vid->type == VIR_DOMAIN_VIDEO_TYPE_QXL ?
                        virDomainVideoDefaultRAM(def, vid->type) : 0;
-- 
1.7.12.4





More information about the libvir-list mailing list