Native config files sometimes can setup cpuset.cpus to pin some CPUs.
Before this, LXC was using a fixed number of 1 VCPU. After this commit,
XML definition will generate a dynamic number of VCPUs based on that
cgroup attribute.
Signed-off-by: Julio Faracco <jcfaracco@gmail.com>
---
src/lxc/lxc_container.c | 23 ++++++++++++++++++
src/lxc/lxc_container.h | 2 ++
src/lxc/lxc_native.c | 24 +++++++++++++++++--
.../lxcconf2xml-cpusettune.xml | 2 +-
4 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 88e27f3060..c5788e5c32 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -2487,3 +2487,26 @@ int lxcContainerChown(virDomainDefPtr def, const char *path)
return 0;
}
+
+
+int lxcContainerGetMaxCpusInCpuset(const char *cpuset)
+{
+ const char *c = cpuset;
+ int max_cpu = 0;
+
+ while (c) {
+ int a, b, ret;
+
+ ret = sscanf(c, "%d-%d", &a, &b);
+ if (ret == 1)
+ max_cpu++;
+ else if (ret == 2)
+ max_cpu += a > b ? a - b + 1 : b - a + 1;
+
+ if (!(c = strchr(c+1, ',')))
+ break;
+ c++;
+ }
+
+ return max_cpu;
+}
diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h
index 94a6c5309c..6f112e0667 100644
--- a/src/lxc/lxc_container.h
+++ b/src/lxc/lxc_container.h
@@ -63,3 +63,5 @@ virArch lxcContainerGetAlt32bitArch(virArch arch);
int lxcContainerChown(virDomainDefPtr def, const char *path);
bool lxcIsBasicMountLocation(const char *path);
+
+int lxcContainerGetMaxCpusInCpuset(const char *cpuset);
diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c
index 02d2bf33e4..409bf00bd2 100644
--- a/src/lxc/lxc_native.c
+++ b/src/lxc/lxc_native.c
@@ -993,6 +993,24 @@ lxcSetCpusetTune(virDomainDefPtr def, virConfPtr properties)
return 0;
}
+
+static int
+lxcGetVCpuMax(virConfPtr properties)
+{
+ g_autofree char *value = NULL;
+ int vcpumax = 1;
+
+ if (virConfGetValueString(properties, "lxc.cgroup.cpuset.cpus",
+ &value) > 0) {
+ vcpumax = lxcContainerGetMaxCpusInCpuset(value);
+ if (vcpumax > 0)
+ return vcpumax;
+ }
+
+ return vcpumax;
+}
+
+
static int
lxcBlkioDeviceWalkCallback(const char *name, virConfValuePtr value, void *data)
{
@@ -1132,6 +1150,7 @@ lxcParseConfigString(const char *config,
virDomainDefPtr vmdef = NULL;
g_autoptr(virConf) properties = NULL;
g_autofree char *value = NULL;
+ int vcpumax;
if (!(properties = virConfReadString(config, VIR_CONF_FLAG_LXC_FORMAT)))
return NULL;
@@ -1155,10 +1174,11 @@ lxcParseConfigString(const char *config,
/* Value not handled by the LXC driver, setting to
* minimum required to make XML parsing pass */
- if (virDomainDefSetVcpusMax(vmdef, 1, xmlopt) < 0)
+ vcpumax = lxcGetVCpuMax(properties);
+ if (virDomainDefSetVcpusMax(vmdef, vcpumax, xmlopt) < 0)
goto error;
- if (virDomainDefSetVcpus(vmdef, 1) < 0)
+ if (virDomainDefSetVcpus(vmdef, vcpumax) < 0)
goto error;
vmdef->nfss = 0;
diff --git a/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml b/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml
index 6df089d00f..a1fec12d9b 100644
--- a/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml
+++ b/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml
@@ -3,7 +3,7 @@
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>65536</memory>
<currentMemory unit='KiB'>65536</currentMemory>
- <vcpu placement='static' cpuset='1-2,5-7'>1</vcpu>
+ <vcpu placement='static' cpuset='1-2,5-7'>5</vcpu>
<numatune>
<memory mode='strict' nodeset='1-4'/>
</numatune>
--
2.20.1
On Mon, Feb 24, 2020 at 11:24:29AM -0300, Julio Faracco wrote:
> Native config files sometimes can setup cpuset.cpus to pin some CPUs.
> Before this, LXC was using a fixed number of 1 VCPU. After this commit,
> XML definition will generate a dynamic number of VCPUs based on that
> cgroup attribute.
I'm not sure whether this is worth doing - mapping between VCPU count
and CPUset doesn't really work during startup. Historically we've just
completely ignored <vcpu> for containers. Ideally that element should
have been optional in the XML parser as it is not a good conceptual
fit for LXC.
>
> Signed-off-by: Julio Faracco <jcfaracco@gmail.com>
> ---
> src/lxc/lxc_container.c | 23 ++++++++++++++++++
> src/lxc/lxc_container.h | 2 ++
> src/lxc/lxc_native.c | 24 +++++++++++++++++--
> .../lxcconf2xml-cpusettune.xml | 2 +-
> 4 files changed, 48 insertions(+), 3 deletions(-)
>
> diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
> index 88e27f3060..c5788e5c32 100644
> --- a/src/lxc/lxc_container.c
> +++ b/src/lxc/lxc_container.c
> @@ -2487,3 +2487,26 @@ int lxcContainerChown(virDomainDefPtr def, const char *path)
>
> return 0;
> }
> +
> +
> +int lxcContainerGetMaxCpusInCpuset(const char *cpuset)
> +{
> + const char *c = cpuset;
> + int max_cpu = 0;
> +
> + while (c) {
> + int a, b, ret;
> +
> + ret = sscanf(c, "%d-%d", &a, &b);
> + if (ret == 1)
> + max_cpu++;
> + else if (ret == 2)
> + max_cpu += a > b ? a - b + 1 : b - a + 1;
> +
> + if (!(c = strchr(c+1, ',')))
> + break;
> + c++;
> + }
> +
> + return max_cpu;
> +}
> diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h
> index 94a6c5309c..6f112e0667 100644
> --- a/src/lxc/lxc_container.h
> +++ b/src/lxc/lxc_container.h
> @@ -63,3 +63,5 @@ virArch lxcContainerGetAlt32bitArch(virArch arch);
> int lxcContainerChown(virDomainDefPtr def, const char *path);
>
> bool lxcIsBasicMountLocation(const char *path);
> +
> +int lxcContainerGetMaxCpusInCpuset(const char *cpuset);
> diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c
> index 02d2bf33e4..409bf00bd2 100644
> --- a/src/lxc/lxc_native.c
> +++ b/src/lxc/lxc_native.c
> @@ -993,6 +993,24 @@ lxcSetCpusetTune(virDomainDefPtr def, virConfPtr properties)
> return 0;
> }
>
> +
> +static int
> +lxcGetVCpuMax(virConfPtr properties)
> +{
> + g_autofree char *value = NULL;
> + int vcpumax = 1;
> +
> + if (virConfGetValueString(properties, "lxc.cgroup.cpuset.cpus",
> + &value) > 0) {
> + vcpumax = lxcContainerGetMaxCpusInCpuset(value);
> + if (vcpumax > 0)
> + return vcpumax;
> + }
> +
> + return vcpumax;
> +}
> +
> +
> static int
> lxcBlkioDeviceWalkCallback(const char *name, virConfValuePtr value, void *data)
> {
> @@ -1132,6 +1150,7 @@ lxcParseConfigString(const char *config,
> virDomainDefPtr vmdef = NULL;
> g_autoptr(virConf) properties = NULL;
> g_autofree char *value = NULL;
> + int vcpumax;
>
> if (!(properties = virConfReadString(config, VIR_CONF_FLAG_LXC_FORMAT)))
> return NULL;
> @@ -1155,10 +1174,11 @@ lxcParseConfigString(const char *config,
>
> /* Value not handled by the LXC driver, setting to
> * minimum required to make XML parsing pass */
> - if (virDomainDefSetVcpusMax(vmdef, 1, xmlopt) < 0)
> + vcpumax = lxcGetVCpuMax(properties);
> + if (virDomainDefSetVcpusMax(vmdef, vcpumax, xmlopt) < 0)
> goto error;
>
> - if (virDomainDefSetVcpus(vmdef, 1) < 0)
> + if (virDomainDefSetVcpus(vmdef, vcpumax) < 0)
> goto error;
>
> vmdef->nfss = 0;
> diff --git a/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml b/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml
> index 6df089d00f..a1fec12d9b 100644
> --- a/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml
> +++ b/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml
> @@ -3,7 +3,7 @@
> <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
> <memory unit='KiB'>65536</memory>
> <currentMemory unit='KiB'>65536</currentMemory>
> - <vcpu placement='static' cpuset='1-2,5-7'>1</vcpu>
> + <vcpu placement='static' cpuset='1-2,5-7'>5</vcpu>
> <numatune>
> <memory mode='strict' nodeset='1-4'/>
> </numatune>
> --
> 2.20.1
>
>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
© 2016 - 2026 Red Hat, Inc.