mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 19:45:21 +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_ESX, /* Error from ESX driver */
|
||||||
VIR_FROM_PHYP, /* Error from IBM power hypervisor */
|
VIR_FROM_PHYP, /* Error from IBM power hypervisor */
|
||||||
VIR_FROM_SECRET, /* Error from secret storage */
|
VIR_FROM_SECRET, /* Error from secret storage */
|
||||||
|
VIR_FROM_CPU, /* Error from CPU driver */
|
||||||
} virErrorDomain;
|
} virErrorDomain;
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ libvirt_proxy_SOURCES = libvirt_proxy.c \
|
|||||||
@top_srcdir@/src/conf/capabilities.c \
|
@top_srcdir@/src/conf/capabilities.c \
|
||||||
@top_srcdir@/src/conf/storage_encryption_conf.c \
|
@top_srcdir@/src/conf/storage_encryption_conf.c \
|
||||||
@top_srcdir@/src/conf/domain_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/xend_internal.c \
|
||||||
@top_srcdir@/src/xen/xen_hypervisor.c \
|
@top_srcdir@/src/xen/xen_hypervisor.c \
|
||||||
@top_srcdir@/src/xen/sexpr.c \
|
@top_srcdir@/src/xen/sexpr.c \
|
||||||
|
@ -114,6 +114,9 @@ NODE_DEVICE_CONF_SOURCES = \
|
|||||||
ENCRYPTION_CONF_SOURCES = \
|
ENCRYPTION_CONF_SOURCES = \
|
||||||
conf/storage_encryption_conf.c conf/storage_encryption_conf.h
|
conf/storage_encryption_conf.c conf/storage_encryption_conf.h
|
||||||
|
|
||||||
|
CPU_CONF_SOURCES = \
|
||||||
|
conf/cpu_conf.c conf/cpu_conf.h
|
||||||
|
|
||||||
CONF_SOURCES = \
|
CONF_SOURCES = \
|
||||||
$(DOMAIN_CONF_SOURCES) \
|
$(DOMAIN_CONF_SOURCES) \
|
||||||
$(DOMAIN_EVENT_SOURCES) \
|
$(DOMAIN_EVENT_SOURCES) \
|
||||||
@ -122,7 +125,8 @@ CONF_SOURCES = \
|
|||||||
$(STORAGE_CONF_SOURCES) \
|
$(STORAGE_CONF_SOURCES) \
|
||||||
$(ENCRYPTION_CONF_SOURCES) \
|
$(ENCRYPTION_CONF_SOURCES) \
|
||||||
$(INTERFACE_CONF_SOURCES) \
|
$(INTERFACE_CONF_SOURCES) \
|
||||||
$(SECRET_CONF_SOURCES)
|
$(SECRET_CONF_SOURCES) \
|
||||||
|
$(CPU_CONF_SOURCES)
|
||||||
|
|
||||||
# The remote RPC driver, covering domains, storage, networks, etc
|
# The remote RPC driver, covering domains, storage, networks, etc
|
||||||
REMOTE_DRIVER_SOURCES = \
|
REMOTE_DRIVER_SOURCES = \
|
||||||
@ -831,7 +835,8 @@ libvirt_lxc_SOURCES = \
|
|||||||
$(UTIL_SOURCES) \
|
$(UTIL_SOURCES) \
|
||||||
$(NODE_INFO_SOURCES) \
|
$(NODE_INFO_SOURCES) \
|
||||||
$(ENCRYPTION_CONF_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_LDFLAGS = $(WARN_CFLAGS) $(COVERAGE_LDCFLAGS) $(CAPNG_LIBS) $(YAJL_LIBS)
|
||||||
libvirt_lxc_LDADD = $(LIBXML_LIBS) $(NUMACTL_LIBS) ../gnulib/lib/libgnu.la
|
libvirt_lxc_LDADD = $(LIBXML_LIBS) $(NUMACTL_LIBS) ../gnulib/lib/libgnu.la
|
||||||
libvirt_lxc_CFLAGS = \
|
libvirt_lxc_CFLAGS = \
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "cpu_conf.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virCapabilitiesNew:
|
* virCapabilitiesNew:
|
||||||
@ -171,6 +172,8 @@ virCapabilitiesFree(virCapsPtr caps) {
|
|||||||
VIR_FREE(caps->host.arch);
|
VIR_FREE(caps->host.arch);
|
||||||
VIR_FREE(caps->host.secModel.model);
|
VIR_FREE(caps->host.secModel.model);
|
||||||
VIR_FREE(caps->host.secModel.doi);
|
VIR_FREE(caps->host.secModel.doi);
|
||||||
|
virCPUDefFree(caps->host.cpu);
|
||||||
|
|
||||||
VIR_FREE(caps);
|
VIR_FREE(caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,6 +266,27 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
|
|||||||
return 0;
|
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:
|
* virCapabilitiesAllocMachines:
|
||||||
* @machines: machine variants for emulator ('pc', or 'isapc', etc)
|
* @machines: machine variants for emulator ('pc', or 'isapc', etc)
|
||||||
@ -653,6 +677,10 @@ virCapabilitiesFormatXML(virCapsPtr caps)
|
|||||||
}
|
}
|
||||||
virBufferAddLit(&xml, " </features>\n");
|
virBufferAddLit(&xml, " </features>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virCPUDefFormatBuf(NULL, &xml, caps->host.cpu, " ",
|
||||||
|
VIR_CPU_FORMAT_EMBEDED);
|
||||||
|
|
||||||
virBufferAddLit(&xml, " </cpu>\n");
|
virBufferAddLit(&xml, " </cpu>\n");
|
||||||
|
|
||||||
if (caps->host.offlineMigrate) {
|
if (caps->host.offlineMigrate) {
|
||||||
@ -750,7 +778,8 @@ virCapabilitiesFormatXML(virCapsPtr caps)
|
|||||||
for (j = 0 ; j < caps->guests[i]->nfeatures ; j++) {
|
for (j = 0 ; j < caps->guests[i]->nfeatures ; j++) {
|
||||||
if (STREQ(caps->guests[i]->features[j]->name, "pae") ||
|
if (STREQ(caps->guests[i]->features[j]->name, "pae") ||
|
||||||
STREQ(caps->guests[i]->features[j]->name, "nonpae") ||
|
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",
|
virBufferVSprintf(&xml, " <%s/>\n",
|
||||||
caps->guests[i]->features[j]->name);
|
caps->guests[i]->features[j]->name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
|
#include "cpu_conf.h"
|
||||||
|
|
||||||
#include <libxml/xpath.h>
|
#include <libxml/xpath.h>
|
||||||
|
|
||||||
@ -108,6 +109,7 @@ struct _virCapsHost {
|
|||||||
int nnumaCell;
|
int nnumaCell;
|
||||||
virCapsHostNUMACellPtr *numaCell;
|
virCapsHostNUMACellPtr *numaCell;
|
||||||
virCapsHostSecModel secModel;
|
virCapsHostSecModel secModel;
|
||||||
|
virCPUDefPtr cpu;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _virCaps virCaps;
|
typedef struct _virCaps virCaps;
|
||||||
@ -166,6 +168,10 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
|
|||||||
const int *cpus);
|
const int *cpus);
|
||||||
|
|
||||||
|
|
||||||
|
extern int
|
||||||
|
virCapabilitiesSetHostCPU(virCapsPtr caps,
|
||||||
|
virCPUDefPtr cpu);
|
||||||
|
|
||||||
|
|
||||||
extern virCapsGuestMachinePtr *
|
extern virCapsGuestMachinePtr *
|
||||||
virCapabilitiesAllocMachines(const char *const *names,
|
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);
|
virSecurityLabelDefFree(def);
|
||||||
|
|
||||||
|
virCPUDefFree(def->cpu);
|
||||||
|
|
||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3360,6 +3362,16 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn,
|
|||||||
if (virSecurityLabelDefParseXML(conn, def, ctxt, flags) == -1)
|
if (virSecurityLabelDefParseXML(conn, def, ctxt, flags) == -1)
|
||||||
goto error;
|
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;
|
return def;
|
||||||
|
|
||||||
no_memory:
|
no_memory:
|
||||||
@ -4660,6 +4672,9 @@ char *virDomainDefFormat(virConnectPtr conn,
|
|||||||
virBufferAddLit(&buf, " </features>\n");
|
virBufferAddLit(&buf, " </features>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virCPUDefFormatBuf(conn, &buf, def->cpu, " ", 0) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
virBufferVSprintf(&buf, " <clock offset='%s'/>\n",
|
virBufferVSprintf(&buf, " <clock offset='%s'/>\n",
|
||||||
def->localtime ? "localtime" : "utc");
|
def->localtime ? "localtime" : "utc");
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "capabilities.h"
|
#include "capabilities.h"
|
||||||
#include "storage_encryption_conf.h"
|
#include "storage_encryption_conf.h"
|
||||||
|
#include "cpu_conf.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
@ -635,6 +636,7 @@ struct _virDomainDef {
|
|||||||
virDomainChrDefPtr console;
|
virDomainChrDefPtr console;
|
||||||
virSecurityLabelDef seclabel;
|
virSecurityLabelDef seclabel;
|
||||||
virDomainWatchdogDefPtr watchdog;
|
virDomainWatchdogDefPtr watchdog;
|
||||||
|
virCPUDefPtr cpu;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Guest VM runtime state */
|
/* Guest VM runtime state */
|
||||||
|
@ -35,6 +35,7 @@ virCapabilitiesSetEmulatorRequired;
|
|||||||
virCapabilitiesIsEmulatorRequired;
|
virCapabilitiesIsEmulatorRequired;
|
||||||
virCapabilitiesAllocMachines;
|
virCapabilitiesAllocMachines;
|
||||||
virCapabilitiesFreeMachines;
|
virCapabilitiesFreeMachines;
|
||||||
|
virCapabilitiesSetHostCPU;
|
||||||
|
|
||||||
|
|
||||||
# conf.h
|
# conf.h
|
||||||
@ -70,6 +71,14 @@ virCgroupGetFreezerState;
|
|||||||
virCgroupSetFreezerState;
|
virCgroupSetFreezerState;
|
||||||
|
|
||||||
|
|
||||||
|
# cpu_conf.h
|
||||||
|
virCPUDefFree;
|
||||||
|
virCPUDefParseXML;
|
||||||
|
virCPUDefFormat;
|
||||||
|
virCPUDefFormatBuf;
|
||||||
|
virCPUDefAddFeature;
|
||||||
|
|
||||||
|
|
||||||
# datatypes.h
|
# datatypes.h
|
||||||
virGetDomain;
|
virGetDomain;
|
||||||
virGetInterface;
|
virGetInterface;
|
||||||
|
@ -172,6 +172,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
|
|||||||
case VIR_FROM_SECRET:
|
case VIR_FROM_SECRET:
|
||||||
dom = "Secret Storage ";
|
dom = "Secret Storage ";
|
||||||
break;
|
break;
|
||||||
|
case VIR_FROM_CPU:
|
||||||
|
dom = "CPU ";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return(dom);
|
return(dom);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user