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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list