Index: xm_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xm_internal.c,v retrieving revision 1.47 diff -u -p -r1.47 xm_internal.c --- xm_internal.c 21 Nov 2007 16:31:30 -0000 1.47 +++ xm_internal.c 27 Nov 2007 12:29:21 -0000 @@ -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,84 @@ int xenXMDomainSetVcpus(virDomainPtr dom 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, + unsigned char *cpumap, int maplen) +{ + const char *filename; + xenXMConfCachePtr entry; + char *mapstr = NULL; + char *ranges = NULL; + int alloc_sz = 0; + int i, j; + int len; + 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) + return (-1); + if (domain->id != -1) + return (-1); + + if (!(filename = virHashLookup(nameConfigMap, domain->name))) + return (-1); + if (!(entry = virHashLookup(configCache, filename))) + return (-1); + + /* allocate memory for mapstr */ + alloc_sz = (maplen * 32); + mapstr = malloc(alloc_sz); + if (mapstr == NULL) + return (-1); + memset(mapstr, 0, alloc_sz); + + /* from bit map, build character string of mapped CPU numbers */ + for (i = 0; i < maplen; i++) + for (j = 0; j < 8; j++) + if (cpumap[i] & (1 << j)) { + len = snprintf(mapstr, alloc_sz, "%s%d,", mapstr, (8 * i) + j); + if (len >= alloc_sz) + goto cleanup; + } + mapstr[strlen(mapstr) - 1] = '\0'; + + /* 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 */ Index: xm_internal.h =================================================================== RCS file: /data/cvs/libvirt/src/xm_internal.h,v retrieving revision 1.6 diff -u -p -r1.6 xm_internal.h --- xm_internal.h 14 Nov 2007 11:40:57 -0000 1.6 +++ xm_internal.h 27 Nov 2007 12:29:21 -0000 @@ -45,6 +45,8 @@ int xenXMDomainSetMemory(virDomainPtr do 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);