This patch creates new <bios> element which, at this time has the only
attribute useserial='yes|no'. This attribute allow users to use
Serial Graphics Adapter and see BIOS messages from the very first moment
domain boots up. Therefore, users can choose boot medium, set PXE, etc.
---
diff to v2:
-move from <serial> to <bios>
-include Eric's and Dan's suggestions
diff to v1:
-move from <video> to <serial> as Dan suggested:
https://www.redhat.com/archives/libvir-list/2011-July/msg00134.html
docs/formatdomain.html.in | 9 ++++++
docs/schemas/domain.rng | 14 +++++++++
src/conf/domain_conf.c | 27 ++++++++++++++++-
src/conf/domain_conf.h | 13 ++++++++
src/qemu/qemu_capabilities.c | 3 ++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 20 +++++++++++++
tests/qemuxml2argvdata/qemuxml2argv-bios.args | 6 ++++
tests/qemuxml2argvdata/qemuxml2argv-bios.xml | 39 +++++++++++++++++++++++++
tests/qemuxml2argvtest.c | 1 +
10 files changed, 131 insertions(+), 2 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 10d87a9..9cc0bca 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -86,6 +86,7 @@
<boot dev='cdrom'/>
<bootmenu enable='yes'/>
<smbios mode='sysinfo'/>
+ <bios useserial='yes'/>
</os>
...</pre>
@@ -137,6 +138,14 @@
specified, the hypervisor default is used. <span class="since">
Since 0.8.7</span>
</dd>
+ <dt><code>bios</code></dt>
+ <dd>This element has attribute <code>useserial</code> with
possible
+ values <code>yes</code> or <code>no</code>. It enables or
disables
+ Serial Graphics Adapter which allows users to see BIOS messages
+ on a serial port. Therefore, one need to have
+ <a href="#elementCharSerial">serial port</a> defined.
+ <span class="since">Since 0.9.4</span>
+ </dd>
</dl>
<h4><a name="elementsOSBootloader">Host
bootloader</a></h4>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 3c8414e..2d3b3cd 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -151,6 +151,9 @@
<optional>
<ref name="smbios"/>
</optional>
+ <optional>
+ <ref name="bios"/>
+ </optional>
</interleave>
</element>
</define>
@@ -2261,6 +2264,17 @@
</element>
</define>
+ <define name="bios">
+ <element name="bios">
+ <attribute name="useserial">
+ <choice>
+ <value>yes</value>
+ <value>no</value>
+ </choice>
+ </attribute>
+ </element>
+ </define>
+
<define name="address">
<element name="address">
<choice>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2275d3a..eaafa15 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5628,9 +5628,9 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
{
xmlNodePtr *nodes = NULL;
int i, n;
- char *bootstr;
+ char *bootstr, *useserial;
int ret = -1;
- unsigned long deviceBoot;
+ unsigned long deviceBoot, serialPorts;
if (virXPathULong("count(./devices/disk[boot]"
"|./devices/interface[boot]"
@@ -5684,6 +5684,22 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
VIR_FREE(bootstr);
}
+ useserial = virXPathString("string(./os/bios[1]/@useserial)", ctxt);
+ if (useserial) {
+ if (STREQ(useserial, "yes")) {
+ if (virXPathULong("count(./devices/serial)",
+ ctxt, &serialPorts) < 0) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("need at least one serial port "
+ "for useserial"));
+ goto cleanup;
+ }
+ def->os.bios.useserial = VIR_DOMAIN_BIOS_USESERIAL_YES;
+ } else {
+ def->os.bios.useserial = VIR_DOMAIN_BIOS_USESERIAL_NO;
+ }
+ }
+
*bootCount = deviceBoot;
ret = 0;
@@ -9720,6 +9736,13 @@ char *virDomainDefFormat(virDomainDefPtr def,
: "no");
virBufferAsprintf(&buf, " <bootmenu
enable='%s'/>\n", enabled);
}
+
+ if (def->os.bios.useserial) {
+ const char *useserial = (def->os.bios.useserial ==
+ VIR_DOMAIN_BIOS_USESERIAL_YES ? "yes"
+ : "no");
+ virBufferAsprintf(&buf, " <bios
useserial='%s'/>\n", useserial);
+ }
}
if (def->os.smbios_mode) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ddfe18e..71cb145 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -923,6 +923,18 @@ enum virDomainLifecycleCrashAction {
VIR_DOMAIN_LIFECYCLE_CRASH_LAST
};
+enum virDomainBIOSUseserial {
+ VIR_DOMAIN_BIOS_USESERIAL_DEFAULT = 0,
+ VIR_DOMAIN_BIOS_USESERIAL_YES,
+ VIR_DOMAIN_BIOS_USESERIAL_NO
+};
+
+typedef struct _virDomainBIOSDef virDomainBIOSDef;
+typedef virDomainBIOSDef *virDomainBIOSDefPtr;
+struct _virDomainBIOSDef {
+ int useserial;
+};
+
/* Operating system configuration data & machine / arch */
typedef struct _virDomainOSDef virDomainOSDef;
typedef virDomainOSDef *virDomainOSDefPtr;
@@ -942,6 +954,7 @@ struct _virDomainOSDef {
char *bootloader;
char *bootloaderArgs;
int smbios_mode;
+ virDomainBIOSDef bios;
};
enum virDomainSeclabelType {
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2c037ce..1421a5e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -122,6 +122,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"pci-multifunction", /* 60 */
"virtio-blk-pci.ioeventfd",
+ "sga",
);
struct qemu_feature_flags {
@@ -1212,6 +1213,8 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
qemuCapsSet(flags, QEMU_CAPS_DEVICE_QXL_VGA);
if (strstr(str, "virtio-blk-pci.ioeventfd"))
qemuCapsSet(flags, QEMU_CAPS_VIRTIO_IOEVENTFD);
+ if (strstr(str, "name \"sga\""))
+ qemuCapsSet(flags, QEMU_CAPS_SGA);
return 0;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 0b9c8be..d251262 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -97,6 +97,7 @@ enum qemuCapsFlags {
QEMU_CAPS_DEVICE_QXL_VGA = 59, /* Is the primary and vga campatible qxl device
named qxl-vga? */
QEMU_CAPS_PCI_MULTIFUNCTION = 60, /* -device multifunction=on|off */
QEMU_CAPS_VIRTIO_IOEVENTFD = 61, /* IOeventFD feature:
virtio-{net|blk}-pci.ioeventfd=on/off */
+ QEMU_CAPS_SGA = 62, /* Serial Graphics Adapter */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6e4480e..7eb721c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3060,6 +3060,26 @@ qemuBuildCommandLine(virConnectPtr conn,
"-nodefaults"); /* Disable default guest devices */
}
+ /* Serial graphics adapter */
+ if (def->os.bios.useserial == VIR_DOMAIN_BIOS_USESERIAL_YES) {
+ if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu does not support -device"));
+ goto error;
+ }
+ if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SGA)) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("qemu does not support SGA"));
+ goto error;
+ }
+ if (!def->nserials) {
+ qemuReportError(VIR_ERR_XML_ERROR, "%s",
+ _("need at least one serial port to use SGA"));
+ goto error;
+ }
+ virCommandAddArgList(cmd, "-device", "sga", NULL);
+ }
+
if (monitor_chr) {
char *chrdev;
/* Use -chardev if it's available */
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bios.args
b/tests/qemuxml2argvdata/qemuxml2argv-bios.args
new file mode 100644
index 0000000..f9727c4
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-bios.args
@@ -0,0 +1,6 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M pc -m 1024 -smp 1 -nodefaults -device sga \
+-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-hda /dev/HostVG/QEMUGuest1 -serial pty \
+-usb -device usb-tablet,id=input0 -vnc 127.0.0.1:0 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bios.xml
b/tests/qemuxml2argvdata/qemuxml2argv-bios.xml
new file mode 100644
index 0000000..5ce3e24
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-bios.xml
@@ -0,0 +1,39 @@
+<domain type='qemu'>
+ <name>test-bios</name>
+ <uuid>362d1fc1-df7d-193e-5c18-49a71bd1da66</uuid>
+ <memory>1048576</memory>
+ <currentMemory>1048576</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ <bootmenu enable='yes'/>
+ <bios useserial='yes'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <serial type='pty'>
+ <target port='0'/>
+ </serial>
+ <console type='pty'>
+ <target type='serial' port='0'/>
+ </console>
+ <input type='tablet' bus='usb'/>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='5900' autoport='no'
listen='127.0.0.1'/>
+ <video>
+ <model type='cirrus' vram='9216' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index ec1f4b5..2e6c546 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -287,6 +287,7 @@ mymain(void)
QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_BOOT,
QEMU_CAPS_BOOTINDEX);
DO_TEST("bootloader", true, QEMU_CAPS_DOMID);
+ DO_TEST("bios", false, QEMU_CAPS_DEVICE, QEMU_CAPS_SGA);
DO_TEST("clock-utc", false, NONE);
DO_TEST("clock-localtime", false, NONE);
/*
--
1.7.5.rc3