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@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list