From cd8720b901bc6b3bbdd521396e23165d6c425023 Mon Sep 17 00:00:00 2001
From: Douglas Raillard <douglas.raillard@arm.com>
Date: Mon, 16 May 2022 12:40:04 +0100
Subject: [PATCH] module/cgroups: Fix move_tasks()/move_all_tasks_to()

Both move_all_tasks_to() and move_tasks() take a list of grep patterns
to exclude.

It turned out that move_all_tasks_to() was calling move_tasks() with a
string instead of a list, leading to broken quoting.

Fix that by passing the pattern list to move_tasks() and let
move_tasks() add the "-e" option in front of it. Also add a
DeprecationWarning in move_tasks() if someone passes a string instead of
an iterable of strings.
---
 devlib/module/cgroups.py | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/devlib/module/cgroups.py b/devlib/module/cgroups.py
index e521fd5..6cbab19 100644
--- a/devlib/module/cgroups.py
+++ b/devlib/module/cgroups.py
@@ -17,6 +17,8 @@ import logging
 import re
 from collections import namedtuple
 from shlex import quote
+import itertools
+import warnings
 
 from devlib.module import Module
 from devlib.exception import TargetStableError
@@ -123,9 +125,20 @@ class Controller(object):
         return cgroups
 
     def move_tasks(self, source, dest, exclude=None):
+        if isinstance(exclude, str):
+            warnings.warn("Controller.move_tasks() takes needs a _list_ of exclude patterns, not a string", DeprecationWarning)
+            exclude = [exclude]
+
         if exclude is None:
             exclude = []
 
+        exclude = ' '.join(
+            itertools.chain.from_iterable(
+                ('-e', quote(pattern))
+                for pattern in exclude
+            )
+        )
+
         srcg = self.cgroup(source)
         dstg = self.cgroup(dest)
 
@@ -133,7 +146,7 @@ class Controller(object):
             'cgroups_tasks_move {src} {dst} {exclude}'.format(
                 src=quote(srcg.directory),
                 dst=quote(dstg.directory),
-                exclude=' '.join(map(quote, exclude))
+                exclude=exclude,
             ),
             as_root=True,
         )
@@ -165,18 +178,11 @@ class Controller(object):
         self.logger.debug('Moving all tasks into %s', dest)
 
         # Build list of tasks to exclude
-        grep_filters = ' '.join(
-            '-e {}'.format(comm)
-            for comm in exclude
-        )
-        self.logger.debug('   using grep filter: %s', grep_filters)
-        if grep_filters != '':
-            self.logger.debug('   excluding tasks which name matches:')
-            self.logger.debug('   %s', ', '.join(exclude))
+        self.logger.debug('   using grep filter: %s', exclude)
 
         for cgroup in self.list_all():
             if cgroup != dest:
-                self.move_tasks(cgroup, dest, grep_filters)
+                self.move_tasks(cgroup, dest, exclude)
 
     # pylint: disable=too-many-locals
     def tasks(self, cgroup,