diff options
Diffstat (limited to 'src/shared/cgroup-util.c')
-rw-r--r-- | src/shared/cgroup-util.c | 250 |
1 files changed, 0 insertions, 250 deletions
diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c deleted file mode 100644 index 326b75f763..0000000000 --- a/src/shared/cgroup-util.c +++ /dev/null @@ -1,250 +0,0 @@ -/*** - This file is part of eudev, forked from systemd. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <errno.h> -#include <signal.h> -#include <string.h> -#include <stdlib.h> -#include <sys/types.h> - -#include "cgroup-util.h" -#include "set.h" -#include "process-util.h" -#include "path-util.h" - -int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { - _cleanup_free_ char *fs = NULL; - FILE *f; - int r; - - assert(_f); - - r = cg_get_path(controller, path, "cgroup.procs", &fs); - if (r < 0) - return r; - - f = fopen(fs, "re"); - if (!f) - return -errno; - - *_f = f; - return 0; -} - -int cg_read_pid(FILE *f, pid_t *_pid) { - unsigned long ul; - - /* Note that the cgroup.procs might contain duplicates! See - * cgroups.txt for details. */ - - assert(f); - assert(_pid); - - errno = 0; - if (fscanf(f, "%lu", &ul) != 1) { - - if (feof(f)) - return 0; - - return errno ? -errno : -EIO; - } - - if (ul <= 0) - return -EIO; - - *_pid = (pid_t) ul; - return 1; -} - -int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) { - _cleanup_set_free_ Set *allocated_set = NULL; - bool done = false; - int r, ret = 0; - pid_t my_pid; - - assert(sig >= 0); - - /* This goes through the tasks list and kills them all. This - * is repeated until no further processes are added to the - * tasks list, to properly handle forking processes */ - - if (!s) { - s = allocated_set = set_new(NULL); - if (!s) - return -ENOMEM; - } - - my_pid = getpid(); - - do { - _cleanup_fclose_ FILE *f = NULL; - pid_t pid = 0; - done = true; - - r = cg_enumerate_processes(controller, path, &f); - if (r < 0) { - if (ret >= 0 && r != -ENOENT) - return r; - - return ret; - } - - while ((r = cg_read_pid(f, &pid)) > 0) { - - if (ignore_self && pid == my_pid) - continue; - - if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid)) - continue; - - /* If we haven't killed this process yet, kill - * it */ - if (kill(pid, sig) < 0) { - if (ret >= 0 && errno != ESRCH) - ret = -errno; - } else { - if (sigcont && sig != SIGKILL) - kill(pid, SIGCONT); - - if (ret == 0) - ret = 1; - } - - done = false; - - r = set_put(s, LONG_TO_PTR(pid)); - if (r < 0) { - if (ret >= 0) - return r; - - return ret; - } - } - - if (r < 0) { - if (ret >= 0) - return r; - - return ret; - } - - /* To avoid racing against processes which fork - * quicker than we can kill them we repeat this until - * no new pids need to be killed. */ - - } while (!done); - - return ret; -} - -static const char *normalize_controller(const char *controller) { - - assert(controller); - - if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) - return "systemd"; - else if (startswith(controller, "name=")) - return controller + 5; - else - return controller; -} - -static int join_path(const char *controller, const char *path, const char *suffix, char **fs) { - char *t = NULL; - - if (!isempty(controller)) { - if (!isempty(path) && !isempty(suffix)) - t = strjoin("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL); - else if (!isempty(path)) - t = strjoin("/sys/fs/cgroup/", controller, "/", path, NULL); - else if (!isempty(suffix)) - t = strjoin("/sys/fs/cgroup/", controller, "/", suffix, NULL); - else - t = strappend("/sys/fs/cgroup/", controller); - } else { - if (!isempty(path) && !isempty(suffix)) - t = strjoin(path, "/", suffix, NULL); - else if (!isempty(path)) - t = strdup(path); - else - return -EINVAL; - } - - if (!t) - return -ENOMEM; - - *fs = path_kill_slashes(t); - return 0; -} - -int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) { - const char *p; - static thread_local bool good = false; - - assert(fs); - - if (controller && !cg_controller_is_valid(controller, true)) - return -EINVAL; - - if (_unlikely_(!good)) { - int r; - - r = path_is_mount_point("/sys/fs/cgroup", false); - if (r < 0) - return r; - if (r == 0) - return -ENOENT; - - /* Cache this to save a few stat()s */ - good = true; - } - - p = controller ? normalize_controller(controller) : NULL; - - return join_path(p, path, suffix, fs); -} - -#define CONTROLLER_VALID \ - DIGITS LETTERS \ - "_" - -bool cg_controller_is_valid(const char *p, bool allow_named) { - const char *t, *s; - - if (!p) - return false; - - if (allow_named) { - s = startswith(p, "name="); - if (s) - p = s; - } - - if (*p == 0 || *p == '_') - return false; - - for (t = p; *t; t++) - if (!strchr(CONTROLLER_VALID, *t)) - return false; - - if (t - p > FILENAME_MAX) - return false; - - return true; -} |