]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
api.c: always move all tasks of a process to a cgroup
authorNikola Forró <nforro@redhat.com>
Mon, 23 Jul 2018 15:38:26 +0000 (17:38 +0200)
committerNikola Forró <nforro@redhat.com>
Fri, 23 Nov 2018 15:15:18 +0000 (16:15 +0100)
Move the thread enumeration introduced in commit 2186c97
from cgroup_change_all_cgroups() to cgroup_change_cgroup_path()
to ensure it works in every case.

Signed-off-by: Nikola Forró <nforro@redhat.com>
src/api.c

index 0bf0615fec978e51bbb84ab9357d9f2fad3f48fd..d705d6955da45544e4ac0596b0736e777e9500bf 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -3253,7 +3253,12 @@ int cgroup_change_cgroup_path(const char *dest, pid_t pid,
                                const char *const controllers[])
 {
        int ret;
+       int nr;
        struct cgroup cgroup;
+       DIR *dir;
+       struct dirent *task_dir = NULL;
+       char path[FILENAME_MAX];
+       pid_t tid;
 
        if (!cgroup_initialized) {
                cgroup_warn("Warning: libcgroup is not initialized\n");
@@ -3264,11 +3269,42 @@ int cgroup_change_cgroup_path(const char *dest, pid_t pid,
        ret = cg_prepare_cgroup(&cgroup, pid, dest, controllers);
        if (ret)
                return ret;
-       /* Add task to cgroup */
+       /* Add process to cgroup */
        ret = cgroup_attach_task_pid(&cgroup, pid);
-       if (ret)
+       if (ret) {
                cgroup_warn("Warning: cgroup_attach_task_pid failed: %d\n",
                                ret);
+               goto finished;
+       }
+
+       /* Add all threads to cgroup */
+       snprintf(path, FILENAME_MAX, "/proc/%d/task/", pid);
+       dir = opendir(path);
+       if (!dir) {
+               last_errno = errno;
+               ret = ECGOTHER;
+               goto finished;
+       }
+
+       while ((task_dir = readdir(dir)) != NULL) {
+               nr = sscanf(task_dir->d_name, "%i", &tid);
+               if (nr < 1)
+                       continue;
+
+               if (tid == pid)
+                       continue;
+
+               ret = cgroup_attach_task_pid(&cgroup, tid);
+               if (ret) {
+                       cgroup_warn("Warning: cgroup_attach_task_pid failed: %d\n",
+                                       ret);
+                       break;
+               }
+       }
+
+       closedir(dir);
+
+finished:
        cgroup_free_controllers(&cgroup);
        return ret;
 }
@@ -3293,13 +3329,10 @@ int cgroup_change_all_cgroups(void)
                return -ECGOTHER;
 
        while ((pid_dir = readdir(dir)) != NULL) {
-               int err, pid, tid;
+               int err, pid;
                uid_t euid;
                gid_t egid;
                char *procname = NULL;
-               DIR *tdir;
-               struct dirent *tid_dir = NULL;
-               char tpath[FILENAME_MAX] = { '\0' };
 
                err = sscanf(pid_dir->d_name, "%i", &pid);
                if (err < 1)
@@ -3313,24 +3346,11 @@ int cgroup_change_all_cgroups(void)
                if (err)
                        continue;
 
-               snprintf(tpath, FILENAME_MAX, "%s%d/task/", path, pid);
-
-               tdir = opendir(tpath);
-               if (!tdir)
-                       continue;
-
-               while ((tid_dir = readdir(tdir)) != NULL) {
-                       err = sscanf(tid_dir->d_name, "%i", &tid);
-                       if (err < 1)
-                               continue;
-
-                       err = cgroup_change_cgroup_flags(euid,
-                                       egid, procname, tid, CGFLAG_USECACHE);
-                       if (err)
-                               cgroup_dbg("cgroup change tid %i failed\n", tid);
-               }
+               err = cgroup_change_cgroup_flags(euid,
+                               egid, procname, pid, CGFLAG_USECACHE);
+               if (err)
+                       cgroup_dbg("cgroup change pid %i failed\n", pid);
 
-               closedir(tdir);
                free(procname);
        }