From b8bba7ba61fbcdcebf8291c639a9a88110e5098a Mon Sep 17 00:00:00 2001 From: Kamalesh Babulal Date: Tue, 8 Oct 2024 13:25:00 +0000 Subject: [PATCH] cgrules: Add ignore_rt option 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 Signed-off-by: Kamalesh Babulal Signed-off-by: Tom Hromatka --- src/api.c | 61 ++++++++++++++++++++++++++++++++-------- src/libcgroup-internal.h | 8 ++++-- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/api.c b/src/api.c index 39eccdd7..8c180998 100644 --- 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) { diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h index 41db4dc4..8f2201ab 100644 --- a/src/libcgroup-internal.h +++ b/src/libcgroup-internal.h @@ -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]; -- 2.47.3