On 09/04/2014 03:52 AM, Wang Rui wrote:
From: Yue Wenyuan <yuewenyuan(a)huawei.com>
Implement the lxc driver method for virDomainPinEmulator
to set container's cpuset.
Signed-off-by: Wang Rui <moon.wangrui(a)huawei.com>
Signed-off-by: Yue Wenyuan <yuewenyuan(a)huawei.com>
---
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);
+
alignment issues with the arguments
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)
Alignment issues with arguments.
+{
+ 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;
This is set, but never used - compilation failure on my Fedora system
+
+ if (flags & VIR_DOMAIN_AFFECT_LIVE) {
+ if (virCgroupHasController(priv->cgroup,
+ VIR_CGROUP_CONTROLLER_CPUSET)) {
Alignment issues
+ if (virCgroupNewEmulator(priv->cgroup, false,
&cgroup_emulator) < 0)
+ goto cleanup;
+ if (virLXCSetupCgroupEmulatorPin(cgroup_emulator,
+ pcpumap) < 0) {
Alignment issues
+ virReportError(VIR_ERR_OPERATION_INVALID,
"%s",
+ _("failed to set cpuset.cpus in cgroup "
+ "for lxc emulator"));
+ goto cleanup;
+ }
+ } else {
And here is the missing line from the comparable qemu code, e.g. a call
to virProcessSetAffinity(pid, pcpumap).
I note that the LXC code during virLXCControllerSetupCpuAffinity will
call SetAffinity with 0 (zero) as the pid. Whether that's relevant here
or not I'm not quite sure.
+ virReportError(VIR_ERR_SYSTEM_ERROR, "%s",
+ _("there is not cgroup controller for "
+ "lxc emulator"));
Perhaps better said "no cpuset cgroup controller found for lxc emulator"
- although just because HasController/CPUSET fails, we won't continue
which doesn't seem right.
+ 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;
The qemu code will issue a (new) event here for
VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN... Is that applicable here? If so and
you add it, don't forget to clean up the event during 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*/
Comment spacing is off, will now be at least /* 1.2.10 */
John
.domainLookupByID = lxcDomainLookupByID, /* 0.4.2 */
.domainLookupByUUID = lxcDomainLookupByUUID, /* 0.4.2 */
.domainLookupByName = lxcDomainLookupByName, /* 0.4.2 */