* proxy/libvirt_proxy.c src/proxy_internal.[ch] src/xen_internal.c

src/xen_unified.[ch] src/xend_internal.[ch] src/xml.[ch]: last
  patch for the library NUMA support, allow to serialize CPU pinning
  to domain configs (but won't work though proxy access), includes
  many patches from Saori Fukuta.
Daniel
This commit is contained in:
Daniel Veillard 2007-10-31 09:39:13 +00:00
parent 8a0711c758
commit 390cca8125
12 changed files with 242 additions and 44 deletions

View File

@ -1,3 +1,11 @@
Wed Oct 31 10:36:00 CET 2007 Daniel Veillard <veillard@redhat.com>
* proxy/libvirt_proxy.c src/proxy_internal.[ch] src/xen_internal.c
src/xen_unified.[ch] src/xend_internal.[ch] src/xml.[ch]: last
patch for the library NUMA support, allow to serialize CPU pinning
to domain configs (but won't work though proxy access), includes
many patches from Saori Fukuta.
Fri Oct 26 21:20:44 EST 2007 Daniel P. Berrange <berrange@redhat.com> Fri Oct 26 21:20:44 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* src/libvirt.c: Don't call state driver API if callback is NULL. * src/libvirt.c: Don't call state driver API if callback is NULL.

View File

@ -614,7 +614,13 @@ retry2:
if (req->len != sizeof(virProxyPacket)) if (req->len != sizeof(virProxyPacket))
goto comm_error; goto comm_error;
xml = xenDaemonDomainDumpXMLByID(conn, request.data.arg, 0); /*
* Ideally we should get the CPUs used by the domain
* but that information is really node specific and it
* rather hard to get from that code path. So proxy
* users won't see CPU pinning (last NULL arg)
*/
xml = xenDaemonDomainDumpXMLByID(conn, request.data.arg, 0, NULL);
if (!xml) { if (!xml) {
req->data.arg = -1; req->data.arg = -1;
req->len = sizeof(virProxyPacket); req->len = sizeof(virProxyPacket);

View File

@ -37,7 +37,6 @@ static int xenProxyListDomains(virConnectPtr conn, int *ids, int maxids);
static int xenProxyNumOfDomains(virConnectPtr conn); static int xenProxyNumOfDomains(virConnectPtr conn);
static unsigned long xenProxyDomainGetMaxMemory(virDomainPtr domain); static unsigned long xenProxyDomainGetMaxMemory(virDomainPtr domain);
static int xenProxyDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info); static int xenProxyDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info);
static char *xenProxyDomainDumpXML(virDomainPtr domain, int flags);
static char *xenProxyDomainGetOSType(virDomainPtr domain); static char *xenProxyDomainGetOSType(virDomainPtr domain);
struct xenUnifiedDriver xenProxyDriver = { struct xenUnifiedDriver xenProxyDriver = {
@ -69,7 +68,6 @@ struct xenUnifiedDriver xenProxyDriver = {
NULL, /* domainPinVcpu */ NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */ NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */ NULL, /* domainGetMaxVcpus */
xenProxyDomainDumpXML, /* domainDumpXML */
NULL, /* listDefinedDomains */ NULL, /* listDefinedDomains */
NULL, /* numOfDefinedDomains */ NULL, /* numOfDefinedDomains */
NULL, /* domainCreate */ NULL, /* domainCreate */
@ -1014,7 +1012,7 @@ xenProxyGetCapabilities (virConnectPtr conn)
* *
* Returns the XML document on success, NULL otherwise. * Returns the XML document on success, NULL otherwise.
*/ */
static char * char *
xenProxyDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED) xenProxyDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED)
{ {
virProxyPacket req; virProxyPacket req;

View File

@ -96,6 +96,8 @@ extern virDomainPtr xenProxyLookupByUUID(virConnectPtr conn,
extern virDomainPtr xenProxyLookupByName(virConnectPtr conn, extern virDomainPtr xenProxyLookupByName(virConnectPtr conn,
const char *domname); const char *domname);
extern char * xenProxyDomainDumpXML(virDomainPtr domain,
int flags);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -704,7 +704,6 @@ struct xenUnifiedDriver xenHypervisorDriver = {
xenHypervisorPinVcpu, /* domainPinVcpu */ xenHypervisorPinVcpu, /* domainPinVcpu */
xenHypervisorGetVcpus, /* domainGetVcpus */ xenHypervisorGetVcpus, /* domainGetVcpus */
xenHypervisorGetVcpuMax, /* domainGetMaxVcpus */ xenHypervisorGetVcpuMax, /* domainGetMaxVcpus */
NULL, /* domainDumpXML */
NULL, /* listDefinedDomains */ NULL, /* listDefinedDomains */
NULL, /* numOfDefinedDomains */ NULL, /* numOfDefinedDomains */
NULL, /* domainCreate */ NULL, /* domainCreate */

View File

@ -36,9 +36,16 @@
#include "xend_internal.h" #include "xend_internal.h"
#include "xs_internal.h" #include "xs_internal.h"
#include "xm_internal.h" #include "xm_internal.h"
#include "xml.h"
static int static int
xenUnifiedNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info); xenUnifiedNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info);
static int
xenUnifiedDomainGetMaxVcpus (virDomainPtr dom);
static int
xenUnifiedDomainGetVcpus (virDomainPtr dom,
virVcpuInfoPtr info, int maxinfo,
unsigned char *cpumaps, int maplen);
/* The five Xen drivers below us. */ /* The five Xen drivers below us. */
static struct xenUnifiedDriver *drivers[XEN_UNIFIED_NR_DRIVERS] = { static struct xenUnifiedDriver *drivers[XEN_UNIFIED_NR_DRIVERS] = {
@ -113,9 +120,9 @@ int xenNbCells(virConnectPtr conn) {
* xenNbCpus: * xenNbCpus:
* @conn: pointer to the hypervisor connection * @conn: pointer to the hypervisor connection
* *
* Number of NUMa cells present in the actual Node * Number of CPUs present in the actual Node
* *
* Returns the number of NUMA cells available on that Node * Returns the number of CPUs available on that Node
*/ */
int xenNbCpus(virConnectPtr conn) { int xenNbCpus(virConnectPtr conn) {
if (nbNodeCpus < 0) if (nbNodeCpus < 0)
@ -123,6 +130,81 @@ int xenNbCpus(virConnectPtr conn) {
return(nbNodeCpus); return(nbNodeCpus);
} }
/**
* xenDomainUsedCpus:
* @dom: the domain
*
* Analyze which set of CPUs are used by the domain and
* return a string providing the ranges.
*
* Returns the string which needs to be freed by the caller or
* NULL if the domain uses all CPU or in case of error.
*/
char *
xenDomainUsedCpus(virDomainPtr dom)
{
char *res = NULL;
int nb_cpu, ncpus;
int nb_vcpu;
char *cpulist = NULL;
unsigned char *cpumap = NULL;
size_t cpumaplen;
int nb = 0;
int n, m;
virVcpuInfoPtr cpuinfo = NULL;
virNodeInfo nodeinfo;
if (!VIR_IS_CONNECTED_DOMAIN(dom))
return (NULL);
nb_cpu = xenNbCpus(dom->conn);
if (nb_cpu <= 0)
return(NULL);
nb_vcpu = xenUnifiedDomainGetMaxVcpus(dom);
if (nb_vcpu <= 0)
return(NULL);
if (xenUnifiedNodeGetInfo(dom->conn, &nodeinfo) < 0)
return(NULL);
cpulist = (char *) calloc(nb_cpu, sizeof(char));
if (cpulist == NULL)
goto done;
cpuinfo = malloc(sizeof(virVcpuInfo) * nb_vcpu);
if (cpuinfo == NULL)
goto done;
cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
cpumap = (unsigned char *) calloc(nb_vcpu, cpumaplen);
if (cpumap == NULL)
goto done;
if ((ncpus = xenUnifiedDomainGetVcpus(dom, cpuinfo, nb_vcpu,
cpumap, cpumaplen)) >= 0) {
for (n = 0 ; n < ncpus ; n++) {
for (m = 0 ; m < nb_cpu; m++) {
if ((cpulist[m] == 0) &&
(VIR_CPU_USABLE(cpumap, cpumaplen, n, m))) {
cpulist[m] = 1;
nb++;
/* if all CPU are used just return NULL */
if (nb == nb_cpu)
goto done;
}
}
}
res = virSaveCpuSet(dom->conn, cpulist, nb_cpu);
}
done:
if (cpulist != NULL)
free(cpulist);
if (cpumap != NULL)
free(cpumap);
if (cpuinfo != NULL)
free(cpuinfo);
return(res);
}
/*----- Dispatch functions. -----*/ /*----- Dispatch functions. -----*/
/* These dispatch functions follow the model used historically /* These dispatch functions follow the model used historically
@ -862,19 +944,24 @@ static char *
xenUnifiedDomainDumpXML (virDomainPtr dom, int flags) xenUnifiedDomainDumpXML (virDomainPtr dom, int flags)
{ {
GET_PRIVATE(dom->conn); GET_PRIVATE(dom->conn);
int i;
char *ret;
for (i = 0; i < XEN_UNIFIED_NR_DRIVERS; ++i) if (dom->id == -1 && priv->xendConfigVersion < 3 ) {
if (priv->opened[i] && drivers[i]->domainDumpXML) { if (priv->opened[XEN_UNIFIED_XM_OFFSET])
ret = drivers[i]->domainDumpXML (dom, flags); return xenXMDomainDumpXML(dom, flags);
if (ret) return ret; } else {
if (priv->opened[XEN_UNIFIED_XEND_OFFSET]) {
char *cpus, *res;
cpus = xenDomainUsedCpus(dom);
res = xenDaemonDomainDumpXML(dom, flags, cpus);
if (cpus != NULL)
free(cpus);
return(res);
} }
if (priv->opened[XEN_UNIFIED_PROXY_OFFSET])
return xenProxyDomainDumpXML(dom, flags);
}
/* XXX May need to return an error here if sub-drivers didn't xenUnifiedError (dom->conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
* set one. We really should change these to direct calls to
* the sub-drivers at a later date.
*/
return NULL; return NULL;
} }

View File

@ -65,7 +65,6 @@ struct xenUnifiedDriver {
virDrvDomainPinVcpu domainPinVcpu; virDrvDomainPinVcpu domainPinVcpu;
virDrvDomainGetVcpus domainGetVcpus; virDrvDomainGetVcpus domainGetVcpus;
virDrvDomainGetMaxVcpus domainGetMaxVcpus; virDrvDomainGetMaxVcpus domainGetMaxVcpus;
virDrvDomainDumpXML domainDumpXML;
virDrvListDefinedDomains listDefinedDomains; virDrvListDefinedDomains listDefinedDomains;
virDrvNumOfDefinedDomains numOfDefinedDomains; virDrvNumOfDefinedDomains numOfDefinedDomains;
virDrvDomainCreate domainCreate; virDrvDomainCreate domainCreate;
@ -119,6 +118,7 @@ typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;
int xenNbCells(virConnectPtr conn); int xenNbCells(virConnectPtr conn);
int xenNbCpus(virConnectPtr conn); int xenNbCpus(virConnectPtr conn);
char *xenDomainUsedCpus(virDomainPtr dom);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -94,7 +94,6 @@ struct xenUnifiedDriver xenDaemonDriver = {
xenDaemonDomainPinVcpu, /* domainPinVcpu */ xenDaemonDomainPinVcpu, /* domainPinVcpu */
xenDaemonDomainGetVcpus, /* domainGetVcpus */ xenDaemonDomainGetVcpus, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */ NULL, /* domainGetMaxVcpus */
xenDaemonDomainDumpXML, /* domainDumpXML */
xenDaemonListDefinedDomains, /* listDefinedDomains */ xenDaemonListDefinedDomains, /* listDefinedDomains */
xenDaemonNumOfDefinedDomains, /* numOfDefinedDomains */ xenDaemonNumOfDefinedDomains, /* numOfDefinedDomains */
xenDaemonDomainCreate, /* domainCreate */ xenDaemonDomainCreate, /* domainCreate */
@ -1343,6 +1342,7 @@ xend_parse_sexp_desc_os(virConnectPtr xend, struct sexpr *node, virBufferPtr buf
* @root: the root of the parsed S-Expression * @root: the root of the parsed S-Expression
* @xendConfigVersion: version of xend * @xendConfigVersion: version of xend
* @flags: a combination of virDomainXMLFlags * @flags: a combination of virDomainXMLFlags
* @cpus: set of cpus the domain may be pinned to
* *
* Parse the xend sexp description and turn it into the XML format similar * Parse the xend sexp description and turn it into the XML format similar
* to the one unsed for creation. * to the one unsed for creation.
@ -1352,7 +1352,7 @@ xend_parse_sexp_desc_os(virConnectPtr xend, struct sexpr *node, virBufferPtr buf
*/ */
static char * static char *
xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root,
int xendConfigVersion, int flags) int xendConfigVersion, int flags, const char *cpus)
{ {
struct sexpr *cur, *node; struct sexpr *cur, *node;
const char *tmp; const char *tmp;
@ -1438,8 +1438,18 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root,
if ((cur_mem >= MIN_XEN_GUEST_SIZE) && (cur_mem != max_mem)) if ((cur_mem >= MIN_XEN_GUEST_SIZE) && (cur_mem != max_mem))
virBufferVSprintf(&buf, " <currentMemory>%d</currentMemory>\n", virBufferVSprintf(&buf, " <currentMemory>%d</currentMemory>\n",
cur_mem); cur_mem);
virBufferVSprintf(&buf, " <vcpu>%d</vcpu>\n",
virBufferVSprintf(&buf, " <vcpu");
if (cpus != NULL) {
virBufferVSprintf(&buf, " cpuset='%s'", cpus);
}
virBufferVSprintf(&buf, ">%d</vcpu>\n",
sexpr_int(root, "domain/vcpus")); sexpr_int(root, "domain/vcpus"));
/* TODO if need to output the cpus values,
* - parse the cpus values if xend exports
* or
* - analyze the cpus values extracted by xenDaemonDomainGetVcpus
*/
tmp = sexpr_node(root, "domain/on_poweroff"); tmp = sexpr_node(root, "domain/on_poweroff");
if (tmp != NULL) if (tmp != NULL)
virBufferVSprintf(&buf, " <on_poweroff>%s</on_poweroff>\n", tmp); virBufferVSprintf(&buf, " <on_poweroff>%s</on_poweroff>\n", tmp);
@ -1802,7 +1812,7 @@ xend_parse_domain_sexp(virConnectPtr conn, char *sexpr, int xendConfigVersion) {
if (!root) if (!root)
return NULL; return NULL;
data = xend_parse_sexp_desc(conn, root, xendConfigVersion, 0); data = xend_parse_sexp_desc(conn, root, xendConfigVersion, 0, NULL);
sexpr_free(root); sexpr_free(root);
@ -2481,7 +2491,8 @@ xenDaemonDomainSetMemory(virDomainPtr domain, unsigned long memory)
dumpxml will work over proxy for inactive domains dumpxml will work over proxy for inactive domains
and this can be removed */ and this can be removed */
char * char *
xenDaemonDomainDumpXMLByID(virConnectPtr conn, int domid, int flags) xenDaemonDomainDumpXMLByID(virConnectPtr conn, int domid, int flags,
const char *cpus)
{ {
char *ret = NULL; char *ret = NULL;
struct sexpr *root; struct sexpr *root;
@ -2496,14 +2507,16 @@ xenDaemonDomainDumpXMLByID(virConnectPtr conn, int domid, int flags)
priv = (xenUnifiedPrivatePtr) conn->privateData; priv = (xenUnifiedPrivatePtr) conn->privateData;
ret = xend_parse_sexp_desc(conn, root, priv->xendConfigVersion, flags); ret = xend_parse_sexp_desc(conn, root, priv->xendConfigVersion,
flags, cpus);
sexpr_free(root); sexpr_free(root);
return (ret); return (ret);
} }
char * char *
xenDaemonDomainDumpXMLByName(virConnectPtr conn, const char *name, int flags) xenDaemonDomainDumpXMLByName(virConnectPtr conn, const char *name, int flags,
const char *cpus)
{ {
char *ret = NULL; char *ret = NULL;
struct sexpr *root; struct sexpr *root;
@ -2518,7 +2531,8 @@ xenDaemonDomainDumpXMLByName(virConnectPtr conn, const char *name, int flags)
priv = (xenUnifiedPrivatePtr) conn->privateData; priv = (xenUnifiedPrivatePtr) conn->privateData;
ret = xend_parse_sexp_desc(conn, root, priv->xendConfigVersion, flags); ret = xend_parse_sexp_desc(conn, root, priv->xendConfigVersion,
flags, cpus);
sexpr_free(root); sexpr_free(root);
return (ret); return (ret);
@ -2529,6 +2543,8 @@ xenDaemonDomainDumpXMLByName(virConnectPtr conn, const char *name, int flags)
/** /**
* xenDaemonDomainDumpXML: * xenDaemonDomainDumpXML:
* @domain: a domain object * @domain: a domain object
* @flags: potential dump flags
* @cpus: list of cpu the domain is pinned to.
* *
* Provide an XML description of the domain. * Provide an XML description of the domain.
* *
@ -2536,7 +2552,7 @@ xenDaemonDomainDumpXMLByName(virConnectPtr conn, const char *name, int flags)
* the caller must free() the returned value. * the caller must free() the returned value.
*/ */
char * char *
xenDaemonDomainDumpXML(virDomainPtr domain, int flags) xenDaemonDomainDumpXML(virDomainPtr domain, int flags, const char *cpus)
{ {
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv;
@ -2553,9 +2569,11 @@ xenDaemonDomainDumpXML(virDomainPtr domain, int flags)
} }
if (domain->id < 0) if (domain->id < 0)
return xenDaemonDomainDumpXMLByName(domain->conn, domain->name, flags); return xenDaemonDomainDumpXMLByName(domain->conn, domain->name, flags,
cpus);
else else
return xenDaemonDomainDumpXMLByID(domain->conn, domain->id, flags); return xenDaemonDomainDumpXMLByID(domain->conn, domain->id, flags,
cpus);
} }
#endif /* !PROXY */ #endif /* !PROXY */

View File

@ -110,11 +110,13 @@ int xenDaemonDomainLookupByID(virConnectPtr xend,
char *xenDaemonDomainDumpXMLByID(virConnectPtr xend, char *xenDaemonDomainDumpXMLByID(virConnectPtr xend,
int domid, int domid,
int flags); int flags,
const char *cpus);
char *xenDaemonDomainDumpXMLByName(virConnectPtr xend, char *xenDaemonDomainDumpXMLByName(virConnectPtr xend,
const char *name, const char *name,
int flags); int flags,
const char *cpus);
/** /**
* \brief Lookup information about the host machine * \brief Lookup information about the host machine
@ -196,7 +198,7 @@ int xenDaemonDomainRestore(virConnectPtr conn, const char *filename);
int xenDaemonDomainSetMemory(virDomainPtr domain, unsigned long memory); int xenDaemonDomainSetMemory(virDomainPtr domain, unsigned long memory);
int xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory); int xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory);
int xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info); int xenDaemonDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info);
char *xenDaemonDomainDumpXML(virDomainPtr domain, int flags); char *xenDaemonDomainDumpXML(virDomainPtr domain, int flags, const char *cpus);
unsigned long xenDaemonDomainGetMaxMemory(virDomainPtr domain); unsigned long xenDaemonDomainGetMaxMemory(virDomainPtr domain);
char **xenDaemonListDomainsOld(virConnectPtr xend); char **xenDaemonListDomainsOld(virConnectPtr xend);

View File

@ -104,7 +104,6 @@ struct xenUnifiedDriver xenXMDriver = {
NULL, /* domainPinVcpu */ NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */ NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */ NULL, /* domainGetMaxVcpus */
xenXMDomainDumpXML, /* domainDumpXML */
xenXMListDefinedDomains, /* listDefinedDomains */ xenXMListDefinedDomains, /* listDefinedDomains */
xenXMNumOfDefinedDomains, /* numOfDefinedDomains */ xenXMNumOfDefinedDomains, /* numOfDefinedDomains */
xenXMDomainCreate, /* domainCreate */ xenXMDomainCreate, /* domainCreate */
@ -660,11 +659,20 @@ char *xenXMDomainFormatXML(virConnectPtr conn, virConfPtr conf) {
val = MIN_XEN_GUEST_SIZE * 2; val = MIN_XEN_GUEST_SIZE * 2;
virBufferVSprintf(buf, " <memory>%ld</memory>\n", val * 1024); virBufferVSprintf(buf, " <memory>%ld</memory>\n", val * 1024);
virBufferVSprintf(buf, " <vcpu"); /* DV */
if (xenXMConfigGetString(conf, "cpus", &str) == 0) {
char *ranges;
ranges = virConvertCpuSet(conn, str, 0);
if (ranges != NULL) {
virBufferVSprintf(buf, " cpuset='%s'", ranges);
free(ranges);
} else
virBufferVSprintf(buf, " cpuset='%s'", str);
}
if (xenXMConfigGetInt(conf, "vcpus", &val) < 0) if (xenXMConfigGetInt(conf, "vcpus", &val) < 0)
val = 1; val = 1;
virBufferVSprintf(buf, " <vcpu>%ld</vcpu>\n", val); virBufferVSprintf(buf, ">%ld</vcpu>\n", val);
if (xenXMConfigGetString(conf, "on_poweroff", &str) < 0) if (xenXMConfigGetString(conf, "on_poweroff", &str) < 0)
str = "destroy"; str = "destroy";
@ -1763,6 +1771,7 @@ virConfPtr xenXMParseXMLToConfig(virConnectPtr conn, const char *xml) {
virConfPtr conf = NULL; virConfPtr conf = NULL;
int hvm = 0, i; int hvm = 0, i;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv;
char *cpus;
doc = xmlReadDoc((const xmlChar *) xml, "domain.xml", NULL, doc = xmlReadDoc((const xmlChar *) xml, "domain.xml", NULL,
XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOENT | XML_PARSE_NONET |
@ -1821,6 +1830,32 @@ virConfPtr xenXMParseXMLToConfig(virConnectPtr conn, const char *xml) {
"cannot set vcpus config parameter") < 0) "cannot set vcpus config parameter") < 0)
goto error; goto error;
cpus = virXPathString("string(/domain/vcpu/@cpuset)", ctxt);
if (cpus != NULL) {
char *ranges;
ranges = virConvertCpuSet(conn, cpus, 0);
if (ranges != NULL) {
free(cpus);
if (xenXMConfigSetString(conf, "cpus", ranges) < 0) {
free(ranges);
goto error;
}
free(ranges);
} else {
if (xenXMConfigSetString(conf, "cpus", cpus) < 0) {
free(cpus);
goto error;
}
free(cpus);
}
}
if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "cpus", /* DV */
"string(/domain/vcpu/@cpuset)", 1,
"cannot set the cpuset parameter") < 0)
goto error;
obj = xmlXPathEval(BAD_CAST "string(/domain/os/type)", ctxt); obj = xmlXPathEval(BAD_CAST "string(/domain/os/type)", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) && if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && !strcmp((char*)obj->stringval, "hvm")) (obj->stringval != NULL) && !strcmp((char*)obj->stringval, "hvm"))

View File

@ -135,7 +135,7 @@ parseCpuNumber(const char **str, int maxcpu)
} }
/** /**
* saveCpuSet: * virSaveCpuSet:
* @conn: connection * @conn: connection
* @cpuset: pointer to a char array for the CPU set * @cpuset: pointer to a char array for the CPU set
* @maxcpu: number of elements available in @cpuset * @maxcpu: number of elements available in @cpuset
@ -145,8 +145,8 @@ parseCpuNumber(const char **str, int maxcpu)
* Returns the new string NULL in case of error. The string need to be * Returns the new string NULL in case of error. The string need to be
* freed by the caller. * freed by the caller.
*/ */
static char * char *
saveCpuSet(virConnectPtr conn, char *cpuset, int maxcpu) virSaveCpuSet(virConnectPtr conn, char *cpuset, int maxcpu)
{ {
virBufferPtr buf; virBufferPtr buf;
char *ret; char *ret;
@ -174,8 +174,6 @@ saveCpuSet(virConnectPtr conn, char *cpuset, int maxcpu)
first = 0; first = 0;
if (cur == start + 1) if (cur == start + 1)
virBufferVSprintf(buf, "%d", start); virBufferVSprintf(buf, "%d", start);
else if (cur == start + 2)
virBufferVSprintf(buf, "%d,%d", start, cur - 1);
else else
virBufferVSprintf(buf, "%d-%d", start, cur - 1); virBufferVSprintf(buf, "%d-%d", start, cur - 1);
start = -1; start = -1;
@ -187,8 +185,6 @@ saveCpuSet(virConnectPtr conn, char *cpuset, int maxcpu)
virBufferAdd(buf, ",", -1); virBufferAdd(buf, ",", -1);
if (maxcpu == start + 1) if (maxcpu == start + 1)
virBufferVSprintf(buf, "%d", start); virBufferVSprintf(buf, "%d", start);
else if (maxcpu == start + 2)
virBufferVSprintf(buf, "%d,%d", start, maxcpu - 1);
else else
virBufferVSprintf(buf, "%d-%d", start, maxcpu - 1); virBufferVSprintf(buf, "%d-%d", start, maxcpu - 1);
} }
@ -198,6 +194,7 @@ saveCpuSet(virConnectPtr conn, char *cpuset, int maxcpu)
/** /**
* virParseCpuSet: * virParseCpuSet:
* @conn: connection
* @str: pointer to a CPU set string pointer * @str: pointer to a CPU set string pointer
* @sep: potential character used to mark the end of string if not 0 * @sep: potential character used to mark the end of string if not 0
* @cpuset: pointer to a char array for the CPU set * @cpuset: pointer to a char array for the CPU set
@ -300,6 +297,7 @@ virParseCpuSet(virConnectPtr conn, const char **str, char sep,
/** /**
* virParseXenCpuTopology: * virParseXenCpuTopology:
* @conn: connection
* @xml: XML output buffer * @xml: XML output buffer
* @str: the topology string * @str: the topology string
* @maxcpu: number of elements available in @cpuset * @maxcpu: number of elements available in @cpuset
@ -362,7 +360,7 @@ virParseXenCpuTopology(virConnectPtr conn, virBufferPtr xml,
{ {
char *dump; char *dump;
dump = saveCpuSet(conn, cpuset, maxcpu); dump = virSaveCpuSet(conn, cpuset, maxcpu);
if (dump != NULL) { if (dump != NULL) {
virBufferVSprintf(xml, " <dump>%s</dump>\n", virBufferVSprintf(xml, " <dump>%s</dump>\n",
dump); dump);
@ -408,6 +406,45 @@ virParseXenCpuTopology(virConnectPtr conn, virBufferPtr xml,
return (-1); return (-1);
} }
/**
* virConvertCpuSet:
* @conn: connection
* @str: pointer to a Xen or user provided CPU set string pointer
* @maxcpu: number of CPUs on the node, if 0 4096 will be used
*
* Parse the given CPU set string and convert it to a range based
* string.
*
* Returns a new string which must be freed by the caller or NULL in
* case of error.
*/
char *
virConvertCpuSet(virConnectPtr conn, const char *str, int maxcpu) {
int ret;
char *res, *cpuset;
const char *cur = str;
if (str == NULL)
return(NULL);
if (maxcpu <= 0)
maxcpu = 4096;
cpuset = calloc(maxcpu, sizeof(char));
if (cpuset == NULL) {
virXMLError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"), 0);
return(NULL);
}
ret = virParseCpuSet(conn, &cur, 0, cpuset, maxcpu);
if (ret < 0) {
free(cpuset);
return(NULL);
}
res = virSaveCpuSet(conn, cpuset, maxcpu);
free(cpuset);
return (res);
}
#ifndef PROXY #ifndef PROXY
/************************************************************************ /************************************************************************
@ -1603,7 +1640,7 @@ virDomainParseXMLDesc(virConnectPtr conn, const char *xmldesc, char **name,
if (cpuset != NULL) { if (cpuset != NULL) {
res = virParseCpuSet(conn, &cur, 0, cpuset, maxcpu); res = virParseCpuSet(conn, &cur, 0, cpuset, maxcpu);
if (res > 0) { if (res > 0) {
ranges = saveCpuSet(conn, cpuset, maxcpu); ranges = virSaveCpuSet(conn, cpuset, maxcpu);
if (ranges != NULL) { if (ranges != NULL) {
virBufferVSprintf(&buf, "(cpus '%s')", ranges); virBufferVSprintf(&buf, "(cpus '%s')", ranges);
free(ranges); free(ranges);

View File

@ -41,6 +41,12 @@ int virParseCpuSet (virConnectPtr conn,
char sep, char sep,
char *cpuset, char *cpuset,
int maxcpu); int maxcpu);
char * virSaveCpuSet (virConnectPtr conn,
char *cpuset,
int maxcpu);
char * virConvertCpuSet(virConnectPtr conn,
const char *str,
int maxcpu);
char * virDomainParseXMLDesc(virConnectPtr conn, char * virDomainParseXMLDesc(virConnectPtr conn,
const char *xmldesc, const char *xmldesc,
char **name, char **name,