Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > ebe084c140192657f9094e135a84202c > files > 18

libvirt-0.8.2-29.el5.src.rpm

From 27845c8a80d1c91d5e1c85f24fd7acd4b1f16a8e Mon Sep 17 00:00:00 2001
Message-Id: <27845c8a80d1c91d5e1c85f24fd7acd4b1f16a8e.1305127059.git.jdenemar@redhat.com>
From: Eric Blake <eblake@redhat.com>
Date: Mon, 9 May 2011 17:22:15 -0600
Subject: [PATCH] Add sysinfo/smbios support to the QEmu driver

https://bugzilla.redhat.com/show_bug.cgi?id=661365

The patch is based on the possiblity in the QEmu command line to
add -smbios options allowing to override the default values picked
by QEmu. We need to detect this first from QEmu help output.
If the domain is defined with smbios to be inherited from host
then we pass the values coming from the Host own SMBIOS, but
if the domain is defined with smbios to come from sysinfo, we
use the ones coming from the domain definition.

* src/qemu/qemu_conf.h: add the QEMUD_CMD_FLAG_SMBIOS_TYPE enum
  value
* src/qemu/qemu_conf.c: scan the help output for the smbios support,
  and if available add support based on the domain definitions,
  and host data
* tests/qemuhelptest.c: add the new enum in the outputs
(cherry picked from commit 54c0237ccb95b164741c57c5c00eed95d116edf1)

Conflicts:

	src/qemu/qemu_conf.c - context for neighboring flags
	src/qemu/qemu_conf.h - context for neighboring flags
	tests/qemuhelptest.c - context for neighboring flags
---
 src/qemu/qemu_conf.c |  123 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_conf.h |    1 +
 tests/qemuhelptest.c |   15 ++++--
 3 files changed, 134 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index df89866..bba7d96 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1215,6 +1215,8 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
         flags |= QEMUD_CMD_FLAG_NO_KVM_PIT;
     if (strstr(help, "-tdf"))
         flags |= QEMUD_CMD_FLAG_TDF;
+    if (strstr(help, "-smbios type"))
+        flags |= QEMUD_CMD_FLAG_SMBIOS_TYPE;
 
     /* Keep disabled till we're actually ready to turn on netdev mode
      * The plan is todo it in 0.13.0 QEMU, but lets wait & see... */
@@ -3295,6 +3297,83 @@ error:
     return NULL;
 }
 
+static char *qemuBuildSmbiosBiosStr(virSysinfoDefPtr def)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if ((def->bios_vendor == NULL) && (def->bios_version == NULL) &&
+        (def->bios_date == NULL) && (def->bios_release == NULL))
+        return(NULL);
+
+    virBufferAddLit(&buf, "type=0");
+
+    /* 0:Vendor */
+    if (def->bios_vendor)
+        virBufferVSprintf(&buf, ",vendor=\"%s\"", def->bios_vendor);
+    /* 0:BIOS Version */
+    if (def->bios_version)
+        virBufferVSprintf(&buf, ",version=\"%s\"", def->bios_version);
+    /* 0:BIOS Release Date */
+    if (def->bios_date)
+        virBufferVSprintf(&buf, ",date=\"%s\"", def->bios_date);
+    /* 0:System BIOS Major Release and 0:System BIOS Minor Release */
+    if (def->bios_release)
+        virBufferVSprintf(&buf, ",release=\"%s\"", def->bios_release);
+
+    if (virBufferError(&buf)) {
+        virReportOOMError();
+        goto error;
+    }
+
+    return virBufferContentAndReset(&buf);
+
+error:
+    virBufferFreeAndReset(&buf);
+    return(NULL);
+}
+
+static char *qemuBuildSmbiosSystemStr(virSysinfoDefPtr def)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    if ((def->system_manufacturer == NULL) && (def->system_sku == NULL) &&
+        (def->system_product == NULL) && (def->system_uuid == NULL) &&
+        (def->system_version == NULL) && (def->system_serial == NULL))
+        return(NULL);
+
+    virBufferAddLit(&buf, "type=1");
+
+    /* 1:Manufacturer */
+    if (def->system_manufacturer)
+        virBufferVSprintf(&buf, ",manufacturer=\"%s\"",
+                          def->system_manufacturer);
+     /* 1:Product Name */
+    if (def->system_product)
+        virBufferVSprintf(&buf, ",product=\"%s\"", def->system_product);
+    /* 1:Version */
+    if (def->system_version)
+        virBufferVSprintf(&buf, ",version=\"%s\"", def->system_version);
+    /* 1:Serial Number */
+    if (def->system_serial)
+        virBufferVSprintf(&buf, ",serial=\"%s\"", def->system_serial);
+    /* 1:UUID */
+    if (def->system_uuid)
+        virBufferVSprintf(&buf, ",uuid=\"%s\"", def->system_uuid);
+    /* 1:SKU Number */
+    if (def->system_sku)
+        virBufferVSprintf(&buf, ",sku=\"%s\"", def->system_sku);
+
+    if (virBufferError(&buf)) {
+        virReportOOMError();
+        goto error;
+    }
+
+    return virBufferContentAndReset(&buf);
+
+error:
+    virBufferFreeAndReset(&buf);
+    return(NULL);
+}
 
 static char *
 qemuBuildClockArgStr(virDomainClockDefPtr def)
@@ -3818,6 +3897,50 @@ int qemudBuildCommandLine(virConnectPtr conn,
         }
     }
 
+    if ((def->os.smbios_mode != VIR_DOMAIN_SMBIOS_NONE) &&
+        (def->os.smbios_mode != VIR_DOMAIN_SMBIOS_EMULATE)) {
+        virSysinfoDefPtr source = NULL;
+
+        if (!(qemuCmdFlags & QEMUD_CMD_FLAG_SMBIOS_TYPE)) {
+            qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                    _("the QEMU binary %s does not support smbios settings"),
+                            emulator);
+            goto error;
+        }
+
+        /* should we really error out or just warn in those cases ? */
+        if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_HOST) {
+            if (driver->hostsysinfo == NULL) {
+                qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("Host SMBIOS information is not available"));
+                goto error;
+            }
+            source = driver->hostsysinfo;
+        } else if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_SYSINFO) {
+            if (def->sysinfo == NULL) {
+                qemuReportError(VIR_ERR_XML_ERROR,
+                            _("Domain '%s' sysinfo are not available"),
+                               def->name);
+                goto error;
+            }
+            source = def->sysinfo;
+        }
+        if (source != NULL) {
+            char *smbioscmd;
+
+            smbioscmd = qemuBuildSmbiosBiosStr(source);
+            if (smbioscmd != NULL) {
+                ADD_ARG_LIT("-smbios");
+                ADD_ARG(smbioscmd);
+            }
+            smbioscmd = qemuBuildSmbiosSystemStr(source);
+            if (smbioscmd != NULL) {
+                ADD_ARG_LIT("-smbios");
+                ADD_ARG(smbioscmd);
+            }
+        }
+    }
+
     /*
      * NB, -nographic *MUST* come before any serial, or monitor
      * or parallel port flags due to QEMU craziness, where it
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 67c4e46..731de4d 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -92,6 +92,7 @@ enum qemud_cmd_flags {
     QEMUD_CMD_FLAG_PCI_CONFIGFD  = (1LL << 36), /* pci-assign.configfd */
     QEMUD_CMD_FLAG_NODEFCONFIG   = (1LL << 37), /* -nodefconfig */
     QEMUD_CMD_FLAG_DRIVE_READONLY    = (1LL << 43), /* -drive readonly=on|off */
+    QEMUD_CMD_FLAG_SMBIOS_TYPE   = (1LL << 44), /* Is -smbios type= available */
     QEMUD_CMD_FLAG_VGA_NONE      = (1LL << 47), /* The 'none' arg for '-vga' */
 };
 
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index 373672a..8a8a85e 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -152,7 +152,8 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_NO_HPET |
             QEMUD_CMD_FLAG_NO_KVM_PIT |
             QEMUD_CMD_FLAG_TDF |
-            QEMUD_CMD_FLAG_DRIVE_READONLY,
+            QEMUD_CMD_FLAG_DRIVE_READONLY |
+            QEMUD_CMD_FLAG_SMBIOS_TYPE,
             9001, 1,  83);
     DO_TEST("qemu-0.10.5",
             QEMUD_CMD_FLAG_KQEMU |
@@ -221,7 +222,8 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_NO_HPET |
             QEMUD_CMD_FLAG_NO_KVM_PIT |
             QEMUD_CMD_FLAG_TDF |
-            QEMUD_CMD_FLAG_VGA_NONE,
+            QEMUD_CMD_FLAG_VGA_NONE |
+            QEMUD_CMD_FLAG_SMBIOS_TYPE,
             10050, 1,  0);
     DO_TEST("qemu-kvm-0.11.0-rc2",
             QEMUD_CMD_FLAG_VNC_COLON |
@@ -248,7 +250,8 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_NO_HPET |
             QEMUD_CMD_FLAG_NO_KVM_PIT |
             QEMUD_CMD_FLAG_TDF |
-            QEMUD_CMD_FLAG_VGA_NONE,
+            QEMUD_CMD_FLAG_VGA_NONE |
+            QEMUD_CMD_FLAG_SMBIOS_TYPE,
             10092, 1,  0);
     DO_TEST("qemu-0.12.1",
             QEMUD_CMD_FLAG_VNC_COLON |
@@ -274,7 +277,8 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_SMP_TOPOLOGY |
             QEMUD_CMD_FLAG_RTC |
             QEMUD_CMD_FLAG_NO_HPET |
-            QEMUD_CMD_FLAG_VGA_NONE,
+            QEMUD_CMD_FLAG_VGA_NONE |
+            QEMUD_CMD_FLAG_SMBIOS_TYPE,
             12001, 0,  0);
     DO_TEST("qemu-kvm-0.12.3",
             QEMUD_CMD_FLAG_VNC_COLON |
@@ -306,7 +310,8 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_NO_HPET |
             QEMUD_CMD_FLAG_NO_KVM_PIT |
             QEMUD_CMD_FLAG_TDF |
-            QEMUD_CMD_FLAG_VGA_NONE,
+            QEMUD_CMD_FLAG_VGA_NONE |
+            QEMUD_CMD_FLAG_SMBIOS_TYPE,
             12003, 1,  0);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
-- 
1.7.5.rc3