From d9d799ce72f7a6bc4f5c408b05ed682387ce971e Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Wed, 20 Feb 2013 09:08:19 -0800 Subject: [PATCH] libcg: scan running tasks at start time to classify existing pids Add routine to scan rules.conf file and move matching running tasks in /proc/pid/* into configured control groups. Then at init time we can move running tasks into the correct control group. Expose this routine via libcg so other applications can use it to classify existing applications after creating control groups. CC: Jan Safranek Signed-off-by: John Fastabend Signed-off-by: Jan Safranek --- include/libcgroup/tasks.h | 11 ++++++++++ src/api.c | 46 +++++++++++++++++++++++++++++++++++++++ src/daemon/cgrulesengd.c | 5 +++++ src/libcgroup.map | 1 + 4 files changed, 63 insertions(+) diff --git a/include/libcgroup/tasks.h b/include/libcgroup/tasks.h index 0f79220f..aad438a2 100644 --- a/include/libcgroup/tasks.h +++ b/include/libcgroup/tasks.h @@ -120,6 +120,17 @@ void cgroup_print_rules_config(FILE *fp); * following functions. */ +/** + * Changes the cgroup of all running PIDs based on the rules in the config + * file. If a rules exists for a PID, then the PID is placed in the correct + * group. + * + * This function may be called after creating new control groups to move + * running PIDs into the newly created control groups. + * @return 0 on success, < 0 on error + */ +int cgroup_change_all_cgroups(void); + /** * Changes the cgroup of a program based on the rules in the config file. * If a rule exists for the given UID, GID or PROCESS NAME, then the given diff --git a/src/api.c b/src/api.c index 11cd1b45..2851efd0 100644 --- a/src/api.c +++ b/src/api.c @@ -3055,6 +3055,52 @@ int cgroup_change_cgroup_path(const char *dest, pid_t pid, return ret; } +/** + * Changes the cgroup of all running PIDs based on the rules in the config + * file. If a rules exists for a PID, then the PID is placed in the correct + * group. + * + * This function may be called after creating new control groups to move + * running PIDs into the newly created control groups. + * @return 0 on success, < 0 on error + */ +int cgroup_change_all_cgroups(void) +{ + DIR *dir; + struct dirent *pid_dir = NULL; + char *path = "/proc/"; + + dir = opendir(path); + if (!dir) + return -ECGOTHER; + + while ((pid_dir = readdir(dir)) != NULL) { + int err, pid; + uid_t euid; + gid_t egid; + char *procname = NULL; + + err = sscanf(pid_dir->d_name, "%i", &pid); + if (err < 1) + continue; + + err = cgroup_get_uid_gid_from_procfs(pid, &euid, &egid); + if (err) + continue; + + err = cgroup_get_procname_from_procfs(pid, &procname); + if (err) + continue; + + err = cgroup_change_cgroup_flags(euid, egid, procname, pid, 0); + if (err) + cgroup_dbg("cgroup change pid %i failed\n", pid); + } + + closedir(dir); + return 0; +} + /** * Print the cached rules table. This function should be called only after * first calling cgroup_parse_config(), but it will work with an empty rule diff --git a/src/daemon/cgrulesengd.c b/src/daemon/cgrulesengd.c index f12db454..42feaccf 100644 --- a/src/daemon/cgrulesengd.c +++ b/src/daemon/cgrulesengd.c @@ -1171,6 +1171,11 @@ int main(int argc, char *argv[]) if (logfile && loglevel >= LOG_INFO) cgroup_print_rules_config(logfile); + /* Scan for running applications with rules */ + ret = cgroup_change_all_cgroups(); + if (ret) + flog(LOG_WARNING, "Failed to initialize running tasks."); + flog(LOG_NOTICE, "Started the CGroup Rules Engine Daemon."); /* We loop endlesly in this function, unless we encounter an error. */ diff --git a/src/libcgroup.map b/src/libcgroup.map index b550a58f..7dce2dfc 100644 --- a/src/libcgroup.map +++ b/src/libcgroup.map @@ -110,4 +110,5 @@ CGROUP_0.39 { cgroup_reload_cached_templates; cgroup_init_templates_cache; cgroup_config_create_template_group; + cgroup_change_all_cgroups; } CGROUP_0.38; -- 2.47.2