cgroup-util.c revision 2d76d14ea3682c1c144001449654eb0c6bbda08d
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek This file is part of systemd.
71d35b6b5563817dfbe757ab9e3b9f018b2db491Thomas Hindoe Paaboel Andersen Copyright 2010 Lennart Poettering
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek (at your option) any later version.
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek r = cg_get_path(controller, path, "cgroup.procs", &fs);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekint cg_enumerate_tasks(const char *controller, const char *path, FILE **_f) {
return -errno;
*_f = f;
unsigned long ul;
* cgroups.txt for details. */
errno = 0;
if (feof(f))
if (ul <= 0)
return -EIO;
char *fs;
DIR *d;
return -errno;
*_d = d;
assert(d);
errno = 0;
return -ENOMEM;
*fn = b;
if (errno)
return -errno;
if (honour_sticky) {
char *tasks;
if (!tasks) {
free(p);
return -ENOMEM;
free(p);
r = rmdir(p);
free(p);
int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) {
bool done = false;
int r, ret = 0;
return -ENOMEM;
done = true;
ret = r;
goto finish;
} else if (ret == 0) {
if (sigcont)
done = false;
if (ret >= 0)
ret = r;
goto finish;
if (ret >= 0)
ret = r;
goto finish;
fclose(f);
f = NULL;
} while (!done);
if (allocated_set)
fclose(f);
return ret;
int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool rem, Set *s) {
int r, ret = 0;
char *fn;
return -ENOMEM;
ret = r;
goto finish;
char *p = NULL;
if (ret >= 0)
goto finish;
free(p);
if (r != 0 && ret >= 0)
ret = r;
if (r < 0 && ret >= 0)
ret = r;
if (rem)
if (ret >= 0 &&
r != -ENOENT &&
r != -EBUSY)
ret = r;
closedir(d);
if (allocated_set)
return ret;
int sig, r;
sig = 0;
int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self) {
bool done = false;
int r, ret = 0;
return -ENOMEM;
done = true;
ret = r;
return ret;
ret = r;
} else if (ret == 0)
done = false;
if (ret >= 0)
ret = r;
return ret;
if (ret >= 0)
ret = r;
return ret;
fclose(f);
f = NULL;
} while (!done);
return ret;
int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool rem) {
int r, ret = 0;
char *fn;
ret = r;
return ret;
if (ret >= 0)
return ret;
if (r != 0 && ret >= 0)
ret = r;
if (r < 0 && ret >= 0)
ret = r;
if (rem) {
return ret;
return controller;
char *t = NULL;
return -EINVAL;
if (controller) {
else if (path)
else if (suffix)
else if (path)
return -ENOMEM;
*fs = t;
return r < 0 ? r : -ENOENT;
good = true;
static int check(const char *p) {
char *cc;
assert(p);
return -errno;
int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) {
return -EINVAL;
r = check(p);
bool is_sticky;
free(p);
if (is_sticky)
char *fs;
errno = 0;
if (delete_root) {
bool is_sticky;
return -ENOMEM;
free(p);
if (!is_sticky)
r = -errno;
char *parent;
return r == -ENOENT ? 0 : r;
if (pid == 0)
int cg_set_group_access(
const char *controller,
const char *path,
int cg_set_task_access(
const char *controller,
const char *path,
int sticky) {
return -errno;
char *p = NULL;
FILE *f;
char *fs;
if (pid == 0)
return -ENOMEM;
while (!feof(f)) {
errno = 0;
if (feof(f))
goto finish;
r = -ENOMEM;
goto finish;
*path = p;
goto finish;
r = -ENOENT;
fclose(f);
goto finish;
if (sc[0] == 0) {
r = -ENOMEM;
goto finish;
goto finish;
r = -EEXIST;
goto finish;
goto finish;
goto finish;
goto finish;
r = -EIO;
goto finish;
bool found = false;
found = true;
fclose(f);
return !found;
char *fn;
char *p = NULL;
r = -ENOMEM;
goto finish;
free(p);
goto finish;
closedir(d);
return -EINVAL;
if (path) {
return -ENOMEM;
*path = t;
if (controller)
return -EINVAL;
if (controller) {
return -ENOMEM;
*controller = t;
if (path)
return -ENOMEM;
if (!filename_is_safe(t)) {
free(t);
return -EINVAL;
free(t);
return -ENOMEM;
if (!path_is_safe(u)) {
free(t);
free(u);
return -EINVAL;
if (controller)
*controller = t;
free(t);
if (path)
*path = u;
free(u);
controller[0] == 0 ||
return -EINVAL;
return -ENOMEM;
return -ENOMEM;
*result = t;
free(c);
free(p);
char *root, *p;
root[0] = 0;
return -ENOMEM;
*path = p;
if (!controllers)
return controllers;
free(*f);
p = normalize_controller(*f);
r = check(p);
free(*f);
*t = NULL;
return controllers;
if (pid == 0)
cg_init[0] = 0;
p = cg_process;
if (cgroup) {
c = strdup(p);
return -ENOMEM;
*cgroup = c;
if (root) {
char *at;
if (at) {
return -EINVAL;
if (!s || !i2)
return -ENOMEM;
assert(p);
return -EINVAL;
if (!*unit)
return -ENOMEM;
return -ENOENT;
const char *dot;
return -EINVAL;
if (!dot) {
return -ENOMEM;
if (!filename_is_safe(c)) {
free(c);
return -EINVAL;
*controller = c;