Add cgrulesengd support to the Cgroup class.  Add methods
to insert a rule, initialize the daemon, and start the
daemon in a separate process.

Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com>
---
 ftests/cgroup.py | 102 +++++++++++++++++++++++++++++++++++++++++++++++
 ftests/consts.py |   4 +-
 2 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/ftests/cgroup.py b/ftests/cgroup.py
index a9edb9958a43..85b160742e3a 100644
--- a/ftests/cgroup.py
+++ b/ftests/cgroup.py
@@ -22,8 +22,10 @@
 import consts
 from controller import Controller
 from enum import Enum
+import multiprocessing as mp
 import os
 from run import Run
+import time
 import utils
 
 class CgroupVersion(Enum):
@@ -59,6 +61,8 @@ class Cgroup(object):
         # struct cgroup_controller *controller[CG_CONTROLLER_MAX];
         self.controllers = dict()
 
+        self.children = list()
+
     def __str__(self):
         out_str = "Cgroup {}\n".format(self.name)
         for ctrl_key in self.controllers:
@@ -83,6 +87,11 @@ class Cgroup(object):
         return os.path.join(consts.LIBCG_MOUNT_POINT,
                             'src/tools/{}'.format(cmd))
 
+    @staticmethod
+    def build_daemon_path(cmd):
+        return os.path.join(consts.LIBCG_MOUNT_POINT,
+                            'src/daemon/{}'.format(cmd))
+
     # TODO - add support for all of the cgcreate options
     @staticmethod
     def create(config, controller_list, cgname):
@@ -367,3 +376,96 @@ class Cgroup(object):
 
         # convert the cgsnapshot stdout to a dict of cgroup objects
         return Cgroup.snapshot_to_dict(res)
+
+    @staticmethod
+    def set_cgrules_conf(config, line, append=True):
+        cmd = list()
+
+        cmd.append('sudo')
+        cmd.append('su')
+        cmd.append('-c')
+
+        if append:
+            redirect_str = '>>'
+        else:
+            redirect_str = '>'
+
+        subcmd = '"echo {} {} {}"'.format(line, redirect_str,
+                                          consts.CGRULES_FILE)
+        cmd.append(subcmd)
+
+        if config.args.container:
+            config.container.run(cmd, shell_bool=True)
+        else:
+            Run.run(cmd, shell_bool=True)
+
+    @staticmethod
+    def init_cgrules(config):
+        cmd = list()
+
+        cmd.append('sudo')
+        cmd.append('mkdir')
+        cmd.append('/etc/cgconfig.d')
+
+        try:
+            if config.args.container:
+                config.container.run(cmd, shell_bool=True)
+            else:
+                Run.run(cmd, shell_bool=True)
+        except:
+            # todo - check the errno to ensure the directory exists rather
+            # than receiving a different error
+            pass
+
+        cmd2 = list()
+
+        cmd2.append('sudo')
+        cmd2.append('touch')
+        cmd2.append('/etc/cgconfig.conf')
+
+        if config.args.container:
+            config.container.run(cmd2, shell_bool=True)
+        else:
+            Run.run(cmd2, shell_bool=True)
+
+    # note that this runs cgrulesengd in this process and does not fork
+    # the daemon
+    @staticmethod
+    def __run_cgrules(config):
+        cmd = list()
+
+        cmd.append('sudo')
+        cmd.append(Cgroup.build_daemon_path('cgrulesengd'))
+        cmd.append('-d')
+        cmd.append('-n')
+
+        if config.args.container:
+            config.container.run(cmd, shell_bool=True)
+        else:
+            Run.run(cmd, shell_bool=True)
+
+    def start_cgrules(self, config):
+        Cgroup.init_cgrules(config)
+
+        p = mp.Process(target=Cgroup.__run_cgrules,
+                       args=(config, ))
+        p.start()
+        time.sleep(2)
+
+        self.children.append(p)
+
+    def join_children(self, config):
+        # todo - make this smarter.  this is ugly, but it works for now
+        cmd = ['sudo', 'killall', 'cgrulesengd']
+        try:
+            if config.args.container:
+                config.container.run(cmd, shell_bool=True)
+            else:
+                Run.run(cmd, shell_bool=True)
+        except:
+            # ignore any errors during the kill command.  this is belt
+            # and suspenders code
+            pass
+
+        for child in self.children:
+            child.join(1)
diff --git a/ftests/consts.py b/ftests/consts.py
index 208f3a003654..8e4b60373bd2 100644
--- a/ftests/consts.py
+++ b/ftests/consts.py
@@ -1,7 +1,7 @@
 #
 # Constants for the libcgroup functional tests
 #
-# Copyright (c) 2019 Oracle and/or its affiliates.  All rights reserved.
+# Copyright (c) 2019-2021 Oracle and/or its affiliates.
 # Author: Tom Hromatka <tom.hroma...@oracle.com>
 #
 
@@ -43,3 +43,5 @@ TESTS_RUN_ALL_SUITES = "allsuites"
 TEST_PASSED = "passed"
 TEST_FAILED = "failed"
 TEST_SKIPPED = "skipped"
+
+CGRULES_FILE = "/etc/cgrules.conf"
-- 
2.26.2



_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to