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;
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);
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
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;
/* 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) {
#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 */
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];