bios: Add support for SGA

This patch creates new <bios> element which, at this time has only the
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.
This commit is contained in:
Michal Privoznik 2011-07-08 09:56:17 +02:00
parent 920ffe1b0a
commit 874e65aa15
10 changed files with 131 additions and 2 deletions

View File

@ -86,6 +86,7 @@
&lt;boot dev='cdrom'/&gt;
&lt;bootmenu enable='yes'/&gt;
&lt;smbios mode='sysinfo'/&gt;
&lt;bios useserial='yes'/&gt;
&lt;/os&gt;
...</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 needs 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>

View File

@ -151,6 +151,9 @@
<optional>
<ref name="smbios"/>
</optional>
<optional>
<ref name="bios"/>
</optional>
</interleave>
</element>
</define>
@ -2277,6 +2280,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>

View File

@ -5662,9 +5662,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]"
@ -5718,6 +5718,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;
@ -9758,6 +9774,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) {

View File

@ -933,6 +933,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;
@ -952,6 +964,7 @@ struct _virDomainOSDef {
char *bootloader;
char *bootloaderArgs;
int smbios_mode;
virDomainBIOSDef bios;
};
enum virDomainSeclabelType {

View File

@ -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;
}

View File

@ -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 */
};

View File

@ -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 */

View File

@ -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

View File

@ -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>

View File

@ -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);
/*