diff --git a/SOURCES/libcgroup-0.41-api.c-tasks-file-warning.patch b/SOURCES/libcgroup-0.41-api.c-tasks-file-warning.patch
new file mode 100644
index 0000000..20e81c9
--- /dev/null
+++ b/SOURCES/libcgroup-0.41-api.c-tasks-file-warning.patch
@@ -0,0 +1,33 @@
+diff --git a/src/api.c b/src/api.c
+index a98e829..d19abdd 100644
+--- a/src/api.c
++++ b/src/api.c
+@@ -1190,12 +1190,15 @@ static int __cgroup_attach_task_pid(char *path, pid_t tid)
+ 	if (!tasks) {
+ 		switch (errno) {
+ 		case EPERM:
+-			return ECGROUPNOTOWNER;
++			ret = ECGROUPNOTOWNER;
++			break;
+ 		case ENOENT:
+-			return ECGROUPNOTEXIST;
++			ret = ECGROUPNOTEXIST;
++			break;
+ 		default:
+-			return ECGROUPNOTALLOWED;
++			ret = ECGROUPNOTALLOWED;
+ 		}
++		goto err;
+ 	}
+ 	ret = fprintf(tasks, "%d", tid);
+ 	if (ret < 0) {
+@@ -1214,7 +1217,8 @@ static int __cgroup_attach_task_pid(char *path, pid_t tid)
+ err:
+ 	cgroup_warn("Warning: cannot write tid %d to %s:%s\n",
+ 			tid, path, strerror(errno));
+-	fclose(tasks);
++	if (tasks)
++		fclose(tasks);
+ 	return ret;
+ }
+ 
diff --git a/SOURCES/libcgroup-0.41-cgrules.conf.5-extend-controllers-description.patch b/SOURCES/libcgroup-0.41-cgrules.conf.5-extend-controllers-description.patch
new file mode 100644
index 0000000..42ac9c4
--- /dev/null
+++ b/SOURCES/libcgroup-0.41-cgrules.conf.5-extend-controllers-description.patch
@@ -0,0 +1,15 @@
+diff --git a/doc/man/cgrules.conf.5 b/doc/man/cgrules.conf.5
+index 7a89fb5..dd222a9 100644
+--- a/doc/man/cgrules.conf.5
++++ b/doc/man/cgrules.conf.5
+@@ -50,6 +50,10 @@ can be:
+ .nf
+     - comma separated controller names (no spaces) or 
+     - * (for all mounted controllers)
++
++    make sure to define only controllers that are configured
++    for the matching \fIdestination\fR in \fBcgconfig.conf\fR,
++    otherwise the rule can fail
+ .fi
+ 
+ .I destination
diff --git a/SOURCES/libcgroup-0.41-change-cgroup-of-every-thread.patch b/SOURCES/libcgroup-0.41-change-cgroup-of-every-thread.patch
new file mode 100644
index 0000000..05f009a
--- /dev/null
+++ b/SOURCES/libcgroup-0.41-change-cgroup-of-every-thread.patch
@@ -0,0 +1,74 @@
+From c9d651cfd532da6494dab03190c0a207cdf7289c 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] api.c: always move all tasks of a process to a cgroup
+
+---
+ src/api.c | 40 ++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 38 insertions(+), 2 deletions(-)
+
+diff --git a/src/api.c b/src/api.c
+index 803ff35..a2cf981 100644
+--- a/src/api.c
++++ b/src/api.c
+@@ -3180,7 +3180,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");
+@@ -3191,11 +3196,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;
+ }
+-- 
+2.17.1
+
diff --git a/SOURCES/libcgroup-0.41-increase-size-of-controller-values.patch b/SOURCES/libcgroup-0.41-increase-size-of-controller-values.patch
new file mode 100644
index 0000000..dfb075a
--- /dev/null
+++ b/SOURCES/libcgroup-0.41-increase-size-of-controller-values.patch
@@ -0,0 +1,113 @@
+diff --git a/src/api.c b/src/api.c
+index aa912b6..a98e829 100644
+--- a/src/api.c
++++ b/src/api.c
+@@ -1592,7 +1592,7 @@ static int cgroup_copy_controller_values(struct cgroup_controller *dst,
+ 		}
+ 
+ 		dst_val = dst->values[i];
+-		strncpy(dst_val->value, src_val->value, CG_VALUE_MAX);
++		strncpy(dst_val->value, src_val->value, CG_CONTROL_VALUE_MAX);
+ 		strncpy(dst_val->name, src_val->name, FILENAME_MAX);
+ 		dst_val->dirty = src_val->dirty;
+ 	}
+@@ -2317,7 +2317,7 @@ static int cg_rd_ctrl_file(const char *subsys, const char *cgroup,
+ 	if (ctrl_file < 0)
+ 		return ECGROUPVALUENOTEXIST;
+ 
+-	*value = calloc(CG_VALUE_MAX, 1);
++	*value = calloc(CG_CONTROL_VALUE_MAX, 1);
+ 	if (!*value) {
+ 		close(ctrl_file);
+ 		last_errno = errno;
+@@ -2328,7 +2328,7 @@ static int cg_rd_ctrl_file(const char *subsys, const char *cgroup,
+ 	 * using %as or fread crashes when we try to read from files like
+ 	 * memory.stat
+ 	 */
+-	ret = read(ctrl_file, *value, CG_VALUE_MAX-1);
++	ret = read(ctrl_file, *value, CG_CONTROL_VALUE_MAX-1);
+ 	if (ret < 0) {
+ 		free(*value);
+ 		*value = NULL;
+diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
+index c128788..7a761a5 100644
+--- a/src/libcgroup-internal.h
++++ b/src/libcgroup-internal.h
+@@ -32,6 +32,9 @@ __BEGIN_DECLS
+ /* Estimated number of groups created */
+ #define MAX_GROUP_ELEMENTS	128
+ 
++/* Maximum length of a value */
++#define CG_CONTROL_VALUE_MAX 4096
++
+ #define CG_NV_MAX 100
+ #define CG_CONTROLLER_MAX 100
+ /* Max number of mounted hierarchies. Event if one controller is mounted per
+@@ -76,7 +79,7 @@ __BEGIN_DECLS
+ 
+ struct control_value {
+ 	char name[FILENAME_MAX];
+-	char value[CG_VALUE_MAX];
++	char value[CG_CONTROL_VALUE_MAX];
+ 	bool dirty;
+ };
+ 
+diff --git a/src/tools/cgset.c b/src/tools/cgset.c
+index ea9f90d..3d3c8cc 100644
+--- a/src/tools/cgset.c
++++ b/src/tools/cgset.c
+@@ -151,8 +151,8 @@ int main(int argc, char *argv[])
+ 				goto err;
+ 			}
+ 
+-			strncpy(name_value[nv_number].value, buf, CG_VALUE_MAX);
+-			name_value[nv_number].value[CG_VALUE_MAX-1] = '\0';
++			strncpy(name_value[nv_number].value, buf, CG_CONTROL_VALUE_MAX);
++			name_value[nv_number].value[CG_CONTROL_VALUE_MAX-1] = '\0';
+ 
+ 			nv_number++;
+ 			break;
+diff --git a/src/wrapper.c b/src/wrapper.c
+index 3a9331f..0fe80d0 100644
+--- a/src/wrapper.c
++++ b/src/wrapper.c
+@@ -182,10 +182,10 @@ int cgroup_add_value_string(struct cgroup_controller *controller,
+ 	if (!controller)
+ 		return ECGINVAL;
+ 
+-	if (controller->index >= CG_VALUE_MAX)
++	if (controller->index >= CG_NV_MAX)
+ 		return ECGMAXVALUESEXCEEDED;
+ 
+-	for (i = 0; i < controller->index && i < CG_VALUE_MAX; i++) {
++	for (i = 0; i < controller->index && i < CG_NV_MAX; i++) {
+ 		if (!strcmp(controller->values[i]->name, name))
+ 			return ECGVALUEEXISTS;
+ 	}
+@@ -195,8 +195,15 @@ int cgroup_add_value_string(struct cgroup_controller *controller,
+ 	if (!cntl_value)
+ 		return ECGCONTROLLERCREATEFAILED;
+ 
+-	strncpy(cntl_value->name, name, sizeof(cntl_value->name));
+-	strncpy(cntl_value->value, value, sizeof(cntl_value->value));
++	if (strlen(value) >= sizeof(cntl_value->value)) {
++		fprintf(stderr, "value exceeds the maximum of %lu characters\n",
++			sizeof(cntl_value->value));
++		free(cntl_value);
++		return ECGCONFIGPARSEFAIL;
++	}
++
++	strncpy(cntl_value->name, name, sizeof(cntl_value->name) - 1);
++	strncpy(cntl_value->value, value, sizeof(cntl_value->value) - 1);
+ 	cntl_value->dirty = true;
+ 	controller->values[controller->index] = cntl_value;
+ 	controller->index++;
+@@ -406,7 +413,7 @@ int cgroup_set_value_string(struct cgroup_controller *controller,
+ 	for (i = 0; i < controller->index; i++) {
+ 		struct control_value *val = controller->values[i];
+ 		if (!strcmp(val->name, name)) {
+-			strncpy(val->value, value, CG_VALUE_MAX);
++			strncpy(val->value, value, CG_CONTROL_VALUE_MAX - 1);
+ 			val->dirty = true;
+ 			return 0;
+ 		}
diff --git a/SPECS/libcgroup.spec b/SPECS/libcgroup.spec
index 2ddc63d..06411e8 100644
--- a/SPECS/libcgroup.spec
+++ b/SPECS/libcgroup.spec
@@ -5,7 +5,7 @@
 Summary: Library to control and monitor control groups
 Name: libcgroup
 Version: 0.41
-Release: 15%{?dist}
+Release: 20%{?dist}
 License: LGPLv2+
 Group: Development/Libraries
 URL: http://libcg.sourceforge.net/
@@ -38,6 +38,13 @@ Patch15: libcgroup-0.41-api.c-fix-log-level.patch
 Patch16: libcgroup-0.41-api.c-preserve-dirty-flag.patch
 # resolves #1505443
 Patch17: libcgroup-0.41-infinite-loop.patch
+# resolves #1549175
+Patch18: libcgroup-0.41-increase-size-of-controller-values.patch
+# resolves #1561736
+Patch19: libcgroup-0.41-api.c-tasks-file-warning.patch
+Patch20: libcgroup-0.41-cgrules.conf.5-extend-controllers-description.patch
+# resolves #1568354
+Patch21: libcgroup-0.41-change-cgroup-of-every-thread.patch
 
 BuildRequires: byacc, coreutils, flex, pam-devel, systemd
 Requires(pre): shadow-utils
@@ -99,6 +106,10 @@ provide scripts to manage that configuration.
 %patch15 -p1
 %patch16 -p1
 %patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
 
 %build
 %configure --enable-pam-module-dir=%{_libdir}/security \
@@ -219,6 +230,27 @@ fi
 %{_libdir}/pkgconfig/libcgroup.pc
 
 %changelog
+* Wed Sep 05 2018 Nikola Forró <nforro@redhat.com> - 0.41-20
+- always move all tasks of a process to a cgroup
+  related: #1568354
+
+* Fri May 25 2018 Nikola Forró <nforro@redhat.com> - 0.41-19
+- change cgroup of every thread of a process
+  resolves: #1568354
+
+* Wed Apr 25 2018 Nikola Forró <nforro@redhat.com> - 0.41-18
+- fix wrong format in fprintf call that causes compiler warning
+  related: #1549175
+
+* Wed Apr 25 2018 Nikola Forró <nforro@redhat.com> - 0.41-17
+- show warning when "tasks" file can not be opened
+- extend description of "controllers" section in cgrules.conf man page
+  resolves: #1561736
+
+* Tue Apr 17 2018 Nikola Forró <nforro@redhat.com> - 0.41-16
+- increase maximal size of controller values
+  resolves: #1549175
+
 * Tue Oct 24 2017 Nikola Forró <nforro@redhat.com> - 0.41-15
 - resolves: #1464015
   do not verify size, mtime and checksum of config files