1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include <sys/types.h>
32 #include "alloc-util.h"
33 #include "cgroup-util.h"
34 #include "dirent-util.h"
35 #include "extract-word.h"
38 #include "formats-util.h"
40 #include "login-util.h"
43 #include "parse-util.h"
44 #include "path-util.h"
45 #include "proc-cmdline.h"
46 #include "process-util.h"
49 #include "stat-util.h"
50 #include "string-table.h"
51 #include "string-util.h"
52 #include "unit-name.h"
53 #include "user-util.h"
56 int cg_enumerate_processes(const char *controller
, const char *path
, FILE **_f
) {
57 _cleanup_free_
char *fs
= NULL
;
63 r
= cg_get_path(controller
, path
, "cgroup.procs", &fs
);
75 int cg_read_pid(FILE *f
, pid_t
*_pid
) {
78 /* Note that the cgroup.procs might contain duplicates! See
79 * cgroups.txt for details. */
85 if (fscanf(f
, "%lu", &ul
) != 1) {
90 return errno
? -errno
: -EIO
;
100 int cg_enumerate_subgroups(const char *controller
, const char *path
, DIR **_d
) {
101 _cleanup_free_
char *fs
= NULL
;
107 /* This is not recursive! */
109 r
= cg_get_path(controller
, path
, NULL
, &fs
);
121 int cg_read_subgroup(DIR *d
, char **fn
) {
127 FOREACH_DIRENT_ALL(de
, d
, return -errno
) {
130 if (de
->d_type
!= DT_DIR
)
133 if (streq(de
->d_name
, ".") ||
134 streq(de
->d_name
, ".."))
137 b
= strdup(de
->d_name
);
148 int cg_rmdir(const char *controller
, const char *path
) {
149 _cleanup_free_
char *p
= NULL
;
152 r
= cg_get_path(controller
, path
, NULL
, &p
);
157 if (r
< 0 && errno
!= ENOENT
)
163 int cg_kill(const char *controller
, const char *path
, int sig
, bool sigcont
, bool ignore_self
, Set
*s
) {
164 _cleanup_set_free_ Set
*allocated_set
= NULL
;
171 /* This goes through the tasks list and kills them all. This
172 * is repeated until no further processes are added to the
173 * tasks list, to properly handle forking processes */
176 s
= allocated_set
= set_new(NULL
);
184 _cleanup_fclose_
FILE *f
= NULL
;
188 r
= cg_enumerate_processes(controller
, path
, &f
);
190 if (ret
>= 0 && r
!= -ENOENT
)
196 while ((r
= cg_read_pid(f
, &pid
)) > 0) {
198 if (ignore_self
&& pid
== my_pid
)
201 if (set_get(s
, PID_TO_PTR(pid
)) == PID_TO_PTR(pid
))
204 /* If we haven't killed this process yet, kill
206 if (kill(pid
, sig
) < 0) {
207 if (ret
>= 0 && errno
!= ESRCH
)
210 if (sigcont
&& sig
!= SIGKILL
)
211 (void) kill(pid
, SIGCONT
);
219 r
= set_put(s
, PID_TO_PTR(pid
));
235 /* To avoid racing against processes which fork
236 * quicker than we can kill them we repeat this until
237 * no new pids need to be killed. */
244 int cg_kill_recursive(const char *controller
, const char *path
, int sig
, bool sigcont
, bool ignore_self
, bool rem
, Set
*s
) {
245 _cleanup_set_free_ Set
*allocated_set
= NULL
;
246 _cleanup_closedir_
DIR *d
= NULL
;
254 s
= allocated_set
= set_new(NULL
);
259 ret
= cg_kill(controller
, path
, sig
, sigcont
, ignore_self
, s
);
261 r
= cg_enumerate_subgroups(controller
, path
, &d
);
263 if (ret
>= 0 && r
!= -ENOENT
)
269 while ((r
= cg_read_subgroup(d
, &fn
)) > 0) {
270 _cleanup_free_
char *p
= NULL
;
272 p
= strjoin(path
, "/", fn
, NULL
);
277 r
= cg_kill_recursive(controller
, p
, sig
, sigcont
, ignore_self
, rem
, s
);
278 if (r
!= 0 && ret
>= 0)
282 if (ret
>= 0 && r
< 0)
286 r
= cg_rmdir(controller
, path
);
287 if (r
< 0 && ret
>= 0 && r
!= -ENOENT
&& r
!= -EBUSY
)
294 int cg_migrate(const char *cfrom
, const char *pfrom
, const char *cto
, const char *pto
, bool ignore_self
) {
296 _cleanup_set_free_ Set
*s
= NULL
;
312 _cleanup_fclose_
FILE *f
= NULL
;
316 r
= cg_enumerate_processes(cfrom
, pfrom
, &f
);
318 if (ret
>= 0 && r
!= -ENOENT
)
324 while ((r
= cg_read_pid(f
, &pid
)) > 0) {
326 /* This might do weird stuff if we aren't a
327 * single-threaded program. However, we
328 * luckily know we are not */
329 if (ignore_self
&& pid
== my_pid
)
332 if (set_get(s
, PID_TO_PTR(pid
)) == PID_TO_PTR(pid
))
335 /* Ignore kernel threads. Since they can only
336 * exist in the root cgroup, we only check for
339 (isempty(pfrom
) || path_equal(pfrom
, "/")) &&
340 is_kernel_thread(pid
) > 0)
343 r
= cg_attach(cto
, pto
, pid
);
345 if (ret
>= 0 && r
!= -ESRCH
)
352 r
= set_put(s
, PID_TO_PTR(pid
));
372 int cg_migrate_recursive(
380 _cleanup_closedir_
DIR *d
= NULL
;
389 ret
= cg_migrate(cfrom
, pfrom
, cto
, pto
, ignore_self
);
391 r
= cg_enumerate_subgroups(cfrom
, pfrom
, &d
);
393 if (ret
>= 0 && r
!= -ENOENT
)
399 while ((r
= cg_read_subgroup(d
, &fn
)) > 0) {
400 _cleanup_free_
char *p
= NULL
;
402 p
= strjoin(pfrom
, "/", fn
, NULL
);
407 r
= cg_migrate_recursive(cfrom
, p
, cto
, pto
, ignore_self
, rem
);
408 if (r
!= 0 && ret
>= 0)
412 if (r
< 0 && ret
>= 0)
416 r
= cg_rmdir(cfrom
, pfrom
);
417 if (r
< 0 && ret
>= 0 && r
!= -ENOENT
&& r
!= -EBUSY
)
424 int cg_migrate_recursive_fallback(
439 r
= cg_migrate_recursive(cfrom
, pfrom
, cto
, pto
, ignore_self
, rem
);
441 char prefix
[strlen(pto
) + 1];
443 /* This didn't work? Then let's try all prefixes of the destination */
445 PATH_FOREACH_PREFIX(prefix
, pto
) {
448 q
= cg_migrate_recursive(cfrom
, pfrom
, cto
, prefix
, ignore_self
, rem
);
457 static const char *controller_to_dirname(const char *controller
) {
462 /* Converts a controller name to the directory name below
463 * /sys/fs/cgroup/ we want to mount it to. Effectively, this
464 * just cuts off the name= prefixed used for named
465 * hierarchies, if it is specified. */
467 e
= startswith(controller
, "name=");
474 static int join_path_legacy(const char *controller
, const char *path
, const char *suffix
, char **fs
) {
481 dn
= controller_to_dirname(controller
);
483 if (isempty(path
) && isempty(suffix
))
484 t
= strappend("/sys/fs/cgroup/", dn
);
485 else if (isempty(path
))
486 t
= strjoin("/sys/fs/cgroup/", dn
, "/", suffix
, NULL
);
487 else if (isempty(suffix
))
488 t
= strjoin("/sys/fs/cgroup/", dn
, "/", path
, NULL
);
490 t
= strjoin("/sys/fs/cgroup/", dn
, "/", path
, "/", suffix
, NULL
);
498 static int join_path_unified(const char *path
, const char *suffix
, char **fs
) {
503 if (isempty(path
) && isempty(suffix
))
504 t
= strdup("/sys/fs/cgroup");
505 else if (isempty(path
))
506 t
= strappend("/sys/fs/cgroup/", suffix
);
507 else if (isempty(suffix
))
508 t
= strappend("/sys/fs/cgroup/", path
);
510 t
= strjoin("/sys/fs/cgroup/", path
, "/", suffix
, NULL
);
518 int cg_get_path(const char *controller
, const char *path
, const char *suffix
, char **fs
) {
526 /* If no controller is specified, we return the path
527 * *below* the controllers, without any prefix. */
529 if (!path
&& !suffix
)
537 t
= strjoin(path
, "/", suffix
, NULL
);
541 *fs
= path_kill_slashes(t
);
545 if (!cg_controller_is_valid(controller
))
548 unified
= cg_unified();
553 r
= join_path_unified(path
, suffix
, fs
);
555 r
= join_path_legacy(controller
, path
, suffix
, fs
);
559 path_kill_slashes(*fs
);
563 static int controller_is_accessible(const char *controller
) {
568 /* Checks whether a specific controller is accessible,
569 * i.e. its hierarchy mounted. In the unified hierarchy all
570 * controllers are considered accessible, except for the named
573 if (!cg_controller_is_valid(controller
))
576 unified
= cg_unified();
580 /* We don't support named hierarchies if we are using
581 * the unified hierarchy. */
583 if (streq(controller
, SYSTEMD_CGROUP_CONTROLLER
))
586 if (startswith(controller
, "name="))
592 dn
= controller_to_dirname(controller
);
593 cc
= strjoina("/sys/fs/cgroup/", dn
);
595 if (laccess(cc
, F_OK
) < 0)
602 int cg_get_path_and_check(const char *controller
, const char *path
, const char *suffix
, char **fs
) {
608 /* Check if the specified controller is actually accessible */
609 r
= controller_is_accessible(controller
);
613 return cg_get_path(controller
, path
, suffix
, fs
);
616 static int trim_cb(const char *path
, const struct stat
*sb
, int typeflag
, struct FTW
*ftwbuf
) {
621 if (typeflag
!= FTW_DP
)
624 if (ftwbuf
->level
< 1)
631 int cg_trim(const char *controller
, const char *path
, bool delete_root
) {
632 _cleanup_free_
char *fs
= NULL
;
637 r
= cg_get_path(controller
, path
, NULL
, &fs
);
642 if (nftw(fs
, trim_cb
, 64, FTW_DEPTH
|FTW_MOUNT
|FTW_PHYS
) != 0) {
652 if (rmdir(fs
) < 0 && errno
!= ENOENT
)
659 int cg_create(const char *controller
, const char *path
) {
660 _cleanup_free_
char *fs
= NULL
;
663 r
= cg_get_path_and_check(controller
, path
, NULL
, &fs
);
667 r
= mkdir_parents(fs
, 0755);
671 if (mkdir(fs
, 0755) < 0) {
682 int cg_create_and_attach(const char *controller
, const char *path
, pid_t pid
) {
687 r
= cg_create(controller
, path
);
691 q
= cg_attach(controller
, path
, pid
);
695 /* This does not remove the cgroup on failure */
699 int cg_attach(const char *controller
, const char *path
, pid_t pid
) {
700 _cleanup_free_
char *fs
= NULL
;
701 char c
[DECIMAL_STR_MAX(pid_t
) + 2];
707 r
= cg_get_path_and_check(controller
, path
, "cgroup.procs", &fs
);
714 snprintf(c
, sizeof(c
), PID_FMT
"\n", pid
);
716 return write_string_file(fs
, c
, 0);
719 int cg_attach_fallback(const char *controller
, const char *path
, pid_t pid
) {
726 r
= cg_attach(controller
, path
, pid
);
728 char prefix
[strlen(path
) + 1];
730 /* This didn't work? Then let's try all prefixes of
733 PATH_FOREACH_PREFIX(prefix
, path
) {
736 q
= cg_attach(controller
, prefix
, pid
);
745 int cg_set_group_access(
746 const char *controller
,
752 _cleanup_free_
char *fs
= NULL
;
755 if (mode
== MODE_INVALID
&& uid
== UID_INVALID
&& gid
== GID_INVALID
)
758 if (mode
!= MODE_INVALID
)
761 r
= cg_get_path(controller
, path
, NULL
, &fs
);
765 return chmod_and_chown(fs
, mode
, uid
, gid
);
768 int cg_set_task_access(
769 const char *controller
,
775 _cleanup_free_
char *fs
= NULL
, *procs
= NULL
;
780 if (mode
== MODE_INVALID
&& uid
== UID_INVALID
&& gid
== GID_INVALID
)
783 if (mode
!= MODE_INVALID
)
786 r
= cg_get_path(controller
, path
, "cgroup.procs", &fs
);
790 r
= chmod_and_chown(fs
, mode
, uid
, gid
);
794 unified
= cg_unified();
800 /* Compatibility, Always keep values for "tasks" in sync with
802 if (cg_get_path(controller
, path
, "tasks", &procs
) >= 0)
803 (void) chmod_and_chown(procs
, mode
, uid
, gid
);
808 int cg_pid_get_path(const char *controller
, pid_t pid
, char **path
) {
809 _cleanup_fclose_
FILE *f
= NULL
;
818 unified
= cg_unified();
823 if (!cg_controller_is_valid(controller
))
826 controller
= SYSTEMD_CGROUP_CONTROLLER
;
828 cs
= strlen(controller
);
831 fs
= procfs_file_alloca(pid
, "cgroup");
834 return errno
== ENOENT
? -ESRCH
: -errno
;
836 FOREACH_LINE(line
, f
, return -errno
) {
842 e
= startswith(line
, "0:");
852 const char *word
, *state
;
855 l
= strchr(line
, ':');
865 FOREACH_WORD_SEPARATOR(word
, k
, l
, ",", state
) {
866 if (k
== cs
&& memcmp(word
, controller
, cs
) == 0) {
887 int cg_install_release_agent(const char *controller
, const char *agent
) {
888 _cleanup_free_
char *fs
= NULL
, *contents
= NULL
;
894 unified
= cg_unified();
897 if (unified
) /* doesn't apply to unified hierarchy */
900 r
= cg_get_path(controller
, NULL
, "release_agent", &fs
);
904 r
= read_one_line_file(fs
, &contents
);
908 sc
= strstrip(contents
);
910 r
= write_string_file(fs
, agent
, 0);
913 } else if (!path_equal(sc
, agent
))
917 r
= cg_get_path(controller
, NULL
, "notify_on_release", &fs
);
921 contents
= mfree(contents
);
922 r
= read_one_line_file(fs
, &contents
);
926 sc
= strstrip(contents
);
927 if (streq(sc
, "0")) {
928 r
= write_string_file(fs
, "1", 0);
941 int cg_uninstall_release_agent(const char *controller
) {
942 _cleanup_free_
char *fs
= NULL
;
945 unified
= cg_unified();
948 if (unified
) /* Doesn't apply to unified hierarchy */
951 r
= cg_get_path(controller
, NULL
, "notify_on_release", &fs
);
955 r
= write_string_file(fs
, "0", 0);
961 r
= cg_get_path(controller
, NULL
, "release_agent", &fs
);
965 r
= write_string_file(fs
, "", 0);
972 int cg_is_empty(const char *controller
, const char *path
) {
973 _cleanup_fclose_
FILE *f
= NULL
;
979 r
= cg_enumerate_processes(controller
, path
, &f
);
985 r
= cg_read_pid(f
, &pid
);
992 int cg_is_empty_recursive(const char *controller
, const char *path
) {
997 /* The root cgroup is always populated */
998 if (controller
&& (isempty(path
) || path_equal(path
, "/")))
1001 unified
= cg_unified();
1006 _cleanup_free_
char *populated
= NULL
, *t
= NULL
;
1008 /* On the unified hierarchy we can check empty state
1009 * via the "cgroup.populated" attribute. */
1011 r
= cg_get_path(controller
, path
, "cgroup.populated", &populated
);
1015 r
= read_one_line_file(populated
, &t
);
1021 return streq(t
, "0");
1023 _cleanup_closedir_
DIR *d
= NULL
;
1026 r
= cg_is_empty(controller
, path
);
1030 r
= cg_enumerate_subgroups(controller
, path
, &d
);
1036 while ((r
= cg_read_subgroup(d
, &fn
)) > 0) {
1037 _cleanup_free_
char *p
= NULL
;
1039 p
= strjoin(path
, "/", fn
, NULL
);
1044 r
= cg_is_empty_recursive(controller
, p
);
1055 int cg_split_spec(const char *spec
, char **controller
, char **path
) {
1056 char *t
= NULL
, *u
= NULL
;
1062 if (!path_is_safe(spec
))
1070 *path
= path_kill_slashes(t
);
1079 e
= strchr(spec
, ':');
1081 if (!cg_controller_is_valid(spec
))
1098 t
= strndup(spec
, e
-spec
);
1101 if (!cg_controller_is_valid(t
)) {
1115 if (!path_is_safe(u
) ||
1116 !path_is_absolute(u
)) {
1122 path_kill_slashes(u
);
1138 int cg_mangle_path(const char *path
, char **result
) {
1139 _cleanup_free_
char *c
= NULL
, *p
= NULL
;
1146 /* First, check if it already is a filesystem path */
1147 if (path_startswith(path
, "/sys/fs/cgroup")) {
1153 *result
= path_kill_slashes(t
);
1157 /* Otherwise, treat it as cg spec */
1158 r
= cg_split_spec(path
, &c
, &p
);
1162 return cg_get_path(c
?: SYSTEMD_CGROUP_CONTROLLER
, p
?: "/", NULL
, result
);
1165 int cg_get_root_path(char **path
) {
1171 r
= cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER
, 1, &p
);
1175 e
= endswith(p
, "/" SPECIAL_INIT_SCOPE
);
1177 e
= endswith(p
, "/" SPECIAL_SYSTEM_SLICE
); /* legacy */
1179 e
= endswith(p
, "/system"); /* even more legacy */
1187 int cg_shift_path(const char *cgroup
, const char *root
, const char **shifted
) {
1188 _cleanup_free_
char *rt
= NULL
;
1196 /* If the root was specified let's use that, otherwise
1197 * let's determine it from PID 1 */
1199 r
= cg_get_root_path(&rt
);
1206 p
= path_startswith(cgroup
, root
);
1207 if (p
&& p
> cgroup
)
1215 int cg_pid_get_path_shifted(pid_t pid
, const char *root
, char **cgroup
) {
1216 _cleanup_free_
char *raw
= NULL
;
1223 r
= cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER
, pid
, &raw
);
1227 r
= cg_shift_path(raw
, root
, &c
);
1247 int cg_path_decode_unit(const char *cgroup
, char **unit
){
1254 n
= strcspn(cgroup
, "/");
1258 c
= strndupa(cgroup
, n
);
1261 if (!unit_name_is_valid(c
, UNIT_NAME_PLAIN
|UNIT_NAME_INSTANCE
))
1272 static bool valid_slice_name(const char *p
, size_t n
) {
1277 if (n
< strlen("x.slice"))
1280 if (memcmp(p
+ n
- 6, ".slice", 6) == 0) {
1286 c
= cg_unescape(buf
);
1288 return unit_name_is_valid(c
, UNIT_NAME_PLAIN
);
1294 static const char *skip_slices(const char *p
) {
1297 /* Skips over all slice assignments */
1302 p
+= strspn(p
, "/");
1304 n
= strcspn(p
, "/");
1305 if (!valid_slice_name(p
, n
))
1312 int cg_path_get_unit(const char *path
, char **ret
) {
1320 e
= skip_slices(path
);
1322 r
= cg_path_decode_unit(e
, &unit
);
1326 /* We skipped over the slices, don't accept any now */
1327 if (endswith(unit
, ".slice")) {
1336 int cg_pid_get_unit(pid_t pid
, char **unit
) {
1337 _cleanup_free_
char *cgroup
= NULL
;
1342 r
= cg_pid_get_path_shifted(pid
, NULL
, &cgroup
);
1346 return cg_path_get_unit(cgroup
, unit
);
1350 * Skip session-*.scope, but require it to be there.
1352 static const char *skip_session(const char *p
) {
1358 p
+= strspn(p
, "/");
1360 n
= strcspn(p
, "/");
1361 if (n
< strlen("session-x.scope"))
1364 if (memcmp(p
, "session-", 8) == 0 && memcmp(p
+ n
- 6, ".scope", 6) == 0) {
1365 char buf
[n
- 8 - 6 + 1];
1367 memcpy(buf
, p
+ 8, n
- 8 - 6);
1370 /* Note that session scopes never need unescaping,
1371 * since they cannot conflict with the kernel's own
1372 * names, hence we don't need to call cg_unescape()
1375 if (!session_id_valid(buf
))
1379 p
+= strspn(p
, "/");
1387 * Skip user@*.service, but require it to be there.
1389 static const char *skip_user_manager(const char *p
) {
1395 p
+= strspn(p
, "/");
1397 n
= strcspn(p
, "/");
1398 if (n
< strlen("user@x.service"))
1401 if (memcmp(p
, "user@", 5) == 0 && memcmp(p
+ n
- 8, ".service", 8) == 0) {
1402 char buf
[n
- 5 - 8 + 1];
1404 memcpy(buf
, p
+ 5, n
- 5 - 8);
1407 /* Note that user manager services never need unescaping,
1408 * since they cannot conflict with the kernel's own
1409 * names, hence we don't need to call cg_unescape()
1412 if (parse_uid(buf
, NULL
) < 0)
1416 p
+= strspn(p
, "/");
1424 static const char *skip_user_prefix(const char *path
) {
1429 /* Skip slices, if there are any */
1430 e
= skip_slices(path
);
1432 /* Skip the user manager, if it's in the path now... */
1433 t
= skip_user_manager(e
);
1437 /* Alternatively skip the user session if it is in the path... */
1438 return skip_session(e
);
1441 int cg_path_get_user_unit(const char *path
, char **ret
) {
1447 t
= skip_user_prefix(path
);
1451 /* And from here on it looks pretty much the same as for a
1452 * system unit, hence let's use the same parser from here
1454 return cg_path_get_unit(t
, ret
);
1457 int cg_pid_get_user_unit(pid_t pid
, char **unit
) {
1458 _cleanup_free_
char *cgroup
= NULL
;
1463 r
= cg_pid_get_path_shifted(pid
, NULL
, &cgroup
);
1467 return cg_path_get_user_unit(cgroup
, unit
);
1470 int cg_path_get_machine_name(const char *path
, char **machine
) {
1471 _cleanup_free_
char *u
= NULL
;
1475 r
= cg_path_get_unit(path
, &u
);
1479 sl
= strjoina("/run/systemd/machines/unit:", u
);
1480 return readlink_malloc(sl
, machine
);
1483 int cg_pid_get_machine_name(pid_t pid
, char **machine
) {
1484 _cleanup_free_
char *cgroup
= NULL
;
1489 r
= cg_pid_get_path_shifted(pid
, NULL
, &cgroup
);
1493 return cg_path_get_machine_name(cgroup
, machine
);
1496 int cg_path_get_session(const char *path
, char **session
) {
1497 _cleanup_free_
char *unit
= NULL
;
1503 r
= cg_path_get_unit(path
, &unit
);
1507 start
= startswith(unit
, "session-");
1510 end
= endswith(start
, ".scope");
1515 if (!session_id_valid(start
))
1531 int cg_pid_get_session(pid_t pid
, char **session
) {
1532 _cleanup_free_
char *cgroup
= NULL
;
1535 r
= cg_pid_get_path_shifted(pid
, NULL
, &cgroup
);
1539 return cg_path_get_session(cgroup
, session
);
1542 int cg_path_get_owner_uid(const char *path
, uid_t
*uid
) {
1543 _cleanup_free_
char *slice
= NULL
;
1549 r
= cg_path_get_slice(path
, &slice
);
1553 start
= startswith(slice
, "user-");
1556 end
= endswith(start
, ".slice");
1561 if (parse_uid(start
, uid
) < 0)
1567 int cg_pid_get_owner_uid(pid_t pid
, uid_t
*uid
) {
1568 _cleanup_free_
char *cgroup
= NULL
;
1571 r
= cg_pid_get_path_shifted(pid
, NULL
, &cgroup
);
1575 return cg_path_get_owner_uid(cgroup
, uid
);
1578 int cg_path_get_slice(const char *p
, char **slice
) {
1579 const char *e
= NULL
;
1584 /* Finds the right-most slice unit from the beginning, but
1585 * stops before we come to the first non-slice unit. */
1590 p
+= strspn(p
, "/");
1592 n
= strcspn(p
, "/");
1593 if (!valid_slice_name(p
, n
)) {
1598 s
= strdup("-.slice");
1606 return cg_path_decode_unit(e
, slice
);
1614 int cg_pid_get_slice(pid_t pid
, char **slice
) {
1615 _cleanup_free_
char *cgroup
= NULL
;
1620 r
= cg_pid_get_path_shifted(pid
, NULL
, &cgroup
);
1624 return cg_path_get_slice(cgroup
, slice
);
1627 int cg_path_get_user_slice(const char *p
, char **slice
) {
1632 t
= skip_user_prefix(p
);
1636 /* And now it looks pretty much the same as for a system
1637 * slice, so let's just use the same parser from here on. */
1638 return cg_path_get_slice(t
, slice
);
1641 int cg_pid_get_user_slice(pid_t pid
, char **slice
) {
1642 _cleanup_free_
char *cgroup
= NULL
;
1647 r
= cg_pid_get_path_shifted(pid
, NULL
, &cgroup
);
1651 return cg_path_get_user_slice(cgroup
, slice
);
1654 char *cg_escape(const char *p
) {
1655 bool need_prefix
= false;
1657 /* This implements very minimal escaping for names to be used
1658 * as file names in the cgroup tree: any name which might
1659 * conflict with a kernel name or is prefixed with '_' is
1660 * prefixed with a '_'. That way, when reading cgroup names it
1661 * is sufficient to remove a single prefixing underscore if
1664 /* The return value of this function (unlike cg_unescape())
1670 streq(p
, "notify_on_release") ||
1671 streq(p
, "release_agent") ||
1672 streq(p
, "tasks") ||
1673 startswith(p
, "cgroup."))
1678 dot
= strrchr(p
, '.');
1683 for (c
= 0; c
< _CGROUP_CONTROLLER_MAX
; c
++) {
1686 n
= cgroup_controller_to_string(c
);
1691 if (memcmp(p
, n
, l
) != 0)
1701 return strappend("_", p
);
1706 char *cg_unescape(const char *p
) {
1709 /* The return value of this function (unlike cg_escape())
1710 * doesn't need free()! */
1718 #define CONTROLLER_VALID \
1722 bool cg_controller_is_valid(const char *p
) {
1728 s
= startswith(p
, "name=");
1732 if (*p
== 0 || *p
== '_')
1735 for (t
= p
; *t
; t
++)
1736 if (!strchr(CONTROLLER_VALID
, *t
))
1739 if (t
- p
> FILENAME_MAX
)
1745 int cg_slice_to_path(const char *unit
, char **ret
) {
1746 _cleanup_free_
char *p
= NULL
, *s
= NULL
, *e
= NULL
;
1753 if (streq(unit
, "-.slice")) {
1763 if (!unit_name_is_valid(unit
, UNIT_NAME_PLAIN
))
1766 if (!endswith(unit
, ".slice"))
1769 r
= unit_name_to_prefix(unit
, &p
);
1773 dash
= strchr(p
, '-');
1775 /* Don't allow initial dashes */
1780 _cleanup_free_
char *escaped
= NULL
;
1781 char n
[dash
- p
+ sizeof(".slice")];
1783 /* Don't allow trailing or double dashes */
1784 if (dash
[1] == 0 || dash
[1] == '-')
1787 strcpy(stpncpy(n
, p
, dash
- p
), ".slice");
1788 if (!unit_name_is_valid(n
, UNIT_NAME_PLAIN
))
1791 escaped
= cg_escape(n
);
1795 if (!strextend(&s
, escaped
, "/", NULL
))
1798 dash
= strchr(dash
+1, '-');
1801 e
= cg_escape(unit
);
1805 if (!strextend(&s
, e
, NULL
))
1814 int cg_set_attribute(const char *controller
, const char *path
, const char *attribute
, const char *value
) {
1815 _cleanup_free_
char *p
= NULL
;
1818 r
= cg_get_path(controller
, path
, attribute
, &p
);
1822 return write_string_file(p
, value
, 0);
1825 int cg_get_attribute(const char *controller
, const char *path
, const char *attribute
, char **ret
) {
1826 _cleanup_free_
char *p
= NULL
;
1829 r
= cg_get_path(controller
, path
, attribute
, &p
);
1833 return read_one_line_file(p
, ret
);
1836 int cg_create_everywhere(CGroupMask supported
, CGroupMask mask
, const char *path
) {
1840 /* This one will create a cgroup in our private tree, but also
1841 * duplicate it in the trees specified in mask, and remove it
1844 /* First create the cgroup in our own hierarchy. */
1845 r
= cg_create(SYSTEMD_CGROUP_CONTROLLER
, path
);
1849 /* If we are in the unified hierarchy, we are done now */
1850 unified
= cg_unified();
1856 /* Otherwise, do the same in the other hierarchies */
1857 for (c
= 0; c
< _CGROUP_CONTROLLER_MAX
; c
++) {
1858 CGroupMask bit
= CGROUP_CONTROLLER_TO_MASK(c
);
1861 n
= cgroup_controller_to_string(c
);
1864 (void) cg_create(n
, path
);
1865 else if (supported
& bit
)
1866 (void) cg_trim(n
, path
, true);
1872 int cg_attach_everywhere(CGroupMask supported
, const char *path
, pid_t pid
, cg_migrate_callback_t path_callback
, void *userdata
) {
1876 r
= cg_attach(SYSTEMD_CGROUP_CONTROLLER
, path
, pid
);
1880 unified
= cg_unified();
1886 for (c
= 0; c
< _CGROUP_CONTROLLER_MAX
; c
++) {
1887 CGroupMask bit
= CGROUP_CONTROLLER_TO_MASK(c
);
1888 const char *p
= NULL
;
1890 if (!(supported
& bit
))
1894 p
= path_callback(bit
, userdata
);
1899 (void) cg_attach_fallback(cgroup_controller_to_string(c
), p
, pid
);
1905 int cg_attach_many_everywhere(CGroupMask supported
, const char *path
, Set
* pids
, cg_migrate_callback_t path_callback
, void *userdata
) {
1910 SET_FOREACH(pidp
, pids
, i
) {
1911 pid_t pid
= PTR_TO_PID(pidp
);
1914 q
= cg_attach_everywhere(supported
, path
, pid
, path_callback
, userdata
);
1915 if (q
< 0 && r
>= 0)
1922 int cg_migrate_everywhere(CGroupMask supported
, const char *from
, const char *to
, cg_migrate_callback_t to_callback
, void *userdata
) {
1926 if (!path_equal(from
, to
)) {
1927 r
= cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER
, from
, SYSTEMD_CGROUP_CONTROLLER
, to
, false, true);
1932 unified
= cg_unified();
1938 for (c
= 0; c
< _CGROUP_CONTROLLER_MAX
; c
++) {
1939 CGroupMask bit
= CGROUP_CONTROLLER_TO_MASK(c
);
1940 const char *p
= NULL
;
1942 if (!(supported
& bit
))
1946 p
= to_callback(bit
, userdata
);
1951 (void) cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER
, to
, cgroup_controller_to_string(c
), p
, false, false);
1957 int cg_trim_everywhere(CGroupMask supported
, const char *path
, bool delete_root
) {
1961 r
= cg_trim(SYSTEMD_CGROUP_CONTROLLER
, path
, delete_root
);
1965 unified
= cg_unified();
1971 for (c
= 0; c
< _CGROUP_CONTROLLER_MAX
; c
++) {
1972 CGroupMask bit
= CGROUP_CONTROLLER_TO_MASK(c
);
1974 if (!(supported
& bit
))
1977 (void) cg_trim(cgroup_controller_to_string(c
), path
, delete_root
);
1983 int cg_mask_supported(CGroupMask
*ret
) {
1984 CGroupMask mask
= 0;
1987 /* Determines the mask of supported cgroup controllers. Only
1988 * includes controllers we can make sense of and that are
1989 * actually accessible. */
1991 unified
= cg_unified();
1995 _cleanup_free_
char *root
= NULL
, *controllers
= NULL
, *path
= NULL
;
1998 /* In the unified hierarchy we can read the supported
1999 * and accessible controllers from a the top-level
2000 * cgroup attribute */
2002 r
= cg_get_root_path(&root
);
2006 r
= cg_get_path(SYSTEMD_CGROUP_CONTROLLER
, root
, "cgroup.controllers", &path
);
2010 r
= read_one_line_file(path
, &controllers
);
2016 _cleanup_free_
char *n
= NULL
;
2019 r
= extract_first_word(&c
, &n
, NULL
, 0);
2025 v
= cgroup_controller_from_string(n
);
2029 mask
|= CGROUP_CONTROLLER_TO_MASK(v
);
2032 /* Currently, we only support the memory and pids
2033 * controller in the unified hierarchy, mask
2034 * everything else off. */
2035 mask
&= CGROUP_MASK_MEMORY
| CGROUP_MASK_PIDS
;
2040 /* In the legacy hierarchy, we check whether which
2041 * hierarchies are mounted. */
2043 for (c
= 0; c
< _CGROUP_CONTROLLER_MAX
; c
++) {
2046 n
= cgroup_controller_to_string(c
);
2047 if (controller_is_accessible(n
) >= 0)
2048 mask
|= CGROUP_CONTROLLER_TO_MASK(c
);
2056 int cg_kernel_controllers(Set
*controllers
) {
2057 _cleanup_fclose_
FILE *f
= NULL
;
2061 assert(controllers
);
2063 /* Determines the full list of kernel-known controllers. Might
2064 * include controllers we don't actually support, arbitrary
2065 * named hierarchies and controllers that aren't currently
2066 * accessible (because not mounted). */
2068 f
= fopen("/proc/cgroups", "re");
2070 if (errno
== ENOENT
)
2075 /* Ignore the header line */
2076 (void) fgets(buf
, sizeof(buf
), f
);
2083 if (fscanf(f
, "%ms %*i %*i %i", &controller
, &enabled
) != 2) {
2088 if (ferror(f
) && errno
!= 0)
2099 if (!cg_controller_is_valid(controller
)) {
2104 r
= set_consume(controllers
, controller
);
2112 static thread_local
int unified_cache
= -1;
2114 int cg_unified(void) {
2117 /* Checks if we support the unified hierarchy. Returns an
2118 * error when the cgroup hierarchies aren't mounted yet or we
2119 * have any other trouble determining if the unified hierarchy
2122 if (unified_cache
>= 0)
2123 return unified_cache
;
2125 if (statfs("/sys/fs/cgroup/", &fs
) < 0)
2128 if (F_TYPE_EQUAL(fs
.f_type
, CGROUP_SUPER_MAGIC
))
2129 unified_cache
= true;
2130 else if (F_TYPE_EQUAL(fs
.f_type
, TMPFS_MAGIC
))
2131 unified_cache
= false;
2135 return unified_cache
;
2138 void cg_unified_flush(void) {
2142 int cg_enable_everywhere(CGroupMask supported
, CGroupMask mask
, const char *p
) {
2143 _cleanup_free_
char *fs
= NULL
;
2152 unified
= cg_unified();
2155 if (!unified
) /* on the legacy hiearchy there's no joining of controllers defined */
2158 r
= cg_get_path(SYSTEMD_CGROUP_CONTROLLER
, p
, "cgroup.subtree_control", &fs
);
2162 for (c
= 0; c
< _CGROUP_CONTROLLER_MAX
; c
++) {
2163 CGroupMask bit
= CGROUP_CONTROLLER_TO_MASK(c
);
2166 if (!(supported
& bit
))
2169 n
= cgroup_controller_to_string(c
);
2171 char s
[1 + strlen(n
) + 1];
2173 s
[0] = mask
& bit
? '+' : '-';
2176 r
= write_string_file(fs
, s
, 0);
2178 log_debug_errno(r
, "Failed to enable controller %s for %s (%s): %m", n
, p
, fs
);
2185 bool cg_is_unified_wanted(void) {
2186 static thread_local
int wanted
= -1;
2189 /* If the hierarchy is already mounted, then follow whatever
2190 * was chosen for it. */
2191 unified
= cg_unified();
2195 /* Otherwise, let's see what the kernel command line has to
2196 * say. Since checking that is expensive, let's cache the
2201 r
= get_proc_cmdline_key("systemd.unified_cgroup_hierarchy", NULL
);
2203 return (wanted
= true);
2205 _cleanup_free_
char *value
= NULL
;
2207 r
= get_proc_cmdline_key("systemd.unified_cgroup_hierarchy=", &value
);
2211 return (wanted
= false);
2213 return (wanted
= parse_boolean(value
) > 0);
2217 bool cg_is_legacy_wanted(void) {
2218 return !cg_is_unified_wanted();
2221 int cg_cpu_shares_parse(const char *s
, uint64_t *ret
) {
2226 *ret
= CGROUP_CPU_SHARES_INVALID
;
2230 r
= safe_atou64(s
, &u
);
2234 if (u
< CGROUP_CPU_SHARES_MIN
|| u
> CGROUP_CPU_SHARES_MAX
)
2241 int cg_blkio_weight_parse(const char *s
, uint64_t *ret
) {
2246 *ret
= CGROUP_BLKIO_WEIGHT_INVALID
;
2250 r
= safe_atou64(s
, &u
);
2254 if (u
< CGROUP_BLKIO_WEIGHT_MIN
|| u
> CGROUP_BLKIO_WEIGHT_MAX
)
2261 static const char *cgroup_controller_table
[_CGROUP_CONTROLLER_MAX
] = {
2262 [CGROUP_CONTROLLER_CPU
] = "cpu",
2263 [CGROUP_CONTROLLER_CPUACCT
] = "cpuacct",
2264 [CGROUP_CONTROLLER_BLKIO
] = "blkio",
2265 [CGROUP_CONTROLLER_MEMORY
] = "memory",
2266 [CGROUP_CONTROLLER_DEVICES
] = "devices",
2267 [CGROUP_CONTROLLER_PIDS
] = "pids",
2268 [CGROUP_CONTROLLER_NET_CLS
] = "net_cls",
2271 DEFINE_STRING_TABLE_LOOKUP(cgroup_controller
, CGroupController
);