Change-Id: I5821dc8a44f724e59cee65e356dfae4fbae04f76 Signed-off-by: LiFeng <lifeng68@huawei.com>
320 lines
7.3 KiB
Diff
320 lines
7.3 KiB
Diff
From 1118dbb609b83fcca6871e17a11de0752ef3f9d7 Mon Sep 17 00:00:00 2001
|
|
From: LiFeng <lifeng68@huawei.com>
|
|
Date: Wed, 18 Dec 2019 22:37:08 -0500
|
|
Subject: [PATCH 134/138] lxc: do cpuset same as runc
|
|
|
|
Signed-off-by: LiFeng <lifeng68@huawei.com>
|
|
---
|
|
src/lxc/cgroups/cgfsng.c | 288 +----------------------------------------------
|
|
1 file changed, 3 insertions(+), 285 deletions(-)
|
|
|
|
diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
|
|
index 5908c31..79fc5d3 100644
|
|
--- a/src/lxc/cgroups/cgfsng.c
|
|
+++ b/src/lxc/cgroups/cgfsng.c
|
|
@@ -248,288 +248,6 @@ static char *read_file(const char *fnam)
|
|
return buf;
|
|
}
|
|
|
|
-/* Taken over modified from the kernel sources. */
|
|
-#define NBITS 32 /* bits in uint32_t */
|
|
-#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
|
|
-#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, NBITS)
|
|
-
|
|
-static void set_bit(unsigned bit, uint32_t *bitarr)
|
|
-{
|
|
- bitarr[bit / NBITS] |= (1 << (bit % NBITS));
|
|
-}
|
|
-
|
|
-static void clear_bit(unsigned bit, uint32_t *bitarr)
|
|
-{
|
|
- bitarr[bit / NBITS] &= ~(1 << (bit % NBITS));
|
|
-}
|
|
-
|
|
-static bool is_set(unsigned bit, uint32_t *bitarr)
|
|
-{
|
|
- return (bitarr[bit / NBITS] & (1 << (bit % NBITS))) != 0;
|
|
-}
|
|
-
|
|
-/* Create cpumask from cpulist aka turn:
|
|
- *
|
|
- * 0,2-3
|
|
- *
|
|
- * into bit array
|
|
- *
|
|
- * 1 0 1 1
|
|
- */
|
|
-static uint32_t *lxc_cpumask(char *buf, size_t nbits)
|
|
-{
|
|
- char *token;
|
|
- size_t arrlen;
|
|
- uint32_t *bitarr;
|
|
-
|
|
- arrlen = BITS_TO_LONGS(nbits);
|
|
- bitarr = calloc(arrlen, sizeof(uint32_t));
|
|
- if (!bitarr)
|
|
- return NULL;
|
|
-
|
|
- lxc_iterate_parts(token, buf, ",") {
|
|
- errno = 0;
|
|
- unsigned end, start;
|
|
- char *range;
|
|
-
|
|
- start = strtoul(token, NULL, 0);
|
|
- end = start;
|
|
- range = strchr(token, '-');
|
|
- if (range)
|
|
- end = strtoul(range + 1, NULL, 0);
|
|
-
|
|
- if (!(start <= end)) {
|
|
- free(bitarr);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- if (end >= nbits) {
|
|
- free(bitarr);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- while (start <= end)
|
|
- set_bit(start++, bitarr);
|
|
- }
|
|
-
|
|
- return bitarr;
|
|
-}
|
|
-
|
|
-/* Turn cpumask into simple, comma-separated cpulist. */
|
|
-static char *lxc_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits)
|
|
-{
|
|
- int ret;
|
|
- size_t i;
|
|
- char **cpulist = NULL;
|
|
- char numstr[INTTYPE_TO_STRLEN(size_t)] = {0};
|
|
-
|
|
- for (i = 0; i <= nbits; i++) {
|
|
- if (!is_set(i, bitarr))
|
|
- continue;
|
|
-
|
|
- ret = snprintf(numstr, sizeof(numstr), "%zu", i);
|
|
- if (ret < 0 || (size_t)ret >= sizeof(numstr)) {
|
|
- lxc_free_array((void **)cpulist, free);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- ret = lxc_append_string(&cpulist, numstr);
|
|
- if (ret < 0) {
|
|
- lxc_free_array((void **)cpulist, free);
|
|
- return NULL;
|
|
- }
|
|
- }
|
|
-
|
|
- if (!cpulist)
|
|
- return NULL;
|
|
-
|
|
- return lxc_string_join(",", (const char **)cpulist, false);
|
|
-}
|
|
-
|
|
-static ssize_t get_max_cpus(char *cpulist)
|
|
-{
|
|
- char *c1, *c2;
|
|
- char *maxcpus = cpulist;
|
|
- size_t cpus = 0;
|
|
-
|
|
- c1 = strrchr(maxcpus, ',');
|
|
- if (c1)
|
|
- c1++;
|
|
-
|
|
- c2 = strrchr(maxcpus, '-');
|
|
- if (c2)
|
|
- c2++;
|
|
-
|
|
- if (!c1 && !c2)
|
|
- c1 = maxcpus;
|
|
- else if (c1 > c2)
|
|
- c2 = c1;
|
|
- else if (c1 < c2)
|
|
- c1 = c2;
|
|
- else if (!c1 && c2)
|
|
- c1 = c2;
|
|
-
|
|
- errno = 0;
|
|
- cpus = strtoul(c1, NULL, 0);
|
|
- if (errno != 0)
|
|
- return -1;
|
|
-
|
|
- return cpus;
|
|
-}
|
|
-
|
|
-#define __ISOL_CPUS "/sys/devices/system/cpu/isolated"
|
|
-static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized)
|
|
-{
|
|
- int ret;
|
|
- ssize_t i;
|
|
- char *lastslash, *fpath, oldv;
|
|
- ssize_t maxisol = 0, maxposs = 0;
|
|
- char *cpulist = NULL, *isolcpus = NULL, *posscpus = NULL;
|
|
- uint32_t *isolmask = NULL, *possmask = NULL;
|
|
- bool bret = false, flipped_bit = false;
|
|
- bool need_read_parent = false;
|
|
-
|
|
- fpath = must_make_path(path, "cpuset.cpus", NULL);
|
|
- posscpus = read_file(fpath);
|
|
- if (!posscpus) {
|
|
- SYSERROR("Failed to read file \"%s\"", fpath);
|
|
- goto on_error;
|
|
- }
|
|
-
|
|
- if (strcmp(posscpus, "\n") == 0) {
|
|
- need_read_parent = true;
|
|
- free(fpath);
|
|
- free(posscpus);
|
|
- lastslash = strrchr(path, '/');
|
|
- if (!lastslash) {
|
|
- ERROR("Failed to detect \"/\" in \"%s\"", path);
|
|
- return bret;
|
|
- }
|
|
- oldv = *lastslash;
|
|
- *lastslash = '\0';
|
|
- fpath = must_make_path(path, "cpuset.cpus", NULL);
|
|
- posscpus = read_file(fpath);
|
|
- if (!posscpus) {
|
|
- SYSERROR("Failed to read file \"%s\"", fpath);
|
|
- goto on_error;
|
|
- }
|
|
- }
|
|
-
|
|
- /* Get maximum number of cpus found in possible cpuset. */
|
|
- maxposs = get_max_cpus(posscpus);
|
|
- if (maxposs < 0 || maxposs >= INT_MAX - 1)
|
|
- goto on_error;
|
|
-
|
|
- if (!file_exists(__ISOL_CPUS)) {
|
|
- /* This system doesn't expose isolated cpus. */
|
|
- DEBUG("The path \""__ISOL_CPUS"\" to read isolated cpus from does not exist");
|
|
- cpulist = posscpus;
|
|
- /* No isolated cpus but we weren't already initialized by
|
|
- * someone. We should simply copy the parents cpuset.cpus
|
|
- * values.
|
|
- */
|
|
- if (!am_initialized) {
|
|
- DEBUG("Copying cpu settings of parent cgroup");
|
|
- goto copy_parent;
|
|
- }
|
|
- /* No isolated cpus but we were already initialized by someone.
|
|
- * Nothing more to do for us.
|
|
- */
|
|
- goto on_success;
|
|
- }
|
|
-
|
|
- isolcpus = read_file(__ISOL_CPUS);
|
|
- if (!isolcpus) {
|
|
- SYSERROR("Failed to read file \""__ISOL_CPUS"\"");
|
|
- goto on_error;
|
|
- }
|
|
- if (!isdigit(isolcpus[0])) {
|
|
- TRACE("No isolated cpus detected");
|
|
- cpulist = posscpus;
|
|
- /* No isolated cpus but we weren't already initialized by
|
|
- * someone. We should simply copy the parents cpuset.cpus
|
|
- * values.
|
|
- */
|
|
- if (!am_initialized) {
|
|
- DEBUG("Copying cpu settings of parent cgroup");
|
|
- goto copy_parent;
|
|
- }
|
|
- /* No isolated cpus but we were already initialized by someone.
|
|
- * Nothing more to do for us.
|
|
- */
|
|
- goto on_success;
|
|
- }
|
|
-
|
|
- /* Get maximum number of cpus found in isolated cpuset. */
|
|
- maxisol = get_max_cpus(isolcpus);
|
|
- if (maxisol < 0 || maxisol >= INT_MAX - 1)
|
|
- goto on_error;
|
|
-
|
|
- if (maxposs < maxisol)
|
|
- maxposs = maxisol;
|
|
- maxposs++;
|
|
-
|
|
- possmask = lxc_cpumask(posscpus, maxposs);
|
|
- if (!possmask) {
|
|
- ERROR("Failed to create cpumask for possible cpus");
|
|
- goto on_error;
|
|
- }
|
|
-
|
|
- isolmask = lxc_cpumask(isolcpus, maxposs);
|
|
- if (!isolmask) {
|
|
- ERROR("Failed to create cpumask for isolated cpus");
|
|
- goto on_error;
|
|
- }
|
|
-
|
|
- for (i = 0; i <= maxposs; i++) {
|
|
- if (!is_set(i, isolmask) || !is_set(i, possmask))
|
|
- continue;
|
|
-
|
|
- flipped_bit = true;
|
|
- clear_bit(i, possmask);
|
|
- }
|
|
-
|
|
- if (!flipped_bit) {
|
|
- DEBUG("No isolated cpus present in cpuset");
|
|
- goto on_success;
|
|
- }
|
|
- DEBUG("Removed isolated cpus from cpuset");
|
|
-
|
|
- cpulist = lxc_cpumask_to_cpulist(possmask, maxposs);
|
|
- if (!cpulist) {
|
|
- ERROR("Failed to create cpu list");
|
|
- goto on_error;
|
|
- }
|
|
-
|
|
-copy_parent:
|
|
- if (need_read_parent) {
|
|
- *lastslash = oldv;
|
|
- }
|
|
- free(fpath);
|
|
- fpath = must_make_path(path, "cpuset.cpus", NULL);
|
|
- ret = lxc_write_to_file(fpath, cpulist, strlen(cpulist), false, 0666);
|
|
- if (ret < 0) {
|
|
- SYSERROR("Failed to write cpu list to \"%s\"", fpath);
|
|
- goto on_error;
|
|
- }
|
|
-
|
|
-on_success:
|
|
- bret = true;
|
|
-
|
|
-on_error:
|
|
- free(fpath);
|
|
-
|
|
- free(isolcpus);
|
|
- free(isolmask);
|
|
-
|
|
- if (posscpus != cpulist)
|
|
- free(posscpus);
|
|
- free(possmask);
|
|
-
|
|
- free(cpulist);
|
|
- return bret;
|
|
-}
|
|
-
|
|
/* Copy contents of parent(@path)/@file to @path/@file */
|
|
static bool copy_parent_file(char *path, char *file)
|
|
{
|
|
@@ -603,9 +321,9 @@ static bool build_sub_cpuset_cgroup_dir(char *cgpath)
|
|
}
|
|
}
|
|
|
|
- /* Make sure any isolated cpus are removed from cpuset.cpus. */
|
|
- if (!cg_legacy_filter_and_set_cpus(cgpath, false)) {
|
|
- SYSERROR("Failed to remove isolated cpus");
|
|
+ /* copy parent's settings */
|
|
+ if (!copy_parent_file(cgpath, "cpuset.cpus")) {
|
|
+ SYSERROR("Failed to copy \"cpuset.cpus\" settings");
|
|
return false;
|
|
}
|
|
|
|
--
|
|
1.8.3.1
|
|
|