On Tuesday 19 May 2009 11:35:40 Daniel P. Berrange wrote:
We discussed adding a new XML element for representing video devices
a
few weeks back. This is my work in progress patch for the XML parsing
routines supporting
<video>
<model type='vga|cirrus|vmvga|xen' vram='64'
heads='1'/>
</video>
For compatability, if an existing guest has a <graphics> tag, but no
<video> tag, then the parser automatically adds a <video> tag for
type=cirrus. Still todo
- Tweak the addition of default <video> tag a little so it uses the
correct type for the type of guest - eg it should use type=xen in
some cases.
- Add RNG XML schemas & website docs
- Make QEMU driver use this info for setting -vga argument
- Make Xen drivers use this info for setting stdvga=1|0 config arg
- Make VirtualBox use this info in whatever way it needs
Daniel
domain_conf.c | 168
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ domain_conf.h |
26 ++++++++
2 files changed, 194 insertions(+)
diff -r 66fa9bfc797c src/domain_conf.c
--- a/src/domain_conf.c Mon May 18 11:28:46 2009 +0100
+++ b/src/domain_conf.c Mon May 18 11:29:00 2009 +0100
@@ -80,6 +80,7 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAI
"interface",
"input",
"sound",
+ "video",
"hostdev")
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
@@ -140,6 +141,12 @@ VIR_ENUM_IMPL(virDomainSoundModel, VIR_D
"pcspk",
"ac97")
+VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
+ "vga",
+ "cirrus",
+ "vmvga",
+ "xen")
+
VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST,
"mouse",
"tablet")
@@ -372,6 +379,14 @@ void virDomainSoundDefFree(virDomainSoun
VIR_FREE(def);
}
+void virDomainVideoDefFree(virDomainVideoDefPtr def)
+{
+ if (!def)
+ return;
+
+ VIR_FREE(def);
+}
+
void virDomainHostdevDefFree(virDomainHostdevDefPtr def)
{
if (!def)
@@ -399,6 +414,9 @@ void virDomainDeviceDefFree(virDomainDev
case VIR_DOMAIN_DEVICE_SOUND:
virDomainSoundDefFree(def->data.sound);
break;
+ case VIR_DOMAIN_DEVICE_VIDEO:
+ virDomainVideoDefFree(def->data.video);
+ break;
case VIR_DOMAIN_DEVICE_HOSTDEV:
virDomainHostdevDefFree(def->data.hostdev);
break;
@@ -456,6 +474,10 @@ void virDomainDefFree(virDomainDefPtr de
virDomainSoundDefFree(def->sounds[i]);
VIR_FREE(def->sounds);
+ for (i = 0 ; i < def->nvideos ; i++)
+ virDomainVideoDefFree(def->videos[i]);
+ VIR_FREE(def->videos);
+
for (i = 0 ; i < def->nhostdevs ; i++)
virDomainHostdevDefFree(def->hostdevs[i]);
VIR_FREE(def->hostdevs);
@@ -1638,6 +1660,84 @@ error:
goto cleanup;
}
+static virDomainVideoDefPtr
+virDomainVideoDefParseXML(virConnectPtr conn,
+ const xmlNodePtr node,
+ int flags ATTRIBUTE_UNUSED) {
+ virDomainVideoDefPtr def;
+ xmlNodePtr cur;
+ char *type = NULL;
+ char *heads = NULL;
+ char *vram = NULL;
+
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError(conn);
+ return NULL;
+ }
+
+ cur = node->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE) {
+ if ((type == NULL) && (vram == NULL) && (heads == NULL)
&&
+ xmlStrEqual(cur->name, BAD_CAST "model")) {
+ type = virXMLPropString(cur, "type");
+ vram = virXMLPropString(cur, "vram");
+ heads = virXMLPropString(cur, "heads");
+ }
+ }
+ cur = cur->next;
+ }
+
+ if (type &&
+ (def->type = virDomainVideoTypeFromString(type)) < 0) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unknown video model '%s'"), type);
+ goto error;
+ }
+
+ if (vram &&
+ virStrToLong_ui(vram, NULL, 10, &def->vram) < 0) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse video ram '%s'"), vram);
+ goto error;
+ } else {
+ switch (def->type) {
+ /* Wierd, QEMU defaults to 9 MB ??! */
+ case VIR_DOMAIN_VIDEO_TYPE_VGA:
in case of vbox this defaults to 8MB any way of handling that here?
+ case VIR_DOMAIN_VIDEO_TYPE_CIRRUS:
+ case VIR_DOMAIN_VIDEO_TYPE_VMVGA:
+ def->vram = 9 * 1024;
+ break;
+ case VIR_DOMAIN_VIDEO_TYPE_XEN:
+ /* Original PVFB hardcoded to 4 MB */
+ def->vram = 4 * 1024;
+ break;
+ }
+ }
+
+ if (heads &&
+ virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse video heads '%s'"),
heads);
+ goto error;
+ } else {
+ def->heads = 1;
+ }
+
+ VIR_FREE(type);
+ VIR_FREE(vram);
+ VIR_FREE(heads);
+
+ return def;
+
+error:
+ virDomainVideoDefFree(def);
+ VIR_FREE(type);
+ VIR_FREE(vram);
+ VIR_FREE(heads);
+ return NULL;
+}
+
static int
virDomainHostdevSubsysUsbDefParseXML(virConnectPtr conn,
const xmlNodePtr node,
@@ -2064,6 +2164,10 @@ virDomainDeviceDefPtr virDomainDeviceDef
dev->type = VIR_DOMAIN_DEVICE_SOUND;
if (!(dev->data.sound = virDomainSoundDefParseXML(conn, node,
flags))) goto error;
+ } else if (xmlStrEqual(node->name, BAD_CAST "video")) {
+ dev->type = VIR_DOMAIN_DEVICE_VIDEO;
+ if (!(dev->data.video = virDomainVideoDefParseXML(conn, node,
flags))) + goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "hostdev")) {
dev->type = VIR_DOMAIN_DEVICE_HOSTDEV;
if (!(dev->data.hostdev = virDomainHostdevDefParseXML(conn, node,
flags))) @@ -2584,6 +2688,40 @@ static virDomainDefPtr virDomainDefParse
}
VIR_FREE(nodes);
+ /* analysis of the video devices */
+ if ((n = virXPathNodeSet(conn, "./devices/video", ctxt, &nodes)) <
0)
{ + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot extract video
devices"));
+ goto error;
+ }
+ if (n && VIR_ALLOC_N(def->videos, n) < 0)
+ goto no_memory;
+ for (i = 0 ; i < n ; i++) {
+ virDomainVideoDefPtr video = virDomainVideoDefParseXML(conn,
+ nodes[i],
+ flags);
+ if (!video)
+ goto error;
+ def->videos[def->nvideos++] = video;
+ }
+ VIR_FREE(nodes);
+
+ /* For backwards compatability, if no <video> tag is set but there
+ * is a <graphics> tag, then we add a single video tag */
+ if (def->ngraphics && !def->nvideos) {
+ virDomainVideoDefPtr video;
+ if (VIR_ALLOC(video) < 0)
+ goto no_memory;
+ video->type = VIR_DOMAIN_VIDEO_TYPE_CIRRUS;
+ video->vram = 9 * 1024;
+ video->heads = 1;
+ if (VIR_ALLOC_N(def->videos, 1) < 0) {
+ virDomainVideoDefFree(video);
+ goto no_memory;
+ }
+ def->videos[def->nvideos++] = video;
+ }
+
/* analysis of the host devices */
if ((n = virXPathNodeSet(conn, "./devices/hostdev", ctxt, &nodes))
<
0) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
@@ -3286,6 +3424,32 @@ virDomainSoundDefFormat(virConnectPtr co
}
static int
+virDomainVideoDefFormat(virConnectPtr conn,
+ virBufferPtr buf,
+ virDomainVideoDefPtr def)
+{
+ const char *model = virDomainVideoTypeToString(def->type);
+
+ if (!model) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unexpected video model %d"), def->type);
+ return -1;
+ }
+
+ virBufferAddLit(buf, " <video>\n");
+ virBufferVSprintf(buf, " <model type='%s'",
+ model);
+ if (def->vram)
+ virBufferVSprintf(buf, " vram='%u'", def->vram);
+ if (def->heads)
+ virBufferVSprintf(buf, " heads='%u'", def->heads);
+ virBufferAddLit(buf, "/>\n");
+ virBufferAddLit(buf, " </video>\n");
+
+ return 0;
+}
+
+static int
virDomainInputDefFormat(virConnectPtr conn,
virBufferPtr buf,
virDomainInputDefPtr def)
@@ -3660,6 +3824,10 @@ char *virDomainDefFormat(virConnectPtr c
if (virDomainSoundDefFormat(conn, &buf, def->sounds[n]) < 0)
goto cleanup;
+ for (n = 0 ; n < def->nvideos ; n++)
+ if (virDomainVideoDefFormat(conn, &buf, def->videos[n]) < 0)
+ goto cleanup;
+
for (n = 0 ; n < def->nhostdevs ; n++)
if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n]) < 0)
goto cleanup;
diff -r 66fa9bfc797c src/domain_conf.h
--- a/src/domain_conf.h Mon May 18 11:28:46 2009 +0100
+++ b/src/domain_conf.h Mon May 18 11:29:00 2009 +0100
@@ -264,6 +264,25 @@ struct _virDomainSoundDef {
int model;
};
+
+enum virDomainVideoType {
+ VIR_DOMAIN_VIDEO_TYPE_VGA,
+ VIR_DOMAIN_VIDEO_TYPE_CIRRUS,
+ VIR_DOMAIN_VIDEO_TYPE_VMVGA,
+ VIR_DOMAIN_VIDEO_TYPE_XEN,
can we add VIR_DOMAIN_VIDEO_TYPE_VBOX as well here, cause the the graphics
adapter shows up as "VirtualBox Graphics Adapter" in hardware list and has its
own drivers installed via the guest additions.
+
+ VIR_DOMAIN_VIDEO_TYPE_LAST
+};
+
+
+typedef struct _virDomainVideoDef virDomainVideoDef;
+typedef virDomainVideoDef *virDomainVideoDefPtr;
+struct _virDomainVideoDef {
+ int type;
+ unsigned int vram;
+ unsigned int heads;
can we add "unsigned int 3dSupport;" here cause VirtualBox has support for 3d
acceleration and it needs to be specified in video adapter category. (it is not
boolean, but an int cause there could be multiple option, like supporting
acceleration via opengl, directx, etc, just trying to be future proof.. :) )
+};
+
/* 3 possible graphics console modes */
enum virDomainGraphicsType {
VIR_DOMAIN_GRAPHICS_TYPE_SDL,
@@ -360,6 +379,7 @@ enum virDomainDeviceType {
VIR_DOMAIN_DEVICE_NET,
VIR_DOMAIN_DEVICE_INPUT,
VIR_DOMAIN_DEVICE_SOUND,
+ VIR_DOMAIN_DEVICE_VIDEO,
VIR_DOMAIN_DEVICE_HOSTDEV,
VIR_DOMAIN_DEVICE_LAST,
@@ -375,6 +395,7 @@ struct _virDomainDeviceDef {
virDomainNetDefPtr net;
virDomainInputDefPtr input;
virDomainSoundDefPtr sound;
+ virDomainVideoDefPtr video;
virDomainHostdevDefPtr hostdev;
} data;
};
@@ -491,6 +512,9 @@ struct _virDomainDef {
int nsounds;
virDomainSoundDefPtr *sounds;
+ int nvideos;
+ virDomainVideoDefPtr *videos;
+
int nhostdevs;
virDomainHostdevDefPtr *hostdevs;
@@ -557,6 +581,7 @@ void virDomainFSDefFree(virDomainFSDefPt
void virDomainNetDefFree(virDomainNetDefPtr def);
void virDomainChrDefFree(virDomainChrDefPtr def);
void virDomainSoundDefFree(virDomainSoundDefPtr def);
+void virDomainVideoDefFree(virDomainVideoDefPtr def);
void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
void virDomainDefFree(virDomainDefPtr vm);
@@ -671,6 +696,7 @@ VIR_ENUM_DECL(virDomainFS)
VIR_ENUM_DECL(virDomainNet)
VIR_ENUM_DECL(virDomainChr)
VIR_ENUM_DECL(virDomainSoundModel)
+VIR_ENUM_DECL(virDomainVideo)
VIR_ENUM_DECL(virDomainHostdevMode)
VIR_ENUM_DECL(virDomainHostdevSubsys)
VIR_ENUM_DECL(virDomainInput)
rest of the patch seems fine,
Regards,
Pritesh