From: Yue Wenyuan <yuewenyuan@xxxxxxxxxx> Implement the lxc driver method for virDomainPinEmulator to set container's cpuset. Signed-off-by: Wang Rui <moon.wangrui@xxxxxxxxxx> Signed-off-by: Yue Wenyuan <yuewenyuan@xxxxxxxxxx> --- src/lxc/lxc_cgroup.c | 20 ++++++++ src/lxc/lxc_cgroup.h | 3 ++ src/lxc/lxc_driver.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+) diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index f696bf8..7dc7c9b 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -531,6 +531,26 @@ int virLXCCgroupSetup(virDomainDefPtr def, return ret; } +int +virLXCSetupCgroupEmulatorPin(virCgroupPtr cgroup, + virBitmapPtr cpumask) +{ + int ret = -1; + char *new_cpus = NULL; + + if (!(new_cpus = virBitmapFormat(cpumask))) + goto cleanup; + + if (virCgroupSetCpusetCpus(cgroup, new_cpus) < 0) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(new_cpus); + return ret; +} + static int virLXCCgroupSetupCpusetTuneForEmulator(virDomainDefPtr def, virCgroupPtr cgroup, virBitmapPtr nodemask) diff --git a/src/lxc/lxc_cgroup.h b/src/lxc/lxc_cgroup.h index 32086c5..8011a32 100644 --- a/src/lxc/lxc_cgroup.h +++ b/src/lxc/lxc_cgroup.h @@ -33,6 +33,9 @@ int virLXCCgroupSetup(virDomainDefPtr def, virCgroupPtr cgroup, virBitmapPtr nodemask); +int virLXCSetupCgroupEmulatorPin(virCgroupPtr cgroup, + virBitmapPtr cpumask); + int virLXCCgroupSetupForEmulator(virDomainDefPtr def, virCgroupPtr cgroup, virBitmapPtr nodemask); diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 66d708a..9e3a877 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1264,6 +1264,136 @@ lxcDomainCreateXML(virConnectPtr conn, return lxcDomainCreateXMLWithFiles(conn, xml, 0, NULL, flags); } +static int +lxcDomainPinEmulator(virDomainPtr dom, + unsigned char *cpumap, + int maplen, + unsigned int flags) +{ + virLXCDriverPtr driver = dom->conn->privateData; + virDomainObjPtr vm; + virCgroupPtr cgroup_emulator = NULL; + pid_t pid; + virDomainDefPtr persistentDef = NULL; + int ret = -1; + virLXCDomainObjPrivatePtr priv; + bool doReset = false; + virBitmapPtr pcpumap = NULL; + virLXCDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; + + virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + + cfg = virLXCDriverGetConfig(driver); + + if (!(vm = lxcDomObjFromDomain(dom))) + goto cleanup; + + if (virDomainPinEmulatorEnsureACL(dom->conn, vm->def, flags) < 0) + goto cleanup; + + if (!(caps = virLXCDriverGetCapabilities(driver, false))) + goto cleanup; + + if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("Changing affinity for emulator thread dynamically " + "is not allowed when CPU placement is 'auto'")); + goto cleanup; + } + + if (virDomainLiveConfigHelperMethod(caps, driver->xmlopt, vm, &flags, + &persistentDef) < 0) + goto cleanup; + + priv = vm->privateData; + + pcpumap = virBitmapNewData(cpumap, maplen); + if (!pcpumap) + goto cleanup; + + if (virBitmapIsAllClear(pcpumap)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Empty cpu list for pinning")); + goto cleanup; + } + + if (virBitmapIsAllSet(pcpumap)) + doReset = true; + + pid = vm->pid; + + if (flags & VIR_DOMAIN_AFFECT_LIVE) { + if (virCgroupHasController(priv->cgroup, + VIR_CGROUP_CONTROLLER_CPUSET)) { + if (virCgroupNewEmulator(priv->cgroup, false, &cgroup_emulator) < 0) + goto cleanup; + if (virLXCSetupCgroupEmulatorPin(cgroup_emulator, + pcpumap) < 0) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("failed to set cpuset.cpus in cgroup " + "for lxc emulator")); + goto cleanup; + } + } else { + virReportError(VIR_ERR_SYSTEM_ERROR, "%s", + _("there is not cgroup controller for " + "lxc emulator")); + goto cleanup; + } + if (doReset) { + if (virDomainEmulatorPinDel(vm->def) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to delete emulatorpin xml of " + "a running domain")); + goto cleanup; + } + } else { + if (virDomainEmulatorPinAdd(vm->def, cpumap, maplen) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to update or add emulatorpin xml " + "of a running domain")); + goto cleanup; + } + } + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) + goto cleanup; + } + + if (flags & VIR_DOMAIN_AFFECT_CONFIG) { + if (doReset) { + if (virDomainEmulatorPinDel(persistentDef) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to delete emulatorpin xml of " + "a persistent domain")); + goto cleanup; + } + } else { + if (virDomainEmulatorPinAdd(persistentDef, cpumap, maplen) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to update or add emulatorpin xml " + "of a persistent domain")); + goto cleanup; + } + } + + ret = virDomainSaveConfig(cfg->configDir, persistentDef); + goto cleanup; + } + + ret = 0; + + cleanup: + if (cgroup_emulator) + virCgroupFree(&cgroup_emulator); + virBitmapFree(pcpumap); + virObjectUnref(caps); + if (vm) + virObjectUnlock(vm); + virObjectUnref(cfg); + return ret; +} static int lxcDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr seclabel) { @@ -5700,6 +5830,7 @@ static virDriver lxcDriver = { .connectListAllDomains = lxcConnectListAllDomains, /* 0.9.13 */ .domainCreateXML = lxcDomainCreateXML, /* 0.4.4 */ .domainCreateXMLWithFiles = lxcDomainCreateXMLWithFiles, /* 1.1.1 */ + .domainPinEmulator = lxcDomainPinEmulator, /*1.2.9*/ .domainLookupByID = lxcDomainLookupByID, /* 0.4.2 */ .domainLookupByUUID = lxcDomainLookupByUUID, /* 0.4.2 */ .domainLookupByName = lxcDomainLookupByName, /* 0.4.2 */ -- 1.7.12.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list