[libvirt] [PATCH] qemu: Add support for SGA video

This patch extends possible values for <video> element. Serial Graphics Adapter allows users to see BIOS messages from the very first moment domain boots up. Therefore, users can choose boot medium, set PXE, etc. However, to be able to use this, one need SGABIOS, which is accessible here: http://code.google.com/p/sgabios/ --- docs/formatdomain.html.in | 5 +++-- docs/schemas/domain.rng | 1 + src/conf/domain_conf.c | 43 ++++++++++++++++++++++++------------------- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 28 ++++++++++++++++++++++------ 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 3a64983..2d89b37 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2005,8 +2005,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 "sga" + (<span class="since">Since 0.9.4</span>) depending on the hypervisor + features available. You can also provide the amount of video memory in kilobytes using <code>vram</code> and the number of screen with <code>heads</code>. </dd> diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 891662d..74bc111 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -1502,6 +1502,7 @@ <value>xen</value> <value>vbox</value> <value>qxl</value> + <value>sga</value> </choice> </attribute> <optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f9bf51e..9848359 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -299,7 +299,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, "vmvga", "xen", "vbox", - "qxl") + "qxl", + "sga") VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST, "mouse", @@ -4713,28 +4714,32 @@ virDomainVideoDefParseXML(const xmlNodePtr node, } } - if (vram) { - if (virStrToLong_ui(vram, NULL, 10, &def->vram) < 0) { - virDomainReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot parse video ram '%s'"), vram); - goto error; + /* SGA video device does not support heads, vram + * or PCI address. It is not PCI device anyway */ + if (def->type != VIR_DOMAIN_VIDEO_TYPE_SGA) { + if (vram) { + if (virStrToLong_ui(vram, NULL, 10, &def->vram) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot parse video ram '%s'"), vram); + goto error; + } + } else { + def->vram = virDomainVideoDefaultRAM(dom, def->type); } - } else { - def->vram = virDomainVideoDefaultRAM(dom, def->type); - } - if (heads) { - if (virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) { - virDomainReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot parse video heads '%s'"), heads); - goto error; + if (heads) { + if (virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot parse video heads '%s'"), heads); + goto error; + } + } else { + def->heads = 1; } - } else { - def->heads = 1; - } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) - goto error; + if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + goto error; + } VIR_FREE(type); VIR_FREE(vram); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e81977c..7f60754 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -605,6 +605,7 @@ enum virDomainVideoType { VIR_DOMAIN_VIDEO_TYPE_XEN, VIR_DOMAIN_VIDEO_TYPE_VBOX, VIR_DOMAIN_VIDEO_TYPE_QXL, + VIR_DOMAIN_VIDEO_TYPE_SGA, VIR_DOMAIN_VIDEO_TYPE_LAST }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6e4480e..7685d7e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -80,7 +80,8 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, "vmware", "", /* no arg needed for xen */ "", /* don't support vbox */ - "qxl"); + "qxl", + "sga"); static void uname_normalize (struct utsname *ut) @@ -1213,7 +1214,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) /* Further non-primary video cards */ for (i = 1; i < def->nvideos ; i++) { - if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE || + def->videos[i]->type == VIR_DOMAIN_VIDEO_TYPE_SGA) continue; if (qemuDomainPCIAddressSetNextAddr(addrs, &def->videos[i]->info) < 0) goto error; @@ -2083,8 +2085,9 @@ qemuBuildVideoDevStr(virDomainVideoDefPtr video, virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024); } - if (qemuBuildDeviceAddressStr(&buf, &video->info, qemuCaps) < 0) - goto error; + if (video->type != VIR_DOMAIN_VIDEO_TYPE_SGA) + if (qemuBuildDeviceAddressStr(&buf, &video->info, qemuCaps) < 0) + goto error; if (virBufferError(&buf)) { virReportOOMError(); @@ -4254,6 +4257,11 @@ qemuBuildCommandLine(virConnectPtr conn, if (qemuCapsGet(qemuCaps, QEMU_CAPS_VGA)) { if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_XEN) { /* nothing - vga has no effect on Xen pvfb */ + } else if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_SGA) { + if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) + virCommandAddArgList(cmd, "-device", "sga", NULL); + else + virCommandAddArg(cmd, "-nographic"); } else { if ((def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL) && !qemuCapsGet(qemuCaps, QEMU_CAPS_VGA_QXL)) { @@ -4309,6 +4317,13 @@ qemuBuildCommandLine(virConnectPtr conn, /* No special args - this is the default */ break; + case VIR_DOMAIN_VIDEO_TYPE_SGA: + if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) + virCommandAddArgList(cmd, "-device", "sga", NULL); + else + virCommandAddArg(cmd, "-nographic"); + break; + default: qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("video type %s is not supported with this QEMU"), @@ -4321,10 +4336,11 @@ qemuBuildCommandLine(virConnectPtr conn, if (qemuCapsGet(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_SGA) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("video type %s is only valid as primary video card"), - virDomainVideoTypeToString(def->videos[0]->type)); + virDomainVideoTypeToString(def->videos[i]->type)); goto error; } -- 1.7.5.rc3

On Mon, Jul 04, 2011 at 03:21:25PM +0200, Michal Privoznik wrote:
This patch extends possible values for <video> element. Serial Graphics Adapter allows users to see BIOS messages from the very first moment domain boots up. Therefore, users can choose boot medium, set PXE, etc.
This isn't really the right way todo this. '-sga' is not actually a new type of video card. It isn't even a guest device. It is just a hack QEMU uses for loading an option ROM via their qdev infrastructure. This in turn causes the QEMU BIOS to use a serial port for outputting messages. IMHO we should do one of - Automatically enable it if no <graphics> is set, but there is a <serial> set (ie no XML additions at all) - Add a attribute to the <serial> element to allow use of SGA to be toggled on/off - Add an attribute on the <boot> element to redirect BIOS to SGA. One thing about options 2/3 there is that they could allow a user to request the BIOS to use the serial port even when their guest *does* have a <graphics> element present. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (2)
-
Daniel P. Berrange
-
Michal Privoznik