[libvirt] [PATCH v3] bios: Add support for SGA

Michal Privoznik mprivozn at redhat.com
Fri Jul 8 13:48:52 UTC 2011


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




More information about the libvir-list mailing list