mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-31 00:45:18 +00:00
XML parsing/formating code for CPU flags
* include/libvirt/virterror.h src/util/virterror.c: add new domain VIR_FROM_CPU for errors * src/conf/cpu_conf.c src/conf/cpu_conf.h: new parsing module * src/Makefile.am proxy/Makefile.am: include new files * src/conf/capabilities.[ch] src/conf/domain_conf.[ch]: reference new code * src/libvirt_private.syms: private export of new entry points
This commit is contained in:
parent
6df8b363f7
commit
6695818c03
@ -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;
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@ libvirt_proxy_SOURCES = libvirt_proxy.c \
|
||||
@top_srcdir@/src/conf/capabilities.c \
|
||||
@top_srcdir@/src/conf/storage_encryption_conf.c \
|
||||
@top_srcdir@/src/conf/domain_conf.c \
|
||||
@top_srcdir@/src/conf/cpu_conf.c \
|
||||
@top_srcdir@/src/xen/xend_internal.c \
|
||||
@top_srcdir@/src/xen/xen_hypervisor.c \
|
||||
@top_srcdir@/src/xen/sexpr.c \
|
||||
|
@ -114,6 +114,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) \
|
||||
@ -122,7 +125,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 = \
|
||||
@ -831,7 +835,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) $(YAJL_LIBS)
|
||||
libvirt_lxc_LDADD = $(LIBXML_LIBS) $(NUMACTL_LIBS) ../gnulib/lib/libgnu.la
|
||||
libvirt_lxc_CFLAGS = \
|
||||
|
@ -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, "cpuselection")) {
|
||||
virBufferVSprintf(&xml, " <%s/>\n",
|
||||
caps->guests[i]->features[j]->name);
|
||||
} else {
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "internal.h"
|
||||
#include "util.h"
|
||||
#include "buf.h"
|
||||
#include "cpu_conf.h"
|
||||
|
||||
#include <libxml/xpath.h>
|
||||
|
||||
@ -108,6 +109,7 @@ struct _virCapsHost {
|
||||
int nnumaCell;
|
||||
virCapsHostNUMACellPtr *numaCell;
|
||||
virCapsHostSecModel secModel;
|
||||
virCPUDefPtr cpu;
|
||||
};
|
||||
|
||||
typedef struct _virCaps virCaps;
|
||||
@ -166,6 +168,10 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
|
||||
const int *cpus);
|
||||
|
||||
|
||||
extern int
|
||||
virCapabilitiesSetHostCPU(virCapsPtr caps,
|
||||
virCPUDefPtr cpu);
|
||||
|
||||
|
||||
extern virCapsGuestMachinePtr *
|
||||
virCapabilitiesAllocMachines(const char *const *names,
|
||||
|
368
src/conf/cpu_conf.c
Normal file
368
src/conf/cpu_conf.c
Normal file
@ -0,0 +1,368 @@
|
||||
/*
|
||||
* 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@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);
|
||||
}
|
||||
|
||||
|
||||
#ifndef PROXY
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
if (!def->sockets || !def->cores || !def->threads) {
|
||||
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;
|
||||
|
||||
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 = virXMLPropString(nodes[i], "name")) || *name == 0) {
|
||||
VIR_FREE(name);
|
||||
virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("Invalid CPU feature name"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
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' name='%s'/>\n",
|
||||
indent, policy, feature->name);
|
||||
}
|
||||
else {
|
||||
virBufferVSprintf(buf, "%s <feature name='%s'/>\n",
|
||||
indent, feature->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & VIR_CPU_FORMAT_EMBEDED))
|
||||
virBufferVSprintf(buf, "%s</cpu>\n", indent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virCPUDefAddFeature(virConnectPtr conn,
|
||||
virCPUDefPtr def,
|
||||
const char *name,
|
||||
int policy)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < def->nfeatures ; i++) {
|
||||
if (STREQ(name, def->features[i].name)) {
|
||||
virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("CPU feature `%s' specified more than once"), name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (VIR_REALLOC_N(def->features, def->nfeatures + 1) < 0)
|
||||
goto no_memory;
|
||||
|
||||
if (def->type == VIR_CPU_TYPE_HOST)
|
||||
policy = -1;
|
||||
|
||||
if (!(def->features[def->nfeatures].name = strdup(name)))
|
||||
goto no_memory;
|
||||
|
||||
def->features[def->nfeatures].policy = policy;
|
||||
def->nfeatures++;
|
||||
|
||||
return 0;
|
||||
|
||||
no_memory:
|
||||
virReportOOMError(conn);
|
||||
return -1;
|
||||
}
|
119
src/conf/cpu_conf.h
Normal file
119
src/conf/cpu_conf.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_CPU_CONF_H__
|
||||
#define __VIR_CPU_CONF_H__
|
||||
|
||||
#include "util.h"
|
||||
#include "buf.h"
|
||||
#ifndef PROXY
|
||||
#include "xml.h"
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
#ifndef PROXY
|
||||
virCPUDefPtr
|
||||
virCPUDefParseXML(virConnectPtr conn,
|
||||
const xmlNodePtr node,
|
||||
xmlXPathContextPtr ctxt,
|
||||
enum virCPUType mode);
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
int
|
||||
virCPUDefAddFeature(virConnectPtr conn,
|
||||
virCPUDefPtr cpu,
|
||||
const char *name,
|
||||
int policy);
|
||||
|
||||
#endif /* __VIR_CPU_CONF_H__ */
|
@ -601,6 +601,8 @@ void virDomainDefFree(virDomainDefPtr def)
|
||||
|
||||
virSecurityLabelDefFree(def);
|
||||
|
||||
virCPUDefFree(def->cpu);
|
||||
|
||||
VIR_FREE(def);
|
||||
}
|
||||
|
||||
@ -3360,6 +3362,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:
|
||||
@ -4660,6 +4672,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");
|
||||
|
||||
|
@ -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"
|
||||
@ -635,6 +636,7 @@ struct _virDomainDef {
|
||||
virDomainChrDefPtr console;
|
||||
virSecurityLabelDef seclabel;
|
||||
virDomainWatchdogDefPtr watchdog;
|
||||
virCPUDefPtr cpu;
|
||||
};
|
||||
|
||||
/* Guest VM runtime state */
|
||||
|
@ -35,6 +35,7 @@ virCapabilitiesSetEmulatorRequired;
|
||||
virCapabilitiesIsEmulatorRequired;
|
||||
virCapabilitiesAllocMachines;
|
||||
virCapabilitiesFreeMachines;
|
||||
virCapabilitiesSetHostCPU;
|
||||
|
||||
|
||||
# conf.h
|
||||
@ -70,6 +71,14 @@ virCgroupGetFreezerState;
|
||||
virCgroupSetFreezerState;
|
||||
|
||||
|
||||
# cpu_conf.h
|
||||
virCPUDefFree;
|
||||
virCPUDefParseXML;
|
||||
virCPUDefFormat;
|
||||
virCPUDefFormatBuf;
|
||||
virCPUDefAddFeature;
|
||||
|
||||
|
||||
# datatypes.h
|
||||
virGetDomain;
|
||||
virGetInterface;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user