[libvirt] [PATCH 2/3] lxc: Implement emulator pin API in lxc driver
John Ferlan
jferlan at redhat.com
Wed Oct 22 15:34:20 UTC 2014
On 09/04/2014 03:52 AM, Wang Rui wrote:
> From: Yue Wenyuan <yuewenyuan at huawei.com>
>
> Implement the lxc driver method for virDomainPinEmulator
> to set container's cpuset.
>
> Signed-off-by: Wang Rui <moon.wangrui at huawei.com>
> Signed-off-by: Yue Wenyuan <yuewenyuan at 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 */
>
More information about the libvir-list
mailing list