* src/util/sysinfo.h (virSysinfoFormat): New prototype. * src/conf/domain_conf.c (virDomainSysinfoDefFormat): Move guts... * src/util/sysinfo.c (virSysinfoFormat): ...into new function. * src/libvirt_private.syms: Export it. * src/qemu/qemu_driver.c (qemuGetSysinfo): New function. (qemuDriver): Install it. --- Tested both with qemu:///system (works!) and qemu:///session (error: unsupported configuration: Host SMBIOS information is not available) The prefix hack is necessary so that I can use "" or " " as the leading indentation, depending on host sysinfo vs. domain, so it's not quite straight code motion. src/conf/domain_conf.c | 71 ++------------------------ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 18 ++++++- src/util/sysinfo.c | 125 ++++++++++++++++++++++++++++++++++++++++++++- src/util/sysinfo.h | 5 ++- 5 files changed, 148 insertions(+), 72 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9369ed4..401aee7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7143,75 +7143,12 @@ static int virDomainSysinfoDefFormat(virBufferPtr buf, virSysinfoDefPtr def) { - const char *type = virDomainSysinfoTypeToString(def->type); + char *format = virSysinfoFormat(def, " "); - if (!type) { - virDomainReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected sysinfo type model %d"), - def->type); + if (!format) return -1; - } - - virBufferVSprintf(buf, " <sysinfo type='%s'>\n", type); - if ((def->bios_vendor != NULL) || (def->bios_version != NULL) || - (def->bios_date != NULL) || (def->bios_release != NULL)) { - virBufferAddLit(buf, " <bios>\n"); - if (def->bios_vendor != NULL) - virBufferEscapeString(buf, - " <entry name='vendor'>%s</entry>\n", - def->bios_vendor); - if (def->bios_version != NULL) - virBufferEscapeString(buf, - " <entry name='version'>%s</entry>\n", - def->bios_version); - if (def->bios_date != NULL) - virBufferEscapeString(buf, - " <entry name='date'>%s</entry>\n", - def->bios_date); - if (def->bios_release != NULL) - virBufferEscapeString(buf, - " <entry name='release'>%s</entry>\n", - def->bios_release); - virBufferAddLit(buf, " </bios>\n"); - } - if ((def->system_manufacturer != NULL) || (def->system_product != NULL) || - (def->system_version != NULL) || (def->system_serial != NULL) || - (def->system_uuid != NULL) || (def->system_sku != NULL) || - (def->system_family != NULL)) { - virBufferAddLit(buf, " <system>\n"); - if (def->system_manufacturer != NULL) - virBufferEscapeString(buf, - " <entry name='manufacturer'>%s</entry>\n", - def->system_manufacturer); - if (def->system_product != NULL) - virBufferEscapeString(buf, - " <entry name='product'>%s</entry>\n", - def->system_product); - if (def->system_version != NULL) - virBufferEscapeString(buf, - " <entry name='version'>%s</entry>\n", - def->system_version); - if (def->system_serial != NULL) - virBufferEscapeString(buf, - " <entry name='serial'>%s</entry>\n", - def->system_serial); - if (def->system_uuid != NULL) - virBufferEscapeString(buf, - " <entry name='uuid'>%s</entry>\n", - def->system_uuid); - if (def->system_sku != NULL) - virBufferEscapeString(buf, - " <entry name='sku'>%s</entry>\n", - def->system_sku); - if (def->system_family != NULL) - virBufferEscapeString(buf, - " <entry name='family'>%s</entry>\n", - def->system_family); - virBufferAddLit(buf, " </system>\n"); - } - - virBufferAddLit(buf, " </sysinfo>\n"); - + virBufferAdd(buf, format, strlen(format)); + VIR_FREE(format); return 0; } diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 88e270c..6348e0d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -798,6 +798,7 @@ virStorageFileProbeFormatFromFD; # sysinfo.h virSysinfoDefFree; +virSysinfoFormat; virSysinfoRead; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 87d228b..52ea98e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3275,6 +3275,22 @@ static int kvmGetMaxVCPUs(void) { } +static char * +qemuGetSysinfo(virConnectPtr conn, unsigned int flags) +{ + struct qemud_driver *driver = conn->privateData; + + virCheckFlags(0, NULL); + + if (!driver->hostsysinfo) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Host SMBIOS information is not available")); + return NULL; + } + + return virSysinfoFormat(driver->hostsysinfo, ""); +} + static int qemudGetMaxVCPUs(virConnectPtr conn ATTRIBUTE_UNUSED, const char *type) { if (!type) return 16; @@ -10375,7 +10391,7 @@ static virDriver qemuDriver = { qemudGetVersion, /* version */ NULL, /* libvirtVersion (impl. in libvirt.c) */ virGetHostname, /* getHostname */ - NULL, /* getSysinfo */ + qemuGetSysinfo, /* getSysinfo */ qemudGetMaxVCPUs, /* getMaxVcpus */ nodeGetInfo, /* nodeGetInfo */ qemudGetCapabilities, /* getCapabilities */ diff --git a/src/util/sysinfo.c b/src/util/sysinfo.c index 48ab267..2b764ae 100644 --- a/src/util/sysinfo.c +++ b/src/util/sysinfo.c @@ -1,7 +1,7 @@ /* * sysinfo.c: get SMBIOS/sysinfo information from the host * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010-2011 Red Hat, Inc. * Copyright (C) 2010 Daniel Veillard * * This library is free software; you can redistribute it and/or @@ -91,7 +91,18 @@ virSysinfoRead(void) { _("Host sysinfo extraction not supported on this platform")); return NULL; } -#else + +char * +virSysinfoFormat(virSysinfoDefPtr def ATTRIBUTE_UNUSED, + const char *prefix ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Host sysinfo extraction not supported on this platform")); + return NULL; +} + +#else /* !WIN32 */ + virSysinfoDefPtr virSysinfoRead(void) { char *path, *cur, *eol, *base; @@ -207,4 +218,112 @@ no_memory: ret = NULL; goto cleanup; } -#endif + +/** + * virSysinfoFormat: + * @def: structure to convert to xml string + * @prefix: string to prefix before each line of xml + * + * This returns the XML description of the sysinfo, or NULL after + * generating an error message. + */ +char * +virSysinfoFormat(virSysinfoDefPtr def, const char *prefix) +{ + const char *type = virDomainSysinfoTypeToString(def->type); + virBuffer buf = VIR_BUFFER_INITIALIZER; + size_t len = strlen(prefix); + + if (!type) { + virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected sysinfo type model %d"), + def->type); + return NULL; + } + + virBufferVSprintf(&buf, "%s<sysinfo type='%s'>\n", prefix, type); + if ((def->bios_vendor != NULL) || (def->bios_version != NULL) || + (def->bios_date != NULL) || (def->bios_release != NULL)) { + virBufferVSprintf(&buf, "%s <bios>\n", prefix); + if (def->bios_vendor != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='vendor'>%s</entry>\n", + def->bios_vendor); + } + if (def->bios_version != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='version'>%s</entry>\n", + def->bios_version); + } + if (def->bios_date != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='date'>%s</entry>\n", + def->bios_date); + } + if (def->bios_release != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='release'>%s</entry>\n", + def->bios_release); + } + virBufferVSprintf(&buf, "%s </bios>\n", prefix); + } + if ((def->system_manufacturer != NULL) || (def->system_product != NULL) || + (def->system_version != NULL) || (def->system_serial != NULL) || + (def->system_uuid != NULL) || (def->system_sku != NULL) || + (def->system_family != NULL)) { + virBufferVSprintf(&buf, "%s <system>\n", prefix); + if (def->system_manufacturer != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='manufacturer'>%s</entry>\n", + def->system_manufacturer); + } + if (def->system_product != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='product'>%s</entry>\n", + def->system_product); + } + if (def->system_version != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='version'>%s</entry>\n", + def->system_version); + } + if (def->system_serial != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='serial'>%s</entry>\n", + def->system_serial); + } + if (def->system_uuid != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='uuid'>%s</entry>\n", + def->system_uuid); + } + if (def->system_sku != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='sku'>%s</entry>\n", + def->system_sku); + } + if (def->system_family != NULL) { + virBufferAdd(&buf, prefix, len); + virBufferEscapeString(&buf, + " <entry name='family'>%s</entry>\n", + def->system_family); + } + virBufferVSprintf(&buf, "%s </system>\n", prefix); + } + + virBufferVSprintf(&buf, "%s</sysinfo>\n", prefix); + + return virBufferContentAndReset(&buf); +} + +#endif /* !WIN32 */ diff --git a/src/util/sysinfo.h b/src/util/sysinfo.h index 1af7ef6..66a59db 100644 --- a/src/util/sysinfo.h +++ b/src/util/sysinfo.h @@ -1,7 +1,7 @@ /* * sysinfo.h: structure and entry points for sysinfo support * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010-2011 Red Hat, Inc. * Copyright (C) 2010 Daniel Veillard * * This library is free software; you can redistribute it and/or @@ -56,4 +56,7 @@ virSysinfoDefPtr virSysinfoRead(void); void virSysinfoDefFree(virSysinfoDefPtr def); +char *virSysinfoFormat(virSysinfoDefPtr def, const char *prefix) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + #endif /* __VIR_SYSINFOS_H__ */ -- 1.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list