]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
cgrules: Add ignore_rt option
authorKamalesh Babulal <kamalesh.babulal@oracle.com>
Tue, 8 Oct 2024 13:25:00 +0000 (13:25 +0000)
committerTom Hromatka <tom.hromatka@oracle.com>
Wed, 9 Oct 2024 20:17:49 +0000 (14:17 -0600)
Introduce new ignore_rt option for cgrules, that would ignore rules
matching user:process, controller(s), destination cgroup with SCHED_RR
and SCHED_FF policies.

Suggested-by: Tom Hromatka <tom.hromatka@oracle.com>
Signed-off-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
src/api.c
src/libcgroup-internal.h

index 39eccdd779be01179f40e90ec8a8393bfbfcf763..8c1809983a68d0cb43fd80a2e76152332793a229 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -536,14 +536,17 @@ STATIC int cgroup_parse_rules_options(char *options, struct cgroup_rule * const
                cmp_len = min(strlen(stok_buff), strlen(CGRULE_OPTION_IGNORE));
                if (strlen(stok_buff) == strlen(CGRULE_OPTION_IGNORE) &&
                    strncmp(stok_buff, CGRULE_OPTION_IGNORE, cmp_len) == 0) {
-                       rule->is_ignore = true;
+                       rule->is_ignore |= CGRULE_OPT_IGNORE;
+                       continue;
+               }
+
+               cmp_len = min(strlen(stok_buff), strlen(CGRULE_OPTION_IGNORE_RT));
+               if (strlen(stok_buff) == strlen(CGRULE_OPTION_IGNORE_RT) &&
+                   strncmp(stok_buff, CGRULE_OPTION_IGNORE_RT, cmp_len) == 0) {
+                       rule->is_ignore |= CGRULE_OPT_IGNORE_RT;
                        continue;
                }
 
-               /*
-                * "ignore" is the only currently supported option.
-                * Raise an error if we get here.
-                */
                cgroup_err("Unsupported option: %s\n", stok_buff);
                ret = -EINVAL;
                break;
@@ -818,7 +821,7 @@ static int cgroup_parse_rules_file(char *filename, bool cache, uid_t muid, gid_t
 
                newrule->uid = uid;
                newrule->gid = gid;
-               newrule->is_ignore = false;
+               newrule->is_ignore = 0;
 
                len_username = min(len_username, sizeof(newrule->username) - 1);
                strncpy(newrule->username, user, len_username);
@@ -4112,6 +4115,29 @@ static int cgroup_find_matching_controller(char * const *rule_controllers,
        return ret;
 }
 
+static bool cgroup_is_rt_task(const pid_t pid)
+{
+       int sched_prio_min, sched_prio_max;
+       struct sched_param pid_param;
+       int ret;
+
+       ret = sched_getparam(pid, &pid_param);
+       if (ret == -1) {
+               ret = ECGOTHER;
+               last_errno = errno;
+               return false;
+       }
+
+       sched_prio_min = sched_get_priority_min(SCHED_RR);
+       sched_prio_max = sched_get_priority_max(SCHED_RR);
+
+       if (pid_param.sched_priority >= sched_prio_min &&
+           pid_param.sched_priority <= sched_prio_max)
+               return true;
+
+       return false;
+}
+
 /**
  * Evaluates if rule is an ignore rule and the pid/procname match this rule.
  * If rule is an ignore rule and the pid/procname match this rule, then this
@@ -4129,7 +4155,7 @@ STATIC bool cgroup_compare_ignore_rule(const struct cgroup_rule * const rule, pi
        char *controller_list[MAX_MNT_ELEMENTS] = { '\0' };
        char *cgroup_list[MAX_MNT_ELEMENTS] = { '\0' };
        int rule_matching_controller_idx;
-       int cgroup_list_matching_idx;
+       int cgroup_list_matching_idx = 0;
        bool found_match = false;
        char *token, *saveptr;
        int ret, i;
@@ -4138,16 +4164,27 @@ STATIC bool cgroup_compare_ignore_rule(const struct cgroup_rule * const rule, pi
                /* Immediately return if the 'ignore' option is not set */
                return false;
 
+       /* If the rule is "ignore", move only non-rt tasks */
+       if (rule->is_ignore == CGRULE_OPT_IGNORE && cgroup_is_rt_task(pid) == true)
+               return false;
+       /* If the rule is "ignore_rt", move only non-rt tasks */
+       else if (rule->is_ignore == CGRULE_OPT_IGNORE_RT && cgroup_is_rt_task(pid) == false)
+               return false;
+
+       /* If the rule is "ignore" and "ignore_rt", move all tasks */
+
        ret = cg_get_cgroups_from_proc_cgroups(pid, cgroup_list, controller_list,
                                               MAX_MNT_ELEMENTS);
        if (ret < 0)
                goto out;
 
-       ret = cgroup_find_matching_destination(cgroup_list, rule->destination,
-                                              &cgroup_list_matching_idx);
-       if (ret < 0)
-               /* No cgroups matched */
-               goto out;
+       if (strcmp(rule->destination, "*")) {
+               ret = cgroup_find_matching_destination(cgroup_list, rule->destination,
+                                                      &cgroup_list_matching_idx);
+               if (ret < 0)
+                       /* No cgroups matched */
+                       goto out;
+       }
 
        token = strtok_r(controller_list[cgroup_list_matching_idx], ",", &saveptr);
        while (token != NULL) {
index 41db4dc46981115c0bb517e299bb4cf7c5635328..8f2201abf022a01b2a17959e0e1211fd854256ac 100644 (file)
@@ -49,7 +49,11 @@ extern "C" {
 #define CGRULE_WILD    ((uid_t) -2)
 
 #define CGRULE_SUCCESS_STORE_PID       "SUCCESS_STORE_PID"
-#define CGRULE_OPTION_IGNORE           "ignore" /* Definitions for the cgrules options field */
+/* Definitions for cgrules options field */
+#define CGRULE_OPTION_IGNORE           "ignore"
+#define CGRULE_OPTION_IGNORE_RT                "ignore_rt"
+#define CGRULE_OPT_IGNORE              1
+#define CGRULE_OPT_IGNORE_RT           2
 
 #define CGCONFIG_CONF_FILE             "/etc/cgconfig.conf"
 /* Minimum number of file in template file list for cgrulesengd */
@@ -157,7 +161,7 @@ struct cgroup_rules_data {
 struct cgroup_rule {
        uid_t uid;
        gid_t gid;
-       bool is_ignore;
+       int is_ignore;
        char *procname;
        char username[LOGIN_NAME_MAX];
        char destination[FILENAME_MAX];