[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