File 0002-api.c-always-move-all-tasks-of-a-process-to-a-cgroup.patch of Package libcgroup

From e24c0d1ac918250bff831c1410b4b0b23adff810 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
Date: Mon, 23 Jul 2018 17:38:26 +0200
Subject: [PATCH 2/2] api.c: always move all tasks of a process to a cgroup
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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 | 66 +++++++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 43 insertions(+), 23 deletions(-)

diff --git a/src/api.c b/src/api.c
index 27c9540..92a9131 100644
--- a/src/api.c
+++ b/src/api.c
@@ -3068,7 +3068,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");
@@ -3079,11 +3084,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;
 }
@@ -3108,13 +3144,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)
@@ -3128,24 +3161,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);
 	}
 
-- 
2.16.4

openSUSE Build Service is sponsored by