Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
include/libvirt/virterror.h | 1 +
src/Makefile.am | 9 +-
src/conf/capabilities.c | 31 ++++-
src/conf/capabilities.h | 6 +
src/conf/cpu_conf.c | 345 +++++++++++++++++++++++++++++++++++++++++++
src/conf/cpu_conf.h | 110 ++++++++++++++
src/conf/domain_conf.c | 15 ++
src/conf/domain_conf.h | 2 +
src/libvirt_private.syms | 8 +
src/util/virterror.c | 3 +
10 files changed, 527 insertions(+), 3 deletions(-)
create mode 100644 src/conf/cpu_conf.c
create mode 100644 src/conf/cpu_conf.h
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index fa5cac4..4f819b2 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -68,6 +68,7 @@ typedef enum {
VIR_FROM_ESX, /* Error from ESX driver */
VIR_FROM_PHYP, /* Error from IBM power hypervisor */
VIR_FROM_SECRET, /* Error from secret storage */
+ VIR_FROM_CPU, /* Error from CPU driver */
} virErrorDomain;
diff --git a/src/Makefile.am b/src/Makefile.am
index 8e27ea7..17ed03f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -110,6 +110,9 @@ NODE_DEVICE_CONF_SOURCES = \
ENCRYPTION_CONF_SOURCES = \
conf/storage_encryption_conf.c conf/storage_encryption_conf.h
+CPU_CONF_SOURCES = \
+ conf/cpu_conf.c conf/cpu_conf.h
+
CONF_SOURCES = \
$(DOMAIN_CONF_SOURCES) \
$(DOMAIN_EVENT_SOURCES) \
@@ -118,7 +121,8 @@ CONF_SOURCES = \
$(STORAGE_CONF_SOURCES) \
$(ENCRYPTION_CONF_SOURCES) \
$(INTERFACE_CONF_SOURCES) \
- $(SECRET_CONF_SOURCES)
+ $(SECRET_CONF_SOURCES) \
+ $(CPU_CONF_SOURCES)
# The remote RPC driver, covering domains, storage, networks, etc
REMOTE_DRIVER_SOURCES = \
@@ -819,7 +823,8 @@ libvirt_lxc_SOURCES = \
$(UTIL_SOURCES) \
$(NODE_INFO_SOURCES) \
$(ENCRYPTION_CONF_SOURCES) \
- $(DOMAIN_CONF_SOURCES)
+ $(DOMAIN_CONF_SOURCES) \
+ $(CPU_CONF_SOURCES)
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(COVERAGE_LDCFLAGS) $(CAPNG_LIBS)
libvirt_lxc_LDADD = $(LIBXML_LIBS) $(NUMACTL_LIBS) ../gnulib/lib/libgnu.la
libvirt_lxc_CFLAGS = \
diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index 6ebddf5..98d7b0e 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -27,6 +27,7 @@
#include "buf.h"
#include "memory.h"
#include "util.h"
+#include "cpu_conf.h"
/**
* virCapabilitiesNew:
@@ -171,6 +172,8 @@ virCapabilitiesFree(virCapsPtr caps) {
VIR_FREE(caps->host.arch);
VIR_FREE(caps->host.secModel.model);
VIR_FREE(caps->host.secModel.doi);
+ virCPUDefFree(caps->host.cpu);
+
VIR_FREE(caps);
}
@@ -263,6 +266,27 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
return 0;
}
+
+/**
+ * virCapabilitiesSetHostCPU:
+ * @caps: capabilities to extend
+ * @cpu: CPU definition
+ *
+ * Sets host CPU specification
+ */
+int
+virCapabilitiesSetHostCPU(virCapsPtr caps,
+ virCPUDefPtr cpu)
+{
+ if (cpu == NULL)
+ return -1;
+
+ caps->host.cpu = cpu;
+
+ return 0;
+}
+
+
/**
* virCapabilitiesAllocMachines:
* @machines: machine variants for emulator ('pc', or 'isapc', etc)
@@ -653,6 +677,10 @@ virCapabilitiesFormatXML(virCapsPtr caps)
}
virBufferAddLit(&xml, " </features>\n");
}
+
+ virCPUDefFormatBuf(NULL, &xml, caps->host.cpu, " ",
+ VIR_CPU_FORMAT_EMBEDED);
+
virBufferAddLit(&xml, " </cpu>\n");
if (caps->host.offlineMigrate) {
@@ -750,7 +778,8 @@ virCapabilitiesFormatXML(virCapsPtr caps)
for (j = 0 ; j < caps->guests[i]->nfeatures ; j++) {
if (STREQ(caps->guests[i]->features[j]->name, "pae")
||
STREQ(caps->guests[i]->features[j]->name,
"nonpae") ||
- STREQ(caps->guests[i]->features[j]->name,
"ia64_be")) {
+ STREQ(caps->guests[i]->features[j]->name,
"ia64_be") ||
+ STREQ(caps->guests[i]->features[j]->name, "cpu"))
{
virBufferVSprintf(&xml, " <%s/>\n",
caps->guests[i]->features[j]->name);
} else {
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index 2f24605..48e293c 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -26,6 +26,7 @@
#include "internal.h"
#include "util.h"
+#include "cpu_conf.h"
typedef struct _virCapsGuestFeature virCapsGuestFeature;
typedef virCapsGuestFeature *virCapsGuestFeaturePtr;
@@ -105,6 +106,7 @@ struct _virCapsHost {
int nnumaCell;
virCapsHostNUMACellPtr *numaCell;
virCapsHostSecModel secModel;
+ virCPUDefPtr cpu;
};
typedef struct _virCaps virCaps;
@@ -159,6 +161,10 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
const int *cpus);
+extern int
+virCapabilitiesSetHostCPU(virCapsPtr caps,
+ virCPUDefPtr cpu);
+
extern virCapsGuestMachinePtr *
virCapabilitiesAllocMachines(const char *const *names,
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
new file mode 100644
index 0000000..3c100ee
--- /dev/null
+++ b/src/conf/cpu_conf.c
@@ -0,0 +1,345 @@
+/*
+ * cpu_conf.h: CPU XML handling
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Jiri Denemark <jdenemar(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "c-ctype.h"
+#include "virterror_internal.h"
+#include "memory.h"
+#include "util.h"
+#include "buf.h"
+#include "cpu_conf.h"
+
+#define VIR_FROM_THIS VIR_FROM_CPU
+
+#define virCPUReportError(conn, code, fmt...) \
+ virReportErrorHelper(conn, VIR_FROM_CPU, code, __FILE__, \
+ __FUNCTION__, __LINE__, fmt)
+
+VIR_ENUM_IMPL(virCPUMatch, VIR_CPU_MATCH_LAST,
+ "minimum",
+ "exact",
+ "strict")
+
+VIR_ENUM_IMPL(virCPUFeaturePolicy, VIR_CPU_FEATURE_LAST,
+ "force",
+ "require",
+ "optional",
+ "disable",
+ "forbid")
+
+
+void
+virCPUDefFree(virCPUDefPtr def)
+{
+ unsigned int i;
+
+ if (!def)
+ return;
+
+ VIR_FREE(def->model);
+ VIR_FREE(def->arch);
+
+ for (i = 0 ; i < def->nfeatures ; i++)
+ VIR_FREE(def->features[i].name);
+ VIR_FREE(def->features);
+
+ VIR_FREE(def);
+}
+
+
+virCPUDefPtr
+virCPUDefParseXML(virConnectPtr conn,
+ const xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ enum virCPUType mode)
+{
+ virCPUDefPtr def;
+ xmlNodePtr *nodes = NULL;
+ char *match;
+ int n;
+ unsigned int i;
+
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError(conn);
+ return NULL;
+ }
+
+ match = virXMLPropString(node, "match");
+
+ if (mode == VIR_CPU_TYPE_AUTO)
+ def->type = (match == NULL) ? VIR_CPU_TYPE_HOST : VIR_CPU_TYPE_GUEST;
+ else
+ def->type = mode;
+
+ if (def->type == VIR_CPU_TYPE_GUEST) {
+ if ((def->match = virCPUMatchTypeFromString(match)) < 0) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid match attribute for CPU
specification"));
+ goto error;
+ }
+ }
+
+ if (def->type == VIR_CPU_TYPE_HOST) {
+ def->arch = virXPathString(conn, "string(./arch[1])", ctxt);
+ if (!def->arch) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Missing CPU architecture"));
+ goto error;
+ }
+ }
+
+ if (!(def->model = virXPathString(conn, "string(./model[1])", ctxt))) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Missing CPU model name"));
+ goto error;
+ }
+
+ if (virXPathNode(conn, "./topology[1]", ctxt)) {
+ int ret;
+ unsigned long ul;
+ int all_zero;
+
+ ret = virXPathULong(conn, "string(./topology[1]/@sockets)",
+ ctxt, &ul);
+ if (ret < 0) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Missing 'sockets' attribute in CPU
topology"));
+ goto error;
+ }
+ def->sockets = (unsigned int) ul;
+ all_zero = !def->sockets;
+
+ ret = virXPathULong(conn, "string(./topology[1]/@cores)",
+ ctxt, &ul);
+ if (ret < 0) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Missing 'cores' attribute in CPU
topology"));
+ goto error;
+ }
+ def->cores = (unsigned int) ul;
+ all_zero &= !def->cores;
+
+ ret = virXPathULong(conn, "string(./topology[1]/@threads)",
+ ctxt, &ul);
+ if (ret < 0) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Missing 'threads' attribute in CPU
topology"));
+ goto error;
+ }
+ def->threads = (unsigned int) ul;
+ all_zero &= !def->threads;
+
+ /*
+ * sockets, cores, and threads must all be either zero or nonzero;
+ * if all of them are zero, we don't care about topology
+ */
+ if ((!def->sockets || !def->cores || !def->threads) &&
!all_zero) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid CPU topology"));
+ goto error;
+ }
+ }
+
+ n = virXPathNodeSet(conn, "./feature", ctxt, &nodes);
+ if (n < 0)
+ goto error;
+
+ if (n > 0) {
+ if (VIR_ALLOC_N(def->features, n) < 0)
+ goto no_memory;
+ def->nfeatures = n;
+ }
+
+ for (i = 0 ; i < n ; i++) {
+ char *name;
+ int policy; /* enum virDomainCPUFeaturePolicy */
+ unsigned int j;
+ unsigned int len;
+
+ if (def->type == VIR_CPU_TYPE_GUEST) {
+ char *strpolicy;
+
+ strpolicy = virXMLPropString(nodes[i], "policy");
+ policy = virCPUFeaturePolicyTypeFromString(strpolicy);
+ VIR_FREE(strpolicy);
+
+ if (policy < 0) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid CPU feature policy"));
+ goto error;
+ }
+ }
+ else
+ policy = -1;
+
+ if (!(name = (char *) xmlNodeGetContent(nodes[i]))
+ || *name == 0) {
+ VIR_FREE(name);
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Invalid CPU feature name"));
+ goto error;
+ }
+
+ len = strlen(name);
+ for (j = 0 ; j < len ; j++)
+ name[j] = c_tolower(name[j]);
+
+ for (j = 0 ; j < i ; j++) {
+ if (STREQ(name, def->features[j].name)) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("CPU feature `%s' specified more than once"),
+ name);
+ VIR_FREE(name);
+ goto error;
+ }
+ }
+
+ def->features[i].name = name;
+ def->features[i].policy = policy;
+ }
+
+cleanup:
+ VIR_FREE(match);
+ VIR_FREE(nodes);
+
+ return def;
+
+no_memory:
+ virReportOOMError(conn);
+
+error:
+ virCPUDefFree(def);
+ def = NULL;
+ goto cleanup;
+}
+
+
+char *
+virCPUDefFormat(virConnectPtr conn,
+ virCPUDefPtr def,
+ const char *indent,
+ int flags)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char *tmp;
+
+ if (virCPUDefFormatBuf(conn, &buf, def, indent, flags) < 0)
+ goto cleanup;
+
+ if (virBufferError(&buf))
+ goto no_memory;
+
+ return virBufferContentAndReset(&buf);
+
+no_memory:
+ virReportOOMError(conn);
+cleanup:
+ tmp = virBufferContentAndReset(&buf);
+ VIR_FREE(tmp);
+ return NULL;
+}
+
+
+int
+virCPUDefFormatBuf(virConnectPtr conn,
+ virBufferPtr buf,
+ virCPUDefPtr def,
+ const char *indent,
+ int flags)
+{
+ unsigned int i;
+
+ if (!def)
+ return 0;
+
+ if (indent == NULL)
+ indent = "";
+
+ if (!def->model) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Missing CPU model"));
+ return -1;
+ }
+
+ if (!(flags & VIR_CPU_FORMAT_EMBEDED)) {
+ if (def->type == VIR_CPU_TYPE_GUEST) {
+ const char *match;
+ if (!(match = virCPUMatchTypeToString(def->match))) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Unexpected CPU match policy %d"), def->match);
+ return -1;
+ }
+
+ virBufferVSprintf(buf, "%s<cpu match='%s'>\n",
indent, match);
+ }
+ else
+ virBufferVSprintf(buf, "%s<cpu>\n", indent);
+
+ if (def->arch)
+ virBufferVSprintf(buf, "%s <arch>%s</arch>\n", indent,
def->arch);
+ }
+
+ virBufferVSprintf(buf, "%s <model>%s</model>\n", indent,
def->model);
+
+ if (def->sockets && def->cores && def->threads) {
+ virBufferVSprintf(buf, "%s <topology", indent);
+ virBufferVSprintf(buf, " sockets='%u'", def->sockets);
+ virBufferVSprintf(buf, " cores='%u'", def->cores);
+ virBufferVSprintf(buf, " threads='%u'", def->threads);
+ virBufferAddLit(buf, "/>\n");
+ }
+
+ for (i = 0 ; i < def->nfeatures ; i++) {
+ virCPUFeatureDefPtr feature = def->features + i;
+
+ if (!feature->name) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Missing CPU feature name"));
+ return -1;
+ }
+
+ if (def->type == VIR_CPU_TYPE_GUEST) {
+ const char *policy;
+
+ policy = virCPUFeaturePolicyTypeToString(feature->policy);
+ if (!policy) {
+ virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Unexpected CPU feature policy %d"),
feature->policy);
+ return -1;
+ }
+ virBufferVSprintf(buf, "%s <feature
policy='%s'>%s</feature>\n",
+ indent, policy, feature->name);
+ }
+ else {
+ virBufferVSprintf(buf, "%s <feature>%s</feature>\n",
+ indent, feature->name);
+ }
+ }
+
+ if (!(flags & VIR_CPU_FORMAT_EMBEDED))
+ virBufferVSprintf(buf, "%s</cpu>\n", indent);
+
+ return 0;
+}
+
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
new file mode 100644
index 0000000..3629d90
--- /dev/null
+++ b/src/conf/cpu_conf.h
@@ -0,0 +1,110 @@
+/*
+ * cpu_conf.h: CPU XML handling
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Jiri Denemark <jdenemar(a)redhat.com>
+ */
+
+#ifndef __VIR_CPU_CONF_H__
+#define __VIR_CPU_CONF_H__
+
+#include "util.h"
+#include "buf.h"
+#include "xml.h"
+
+
+enum virCPUType {
+ VIR_CPU_TYPE_HOST,
+ VIR_CPU_TYPE_GUEST,
+ VIR_CPU_TYPE_AUTO
+};
+
+enum virCPUMatch {
+ VIR_CPU_MATCH_MINIMUM,
+ VIR_CPU_MATCH_EXACT,
+ VIR_CPU_MATCH_STRICT,
+
+ VIR_CPU_MATCH_LAST
+};
+
+VIR_ENUM_DECL(virCPUMatch)
+
+enum virCPUFeaturePolicy {
+ VIR_CPU_FEATURE_FORCE,
+ VIR_CPU_FEATURE_REQUIRE,
+ VIR_CPU_FEATURE_OPTIONAL,
+ VIR_CPU_FEATURE_DISABLE,
+ VIR_CPU_FEATURE_FORBID,
+
+ VIR_CPU_FEATURE_LAST
+};
+
+VIR_ENUM_DECL(virCPUFeaturePolicy)
+
+typedef struct _virCPUFeatureDef virCPUFeatureDef;
+typedef virCPUFeatureDef *virCPUFeatureDefPtr;
+struct _virCPUFeatureDef {
+ char *name;
+ int policy; /* enum virCPUFeaturePolicy */
+};
+
+typedef struct _virCPUDef virCPUDef;
+typedef virCPUDef *virCPUDefPtr;
+struct _virCPUDef {
+ int type; /* enum virCPUType */
+ int match; /* enum virCPUMatch */
+ char *arch;
+ char *model;
+ unsigned int sockets;
+ unsigned int cores;
+ unsigned int threads;
+ unsigned int nfeatures;
+ virCPUFeatureDefPtr features;
+};
+
+
+void
+virCPUDefFree(virCPUDefPtr def);
+
+virCPUDefPtr
+virCPUDefParseXML(virConnectPtr conn,
+ const xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ enum virCPUType mode);
+
+enum virCPUFormatFlags {
+ VIR_CPU_FORMAT_EMBEDED = (1 << 0) /* embed into existing <cpu/>
element
+ * in host capabilities */
+};
+
+
+char *
+virCPUDefFormat(virConnectPtr conn,
+ virCPUDefPtr def,
+ const char *indent,
+ int flags);
+
+int
+virCPUDefFormatBuf(virConnectPtr conn,
+ virBufferPtr buf,
+ virCPUDefPtr def,
+ const char *indent,
+ int flags);
+
+#endif /* __VIR_CPU_CONF_H__ */
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index de07e13..5a62712 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -577,6 +577,8 @@ void virDomainDefFree(virDomainDefPtr def)
virSecurityLabelDefFree(def);
+ virCPUDefFree(def->cpu);
+
VIR_FREE(def);
}
@@ -3160,6 +3162,16 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
if (virSecurityLabelDefParseXML(conn, def, ctxt, flags) == -1)
goto error;
+ if ((node = virXPathNode(conn, "./cpu[1]", ctxt)) != NULL) {
+ xmlNodePtr oldnode = ctxt->node;
+ ctxt->node = node;
+ def->cpu = virCPUDefParseXML(conn, node, ctxt, VIR_CPU_TYPE_GUEST);
+ ctxt->node = oldnode;
+
+ if (def->cpu == NULL)
+ goto error;
+ }
+
return def;
no_memory:
@@ -4452,6 +4464,9 @@ char *virDomainDefFormat(virConnectPtr conn,
virBufferAddLit(&buf, " </features>\n");
}
+ if (virCPUDefFormatBuf(conn, &buf, def->cpu, " ", 0) < 0)
+ goto cleanup;
+
virBufferVSprintf(&buf, " <clock offset='%s'/>\n",
def->localtime ? "localtime" : "utc");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 389e259..5ff4330 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -31,6 +31,7 @@
#include "internal.h"
#include "capabilities.h"
#include "storage_encryption_conf.h"
+#include "cpu_conf.h"
#include "util.h"
#include "threads.h"
#include "hash.h"
@@ -614,6 +615,7 @@ struct _virDomainDef {
virDomainChrDefPtr console;
virSecurityLabelDef seclabel;
virDomainWatchdogDefPtr watchdog;
+ virCPUDefPtr cpu;
};
/* Guest VM runtime state */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3997704..e668d4b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -33,6 +33,7 @@ virCapabilitiesSetEmulatorRequired;
virCapabilitiesIsEmulatorRequired;
virCapabilitiesAllocMachines;
virCapabilitiesFreeMachines;
+virCapabilitiesSetHostCPU;
# conf.h
@@ -84,6 +85,13 @@ virGetStream;
virUnrefStream;
+# cpu_conf.h
+virCPUDefFree;
+virCPUDefParseXML;
+virCPUDefFormat;
+virCPUDefFormatBuf;
+
+
# domain_conf.h
virDiskNameToBusDeviceIndex;
virDiskNameToIndex;
diff --git a/src/util/virterror.c b/src/util/virterror.c
index 10f979c..ff863ea 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -172,6 +172,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
case VIR_FROM_SECRET:
dom = "Secret Storage ";
break;
+ case VIR_FROM_CPU:
+ dom = "CPU ";
+ break;
}
return(dom);
}
--
1.6.5.2