diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index b5c17b5a22..7d2a1d6367 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1243,6 +1243,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; if (strstr(help, "-netdev")) { /* Disable -netdev on 0.12 since although it exists, @@ -3512,6 +3514,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) @@ -4092,6 +4171,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 13ddbb24e2..2b143e6af9 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -96,7 +96,8 @@ 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_DRIVE_READONLY = (1LL << 43), /* -drive readonly=on|off */ + QEMUD_CMD_FLAG_DRIVE_READONLY= (1LL << 43), /* -drive readonly=on|off */ + QEMUD_CMD_FLAG_SMBIOS_TYPE = (1LL << 44), /* Is -smbios type= available */ }; /* Main driver state */ diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c index 97531ff7f0..912f6075b0 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 | @@ -220,7 +221,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_NO_HPET | QEMUD_CMD_FLAG_NO_KVM_PIT | QEMUD_CMD_FLAG_TDF | - QEMUD_CMD_FLAG_NESTING, + QEMUD_CMD_FLAG_NESTING | + QEMUD_CMD_FLAG_SMBIOS_TYPE, 10050, 1, 0); DO_TEST("qemu-kvm-0.11.0-rc2", QEMUD_CMD_FLAG_VNC_COLON | @@ -249,7 +251,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_TDF | QEMUD_CMD_FLAG_BOOT_MENU | QEMUD_CMD_FLAG_NESTING | - QEMUD_CMD_FLAG_NAME_PROCESS, + QEMUD_CMD_FLAG_NAME_PROCESS | + QEMUD_CMD_FLAG_SMBIOS_TYPE, 10092, 1, 0); DO_TEST("qemu-0.12.1", QEMUD_CMD_FLAG_VNC_COLON | @@ -276,7 +279,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_RTC | QEMUD_CMD_FLAG_NO_HPET | QEMUD_CMD_FLAG_BOOT_MENU | - QEMUD_CMD_FLAG_NAME_PROCESS, + QEMUD_CMD_FLAG_NAME_PROCESS | + QEMUD_CMD_FLAG_SMBIOS_TYPE, 12001, 0, 0); DO_TEST("qemu-kvm-0.12.3", QEMUD_CMD_FLAG_VNC_COLON | @@ -310,7 +314,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_TDF | QEMUD_CMD_FLAG_BOOT_MENU | QEMUD_CMD_FLAG_NESTING | - QEMUD_CMD_FLAG_NAME_PROCESS, + QEMUD_CMD_FLAG_NAME_PROCESS | + QEMUD_CMD_FLAG_SMBIOS_TYPE, 12003, 1, 0); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;