From 208a450a53a7edabff2157c1aba491afde268270 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 28 Nov 2007 10:11:18 +0000 Subject: [PATCH] Wed Nov 28 09:00:00 GMT 2007 Richard W.M. Jones * src/xm_internal.c, src/xm_internal.h: Added support for pinning inactive domains for Xen 3.0.3 (Saori Fukuta). --- ChangeLog | 5 +++ src/xm_internal.c | 105 +++++++++++++++++++++++++++++++++++++++++++++- src/xm_internal.h | 2 + 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8ecc3fb3bd..c39cf22498 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Nov 28 09:00:00 GMT 2007 Richard W.M. Jones + + * src/xm_internal.c, src/xm_internal.h: Added support for + pinning inactive domains for Xen 3.0.3 (Saori Fukuta). + Tue Nov 27 19:16:43 CET 2007 Jim Meyering When reporting errors, use "conn" whenever possible. diff --git a/src/xm_internal.c b/src/xm_internal.c index e8c1ac3e45..ce886fc982 100644 --- a/src/xm_internal.c +++ b/src/xm_internal.c @@ -52,6 +52,9 @@ #include "buf.h" #include "uuid.h" +static int xenXMConfigSetString(virConfPtr conf, const char *setting, + const char *str); + typedef struct xenXMConfCache *xenXMConfCachePtr; typedef struct xenXMConfCache { time_t refreshedAt; @@ -101,7 +104,7 @@ struct xenUnifiedDriver xenXMDriver = { NULL, /* domainRestore */ NULL, /* domainCoreDump */ xenXMDomainSetVcpus, /* domainSetVcpus */ - NULL, /* domainPinVcpu */ + xenXMDomainPinVcpu, /* domainPinVcpu */ NULL, /* domainGetVcpus */ NULL, /* domainGetMaxVcpus */ xenXMListDefinedDomains, /* listDefinedDomains */ @@ -1215,6 +1218,106 @@ int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus) { return (0); } +/** + * xenXMDomainPinVcpu: + * @domain: pointer to domain object + * @vcpu: virtual CPU number (reserved) + * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) + * @maplen: length of cpumap in bytes + * + * Set the vcpu affinity in config + * + * Returns 0 for success; -1 (with errno) on error + */ +int xenXMDomainPinVcpu(virDomainPtr domain, + unsigned int vcpu ATTRIBUTE_UNUSED, + unsigned char *cpumap, int maplen) +{ + const char *filename; + xenXMConfCachePtr entry; + virBufferPtr mapbuf; + char *mapstr = NULL; + char *ranges = NULL; + int i, j, n, comma = 0; + int ret = -1; + + if (domain == NULL || domain->conn == NULL || domain->name == NULL + || cpumap == NULL || maplen < 1 || maplen > (int)sizeof(cpumap_t)) { + xenXMError(domain ? domain->conn : NULL, VIR_ERR_INVALID_ARG, + __FUNCTION__); + return -1; + } + if (domain->conn->flags & VIR_CONNECT_RO) { + xenXMError (domain->conn, VIR_ERR_INVALID_ARG, "read only connection"); + return -1; + } + if (domain->id != -1) { + xenXMError (domain->conn, VIR_ERR_INVALID_ARG, "not inactive domain"); + return -1; + } + + if (!(filename = virHashLookup(nameConfigMap, domain->name))) { + xenXMError (domain->conn, VIR_ERR_INTERNAL_ERROR, "virHashLookup"); + return -1; + } + if (!(entry = virHashLookup(configCache, filename))) { + xenXMError (domain->conn, VIR_ERR_INTERNAL_ERROR, + "can't retrieve config file for domain"); + return -1; + } + + /* from bit map, build character string of mapped CPU numbers */ + mapbuf = virBufferNew (16); + if (mapbuf == NULL) { + xenXMError (domain->conn, VIR_ERR_NO_MEMORY, __FUNCTION__); + return -1; + } + for (i = 0; i < maplen; i++) + for (j = 0; j < 8; j++) + if ((cpumap[i] & (1 << j))) { + n = i*8 + j; + + if (comma) { + if (virBufferAdd (mapbuf, ",", 1) == -1) { + xenXMError (domain->conn, VIR_ERR_NO_MEMORY, __FUNCTION__); + virBufferFree (mapbuf); + return -1; + } + } + comma = 1; + + if (virBufferVSprintf (mapbuf, "%d", n) == -1) { + xenXMError (domain->conn, VIR_ERR_NO_MEMORY, __FUNCTION__); + virBufferFree (mapbuf); + return -1; + } + } + + mapstr = virBufferContentAndFree (mapbuf); + + /* convert the mapstr to a range based string */ + ranges = virConvertCpuSet(domain->conn, mapstr, 0); + + if (ranges != NULL) { + if (xenXMConfigSetString(entry->conf, "cpus", ranges) < 0) + goto cleanup; + } else + if (xenXMConfigSetString(entry->conf, "cpus", mapstr) < 0) + goto cleanup; + + if (virConfWriteFile(entry->filename, entry->conf) < 0) + goto cleanup; + + ret = 0; + + cleanup: + if(mapstr) + free(mapstr); + if(ranges) + free(ranges); + return (ret); +} + /* * Find an inactive domain based on its name */ diff --git a/src/xm_internal.h b/src/xm_internal.h index 33a949078e..5cc13fd4b4 100644 --- a/src/xm_internal.h +++ b/src/xm_internal.h @@ -45,6 +45,8 @@ int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory); int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory); unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain); int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus); +int xenXMDomainPinVcpu(virDomainPtr domain, unsigned int vcpu, + unsigned char *cpumap, int maplen); virDomainPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname); virDomainPtr xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid); -- GitLab