* 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