]> git.proxmox.com Git - mirror_lxc.git/blobdiff - src/lxc/cgroups/cgfsng.c
cgroups: use __do_free in cgfsng_attach()
[mirror_lxc.git] / src / lxc / cgroups / cgfsng.c
index 8c3600bb903045f8cb970f145b69c84e2e29d7ea..b0f90f222971b4ed945ee282761b3174f33e43f6 100644 (file)
@@ -320,6 +320,7 @@ static char *lxc_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits)
 {
        int ret;
        size_t i;
+       char *tmp = NULL;
        char **cpulist = NULL;
        char numstr[INTTYPE_TO_STRLEN(size_t)] = {0};
 
@@ -343,7 +344,10 @@ static char *lxc_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits)
        if (!cpulist)
                return NULL;
 
-       return lxc_string_join(",", (const char **)cpulist, false);
+       tmp = lxc_string_join(",", (const char **)cpulist, false);
+       lxc_free_array((void **)cpulist, free);
+
+       return tmp;
 }
 
 static ssize_t get_max_cpus(char *cpulist)
@@ -378,16 +382,18 @@ static ssize_t get_max_cpus(char *cpulist)
 }
 
 #define __ISOL_CPUS "/sys/devices/system/cpu/isolated"
+#define __OFFLINE_CPUS "/sys/devices/system/cpu/offline"
 static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized)
 {
        __do_free char *cpulist = NULL, *fpath = NULL, *isolcpus = NULL,
-                      *posscpus = NULL;
-       __do_free uint32_t *isolmask = NULL, *possmask = NULL;
+                      *offlinecpus = NULL, *posscpus = NULL;
+       __do_free uint32_t *isolmask = NULL, *offlinemask = NULL,
+                          *possmask = NULL;
        int ret;
        ssize_t i;
        char oldv;
        char *lastslash;
-       ssize_t maxisol = 0, maxposs = 0;
+       ssize_t maxisol = 0, maxoffline = 0, maxposs = 0;
        bool bret = false, flipped_bit = false;
 
        lastslash = strrchr(path, '/');
@@ -398,6 +404,7 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized)
        oldv = *lastslash;
        *lastslash = '\0';
        fpath = must_make_path(path, "cpuset.cpus", NULL);
+       *lastslash = oldv;
        posscpus = read_file(fpath);
        if (!posscpus) {
                SYSERROR("Failed to read file \"%s\"", fpath);
@@ -409,54 +416,52 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized)
        if (maxposs < 0 || maxposs >= INT_MAX - 1)
                return false;
 
-       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");
-               /* 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");
-                       cpulist = posscpus;
-                       goto copy_parent;
+       if (file_exists(__ISOL_CPUS)) {
+               isolcpus = read_file(__ISOL_CPUS);
+               if (!isolcpus) {
+                       SYSERROR("Failed to read file \"%s\"", __ISOL_CPUS);
+                       return false;
                }
-               /* No isolated cpus but we were already initialized by someone.
-                * Nothing more to do for us.
-                */
-               return true;
-       }
 
-       isolcpus = read_file(__ISOL_CPUS);
-       if (!isolcpus) {
-               SYSERROR("Failed to read file \""__ISOL_CPUS"\"");
-               return false;
-       }
-       if (!isdigit(isolcpus[0])) {
-               TRACE("No isolated cpus detected");
-               /* 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");
-                       cpulist = posscpus;
-                       goto copy_parent;
+               if (isdigit(isolcpus[0])) {
+                       /* Get maximum number of cpus found in isolated cpuset. */
+                       maxisol = get_max_cpus(isolcpus);
+                       if (maxisol < 0 || maxisol >= INT_MAX - 1)
+                               return false;
                }
-               /* No isolated cpus but we were already initialized by someone.
-                * Nothing more to do for us.
-                */
-               return true;
+
+               if (maxposs < maxisol)
+                       maxposs = maxisol;
+               maxposs++;
+       } else {
+               TRACE("The path \""__ISOL_CPUS"\" to read isolated cpus from does not exist");
        }
 
-       /* Get maximum number of cpus found in isolated cpuset. */
-       maxisol = get_max_cpus(isolcpus);
-       if (maxisol < 0 || maxisol >= INT_MAX - 1)
-               return false;
+       if (file_exists(__OFFLINE_CPUS)) {
+               offlinecpus = read_file(__OFFLINE_CPUS);
+               if (!offlinecpus) {
+                       SYSERROR("Failed to read file \"%s\"", __OFFLINE_CPUS);
+                       return false;
+               }
+
+               if (isdigit(offlinecpus[0])) {
+                       /* Get maximum number of cpus found in offline cpuset. */
+                       maxoffline = get_max_cpus(offlinecpus);
+                       if (maxoffline < 0 || maxoffline >= INT_MAX - 1)
+                               return false;
+               }
+
+               if (maxposs < maxoffline)
+                       maxposs = maxoffline;
+               maxposs++;
+       } else {
+               TRACE("The path \""__OFFLINE_CPUS"\" to read offline cpus from does not exist");
+       }
 
-       if (maxposs < maxisol)
-               maxposs = maxisol;
-       maxposs++;
+       if ((maxisol == 0) && (maxoffline == 0)) {
+               cpulist = move_ptr(posscpus);
+               goto copy_parent;
+       }
 
        possmask = lxc_cpumask(posscpus, maxposs);
        if (!possmask) {
@@ -464,14 +469,26 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized)
                return false;
        }
 
-       isolmask = lxc_cpumask(isolcpus, maxposs);
-       if (!isolmask) {
-               ERROR("Failed to create cpumask for isolated cpus");
-               return false;
+       if (maxisol > 0) {
+               isolmask = lxc_cpumask(isolcpus, maxposs);
+               if (!isolmask) {
+                       ERROR("Failed to create cpumask for isolated cpus");
+                       return false;
+               }
+       }
+
+       if (maxoffline > 0) {
+               offlinemask = lxc_cpumask(offlinecpus, maxposs);
+               if (!offlinemask) {
+                       ERROR("Failed to create cpumask for offline cpus");
+                       return false;
+               }
        }
 
        for (i = 0; i <= maxposs; i++) {
-               if (!is_set(i, isolmask) || !is_set(i, possmask))
+               if ((isolmask && !is_set(i, isolmask)) ||
+                   (offlinemask && !is_set(i, offlinemask)) ||
+                   !is_set(i, possmask))
                        continue;
 
                flipped_bit = true;
@@ -479,10 +496,10 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized)
        }
 
        if (!flipped_bit) {
-               DEBUG("No isolated cpus present in cpuset");
+               DEBUG("No isolated or offline cpus present in cpuset");
                return true;
        }
-       DEBUG("Removed isolated cpus from cpuset");
+       DEBUG("Removed isolated or offline cpus from cpuset");
 
        cpulist = lxc_cpumask_to_cpulist(possmask, maxposs);
        if (!cpulist) {
@@ -491,14 +508,16 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized)
        }
 
 copy_parent:
-       *lastslash = oldv;
-       fpath = must_make_path(path, "cpuset.cpus", NULL);
-       ret = lxc_write_to_file(fpath, cpulist, strlen(cpulist), false, 0666);
-       if (cpulist == posscpus)
-               cpulist = NULL;
-       if (ret < 0) {
-               SYSERROR("Failed to write cpu list to \"%s\"", fpath);
-               return false;
+       if (!am_initialized) {
+               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);
+                       return false;
+               }
+
+               TRACE("Copied cpu settings of parent cgroup");
        }
 
        return true;
@@ -2078,8 +2097,7 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name,
                return false;
 
        for (i = 0; ops->hierarchies[i]; i++) {
-               __do_free char *path = NULL;
-               char *fullpath = NULL;
+               __do_free char *fullpath = NULL, *path = NULL;
                struct hierarchy *h = ops->hierarchies[i];
 
                if (h->version == CGROUP2_SUPER_MAGIC) {
@@ -2377,13 +2395,10 @@ static bool __cg_unified_setup_limits(struct cgroup_ops *ops,
 }
 
 __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops,
-                                              struct lxc_conf *conf,
-                                              bool do_devices)
+                                            struct lxc_conf *conf,
+                                            bool do_devices)
 {
-       bool bret;
-
-       bret = __cg_legacy_setup_limits(ops, &conf->cgroup, do_devices);
-       if (!bret)
+       if (!__cg_legacy_setup_limits(ops, &conf->cgroup, do_devices))
                return false;
 
        return __cg_unified_setup_limits(ops, &conf->cgroup2);
@@ -2392,15 +2407,13 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops,
 static bool cgroup_use_wants_controllers(const struct cgroup_ops *ops,
                                       char **controllers)
 {
-       char **cur_ctrl, **cur_use;
-
        if (!ops->cgroup_use)
                return true;
 
-       for (cur_ctrl = controllers; cur_ctrl && *cur_ctrl; cur_ctrl++) {
+       for (char **cur_ctrl = controllers; cur_ctrl && *cur_ctrl; cur_ctrl++) {
                bool found = false;
 
-               for (cur_use = ops->cgroup_use; cur_use && *cur_use; cur_use++) {
+               for (char **cur_use = ops->cgroup_use; cur_use && *cur_use; cur_use++) {
                        if (strcmp(*cur_use, *cur_ctrl) != 0)
                                continue;
 
@@ -2735,7 +2748,7 @@ __cgfsng_ops static bool cgfsng_data_init(struct cgroup_ops *ops)
 
 struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
 {
-       struct cgroup_ops *cgfsng_ops;
+       __do_free struct cgroup_ops *cgfsng_ops = NULL;
 
        cgfsng_ops = malloc(sizeof(struct cgroup_ops));
        if (!cgfsng_ops)
@@ -2744,10 +2757,8 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
        memset(cgfsng_ops, 0, sizeof(struct cgroup_ops));
        cgfsng_ops->cgroup_layout = CGROUP_LAYOUT_UNKNOWN;
 
-       if (!cg_init(cgfsng_ops, conf)) {
-               free(cgfsng_ops);
+       if (!cg_init(cgfsng_ops, conf))
                return NULL;
-       }
 
        cgfsng_ops->data_init = cgfsng_data_init;
        cgfsng_ops->payload_destroy = cgfsng_payload_destroy;
@@ -2771,5 +2782,5 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
        cgfsng_ops->mount = cgfsng_mount;
        cgfsng_ops->nrtasks = cgfsng_nrtasks;
 
-       return cgfsng_ops;
+       return move_ptr(cgfsng_ops);
 }