On 09/04/2014 03:52 AM, Wang Rui wrote: > 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); > + 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 */ > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list