[libvirt] [PATCH] 3/4 Add SMBIOS QEmu driver

Daniel Veillard veillard at redhat.com
Thu Oct 21 20:23:43 UTC 2010


The main trouble here is that the QEmu command uses names which are
similar to the official names for the entries used by the DMTF, but
that mean we cant base on name equality. I was tempted to use
something like strcasestr to go fishing on the names but since we
never used this in libvirt yet, and I'm not sure it's available in
gnulib, I did the patch using strstr, assuming entries provided by the
users would contain the word in lower case usually except maybe for the
first character. The matching glue is certainly perfectible.
Also decided that if we can't associate an entry with an existing
QEmu SMBIOS command we would ignore it. On the ther hand if a block
other than type 0 or 1 is used in the XML definition we would emit
a warning, but still not fail.

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 5907bf3..6d4479e 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1224,6 +1224,8 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
         flags |= QEMUD_CMD_FLAG_BOOT_MENU;
     if (strstr(help, "-fsdev"))
         flags |= QEMUD_CMD_FLAG_FSDEV;
+    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... */
@@ -3494,6 +3496,73 @@ error:
     return NULL;
 }
 
+static char *qemuBuildSmbiosBlockStr(virSmbiosBlockPtr def)
+{
+    virSmbiosEntryPtr cur;
+
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    virBufferVSprintf(&buf, "type=%d", def->type);
+
+    /*
+     * QEmu accepts only a limited set of System informations, and
+     * use command line arguments shortcuts from the DMTF real names
+     * so go fishing for those
+     */
+    cur = def->entries;
+    while (cur != NULL) {
+        /* 0:Vendor */
+        if ((def->type == 0) && (strstr(cur->name, "endor")))
+            virBufferVSprintf(&buf, ",vendor=\"%s\"", cur->value);
+        /* 0:BIOS Version */
+        else if ((def->type == 0) && (strstr(cur->name, "ersion")))
+            virBufferVSprintf(&buf, ",version=\"%s\"", cur->value);
+        /* 0:BIOS Release Date */
+        else if ((def->type == 0) && (strstr(cur->name, "ate")))
+            virBufferVSprintf(&buf, ",date=\"%s\"", cur->value);
+        /* 0:System BIOS Major Release and 0:System BIOS Minor Release */
+        else if ((def->type == 0) && (strstr(cur->name, "elease")))
+            virBufferVSprintf(&buf, ",date=\"%s\"", cur->value);
+        /* 1:Manufacturer */
+        else if ((def->type == 1) && (strstr(cur->name, "anuf")))
+            virBufferVSprintf(&buf, ",manufacturer=\"%s\"", cur->value);
+        /* 1:Product Name */
+        else if ((def->type == 1) && (strstr(cur->name, "roduct")))
+            virBufferVSprintf(&buf, ",product=\"%s\"", cur->value);
+        /* 1:Version */
+        else if ((def->type == 1) && (strstr(cur->name, "ersion")))
+            virBufferVSprintf(&buf, ",version=\"%s\"", cur->value);
+        /* 1:Serial Number */
+        else if ((def->type == 1) && (strstr(cur->name, "erial")))
+            virBufferVSprintf(&buf, ",serial=\"%s\"", cur->value);
+        /* 1:UUID */
+        else if ((def->type == 1) && (strstr(cur->name, "uuid")))
+            virBufferVSprintf(&buf, ",uuid=\"%s\"", cur->value);
+        else if ((def->type == 1) && (strstr(cur->name, "UUID")))
+            virBufferVSprintf(&buf, ",uuid=\"%s\"", cur->value);
+        /* 1:SKU Number */
+        else if ((def->type == 1) && (strstr(cur->name, "sku")))
+            virBufferVSprintf(&buf, ",sku=\"%s\"", cur->value);
+        else if ((def->type == 1) && (strstr(cur->name, "SKU")))
+            virBufferVSprintf(&buf, ",sku=\"%s\"", cur->value);
+        /* 1:Family */
+        else if ((def->type == 1) && (strstr(cur->name, "amily")))
+            virBufferVSprintf(&buf, ",family=\"%s\"", cur->value);
+        /* other non string or type are not available just ignore them */
+        cur = cur->next;
+    }
+
+    if (virBufferError(&buf)) {
+        virReportOOMError();
+        goto error;
+    }
+
+    return virBufferContentAndReset(&buf);
+
+error:
+    virBufferFreeAndReset(&buf);
+    return(NULL);
+}
 
 static char *
 qemuBuildClockArgStr(virDomainClockDefPtr def)
@@ -4074,6 +4143,26 @@ int qemudBuildCommandLine(virConnectPtr conn,
         }
     }
 
+    if ((def->smbios != NULL) && (qemuCmdFlags & QEMUD_CMD_FLAG_SMBIOS_TYPE)) {
+        int blk;
+
+        for (blk = 0;blk < def->smbios->nbblocks;blk++) {
+            virSmbiosBlockPtr block = def->smbios->blocks[blk];
+            char *smbiosblockcmd;
+
+            if ((block->type == 0) || (block->type == 1)) {
+                smbiosblockcmd = qemuBuildSmbiosBlockStr(block);
+                if (smbiosblockcmd == NULL)
+                    goto error;
+                ADD_ARG_LIT("-smbios");
+                ADD_ARG(smbiosblockcmd);
+            } else {
+                VIR_WARN("QEmu handles only SMBIOS type 0 and 1, not '%d'",
+                         block->type);
+            }
+        }
+    }
+
     /*
      * 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 005031d..7ff7900 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -96,6 +96,7 @@ enum qemud_cmd_flags {
     QEMUD_CMD_FLAG_FSDEV         = (1LL << 40), /* -fstype filesystem passthrough */
     QEMUD_CMD_FLAG_NESTING       = (1LL << 41), /* -enable-nesting (SVM/VMX) */
     QEMUD_CMD_FLAG_NAME_PROCESS  = (1LL << 42), /* Is -name process= available */
+    QEMUD_CMD_FLAG_SMBIOS_TYPE   = (1LL << 43), /* Is -smbios type= available */
 };
 
 /* Main driver state */

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list