chiark / gitweb /
util-lib: make timestamp generation and parsing reversible (#3869)
[elogind.git] / src / basic / cgroup-util.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2010 Lennart Poettering
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <dirent.h>
21 #include <errno.h>
22 #include <ftw.h>
23 //#include <limits.h>
24 #include <signal.h>
25 //#include <stddef.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/stat.h>
29 //#include <sys/statfs.h>
30 #include <sys/types.h>
31 #include <unistd.h>
32
33 #include "alloc-util.h"
34 #include "cgroup-util.h"
35 //#include "def.h"
36 #include "dirent-util.h"
37 #include "extract-word.h"
38 #include "fd-util.h"
39 #include "fileio.h"
40 #include "formats-util.h"
41 #include "fs-util.h"
42 //#include "log.h"
43 #include "login-util.h"
44 #include "macro.h"
45 //#include "missing.h"
46 #include "mkdir.h"
47 #include "parse-util.h"
48 #include "path-util.h"
49 #include "proc-cmdline.h"
50 #include "process-util.h"
51 #include "set.h"
52 //#include "special.h"
53 #include "stat-util.h"
54 #include "stdio-util.h"
55 #include "string-table.h"
56 #include "string-util.h"
57 #include "unit-name.h"
58 #include "user-util.h"
59
60 int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
61         _cleanup_free_ char *fs = NULL;
62         FILE *f;
63         int r;
64
65         assert(_f);
66
67         r = cg_get_path(controller, path, "cgroup.procs", &fs);
68         if (r < 0)
69                 return r;
70
71         f = fopen(fs, "re");
72         if (!f)
73                 return -errno;
74
75         *_f = f;
76         return 0;
77 }
78
79 int cg_read_pid(FILE *f, pid_t *_pid) {
80         unsigned long ul;
81
82         /* Note that the cgroup.procs might contain duplicates! See
83          * cgroups.txt for details. */
84
85         assert(f);
86         assert(_pid);
87
88         errno = 0;
89         if (fscanf(f, "%lu", &ul) != 1) {
90
91                 if (feof(f))
92                         return 0;
93
94                 return errno > 0 ? -errno : -EIO;
95         }
96
97         if (ul <= 0)
98                 return -EIO;
99
100         *_pid = (pid_t) ul;
101         return 1;
102 }
103
104 int cg_read_event(const char *controller, const char *path, const char *event,
105                   char **val)
106 {
107         _cleanup_free_ char *events = NULL, *content = NULL;
108         char *p, *line;
109         int r;
110
111         r = cg_get_path(controller, path, "cgroup.events", &events);
112         if (r < 0)
113                 return r;
114
115         r = read_full_file(events, &content, NULL);
116         if (r < 0)
117                 return r;
118
119         p = content;
120         while ((line = strsep(&p, "\n"))) {
121                 char *key;
122
123                 key = strsep(&line, " ");
124                 if (!key || !line)
125                         return -EINVAL;
126
127                 if (strcmp(key, event))
128                         continue;
129
130                 *val = strdup(line);
131                 return 0;
132         }
133
134         return -ENOENT;
135 }
136
137 #if 0 /// UNNEEDED by elogind
138 bool cg_ns_supported(void) {
139         static thread_local int enabled = -1;
140
141         if (enabled >= 0)
142                 return enabled;
143
144         if (access("/proc/self/ns/cgroup", F_OK) == 0)
145                 enabled = 1;
146         else
147                 enabled = 0;
148
149         return enabled;
150 }
151 #endif //0
152
153 int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) {
154         _cleanup_free_ char *fs = NULL;
155         int r;
156         DIR *d;
157
158         assert(_d);
159
160         /* This is not recursive! */
161
162         r = cg_get_path(controller, path, NULL, &fs);
163         if (r < 0)
164                 return r;
165
166         d = opendir(fs);
167         if (!d)
168                 return -errno;
169
170         *_d = d;
171         return 0;
172 }
173
174 int cg_read_subgroup(DIR *d, char **fn) {
175         struct dirent *de;
176
177         assert(d);
178         assert(fn);
179
180         FOREACH_DIRENT_ALL(de, d, return -errno) {
181                 char *b;
182
183                 if (de->d_type != DT_DIR)
184                         continue;
185
186                 if (streq(de->d_name, ".") ||
187                     streq(de->d_name, ".."))
188                         continue;
189
190                 b = strdup(de->d_name);
191                 if (!b)
192                         return -ENOMEM;
193
194                 *fn = b;
195                 return 1;
196         }
197
198         return 0;
199 }
200
201 int cg_rmdir(const char *controller, const char *path) {
202         _cleanup_free_ char *p = NULL;
203         int r;
204
205         r = cg_get_path(controller, path, NULL, &p);
206         if (r < 0)
207                 return r;
208
209         r = rmdir(p);
210         if (r < 0 && errno != ENOENT)
211                 return -errno;
212
213         return 0;
214 }
215
216 int cg_kill(
217                 const char *controller,
218                 const char *path,
219                 int sig,
220                 CGroupFlags flags,
221                 Set *s,
222                 cg_kill_log_func_t log_kill,
223                 void *userdata) {
224
225         _cleanup_set_free_ Set *allocated_set = NULL;
226         bool done = false;
227         int r, ret = 0;
228         pid_t my_pid;
229
230         assert(sig >= 0);
231
232          /* Don't send SIGCONT twice. Also, SIGKILL always works even when process is suspended, hence don't send
233           * SIGCONT on SIGKILL. */
234         if (IN_SET(sig, SIGCONT, SIGKILL))
235                 flags &= ~CGROUP_SIGCONT;
236
237         /* This goes through the tasks list and kills them all. This
238          * is repeated until no further processes are added to the
239          * tasks list, to properly handle forking processes */
240
241         if (!s) {
242                 s = allocated_set = set_new(NULL);
243                 if (!s)
244                         return -ENOMEM;
245         }
246
247         my_pid = getpid();
248
249         do {
250                 _cleanup_fclose_ FILE *f = NULL;
251                 pid_t pid = 0;
252                 done = true;
253
254                 r = cg_enumerate_processes(controller, path, &f);
255                 if (r < 0) {
256                         if (ret >= 0 && r != -ENOENT)
257                                 return r;
258
259                         return ret;
260                 }
261
262                 while ((r = cg_read_pid(f, &pid)) > 0) {
263
264                         if ((flags & CGROUP_IGNORE_SELF) && pid == my_pid)
265                                 continue;
266
267                         if (set_get(s, PID_TO_PTR(pid)) == PID_TO_PTR(pid))
268                                 continue;
269
270                         if (log_kill)
271                                 log_kill(pid, sig, userdata);
272
273                         /* If we haven't killed this process yet, kill
274                          * it */
275                         if (kill(pid, sig) < 0) {
276                                 if (ret >= 0 && errno != ESRCH)
277                                         ret = -errno;
278                         } else {
279                                 if (flags & CGROUP_SIGCONT)
280                                         (void) kill(pid, SIGCONT);
281
282                                 if (ret == 0)
283                                         ret = 1;
284                         }
285
286                         done = false;
287
288                         r = set_put(s, PID_TO_PTR(pid));
289                         if (r < 0) {
290                                 if (ret >= 0)
291                                         return r;
292
293                                 return ret;
294                         }
295                 }
296
297                 if (r < 0) {
298                         if (ret >= 0)
299                                 return r;
300
301                         return ret;
302                 }
303
304                 /* To avoid racing against processes which fork
305                  * quicker than we can kill them we repeat this until
306                  * no new pids need to be killed. */
307
308         } while (!done);
309
310         return ret;
311 }
312
313 int cg_kill_recursive(
314                 const char *controller,
315                 const char *path,
316                 int sig,
317                 CGroupFlags flags,
318                 Set *s,
319                 cg_kill_log_func_t log_kill,
320                 void *userdata) {
321
322         _cleanup_set_free_ Set *allocated_set = NULL;
323         _cleanup_closedir_ DIR *d = NULL;
324         int r, ret;
325         char *fn;
326
327         assert(path);
328         assert(sig >= 0);
329
330         if (!s) {
331                 s = allocated_set = set_new(NULL);
332                 if (!s)
333                         return -ENOMEM;
334         }
335
336         ret = cg_kill(controller, path, sig, flags, s, log_kill, userdata);
337
338         r = cg_enumerate_subgroups(controller, path, &d);
339         if (r < 0) {
340                 if (ret >= 0 && r != -ENOENT)
341                         return r;
342
343                 return ret;
344         }
345
346         while ((r = cg_read_subgroup(d, &fn)) > 0) {
347                 _cleanup_free_ char *p = NULL;
348
349                 p = strjoin(path, "/", fn, NULL);
350                 free(fn);
351                 if (!p)
352                         return -ENOMEM;
353
354                 r = cg_kill_recursive(controller, p, sig, flags, s, log_kill, userdata);
355                 if (r != 0 && ret >= 0)
356                         ret = r;
357         }
358         if (ret >= 0 && r < 0)
359                 ret = r;
360
361         if (flags & CGROUP_REMOVE) {
362                 r = cg_rmdir(controller, path);
363                 if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY)
364                         return r;
365         }
366
367         return ret;
368 }
369
370 int cg_migrate(
371                 const char *cfrom,
372                 const char *pfrom,
373                 const char *cto,
374                 const char *pto,
375                 CGroupFlags flags) {
376
377         bool done = false;
378         _cleanup_set_free_ Set *s = NULL;
379         int r, ret = 0;
380         pid_t my_pid;
381
382         assert(cfrom);
383         assert(pfrom);
384         assert(cto);
385         assert(pto);
386
387         s = set_new(NULL);
388         if (!s)
389                 return -ENOMEM;
390
391         my_pid = getpid();
392
393         log_debug_elogind("Migrating \"%s\"/\"%s\" to \"%s\"/\"%s\" (%s)",
394                           cfrom, pfrom, cto, pto,
395                           (flags & CGROUP_IGNORE_SELF)
396                           ? "ignoring self" : "watching self");
397         do {
398                 _cleanup_fclose_ FILE *f = NULL;
399                 pid_t pid = 0;
400                 done = true;
401
402                 r = cg_enumerate_processes(cfrom, pfrom, &f);
403                 if (r < 0) {
404                         if (ret >= 0 && r != -ENOENT)
405                                 return r;
406
407                         return ret;
408                 }
409
410                 while ((r = cg_read_pid(f, &pid)) > 0) {
411
412                         /* This might do weird stuff if we aren't a
413                          * single-threaded program. However, we
414                          * luckily know we are not */
415                         if ((flags & CGROUP_IGNORE_SELF) && pid == my_pid)
416                                 continue;
417
418                         if (set_get(s, PID_TO_PTR(pid)) == PID_TO_PTR(pid))
419                                 continue;
420
421                         /* Ignore kernel threads. Since they can only
422                          * exist in the root cgroup, we only check for
423                          * them there. */
424                         if (cfrom &&
425                             (isempty(pfrom) || path_equal(pfrom, "/")) &&
426                             is_kernel_thread(pid) > 0)
427                                 continue;
428
429                         r = cg_attach(cto, pto, pid);
430                         if (r < 0) {
431                                 if (ret >= 0 && r != -ESRCH)
432                                         ret = r;
433                         } else if (ret == 0)
434                                 ret = 1;
435
436                         done = false;
437
438                         r = set_put(s, PID_TO_PTR(pid));
439                         if (r < 0) {
440                                 if (ret >= 0)
441                                         return r;
442
443                                 return ret;
444                         }
445                 }
446
447                 if (r < 0) {
448                         if (ret >= 0)
449                                 return r;
450
451                         return ret;
452                 }
453         } while (!done);
454
455         return ret;
456 }
457
458 int cg_migrate_recursive(
459                 const char *cfrom,
460                 const char *pfrom,
461                 const char *cto,
462                 const char *pto,
463                 CGroupFlags flags) {
464
465         _cleanup_closedir_ DIR *d = NULL;
466         int r, ret = 0;
467         char *fn;
468
469         assert(cfrom);
470         assert(pfrom);
471         assert(cto);
472         assert(pto);
473
474         ret = cg_migrate(cfrom, pfrom, cto, pto, flags);
475
476         r = cg_enumerate_subgroups(cfrom, pfrom, &d);
477         if (r < 0) {
478                 if (ret >= 0 && r != -ENOENT)
479                         return r;
480
481                 return ret;
482         }
483
484         while ((r = cg_read_subgroup(d, &fn)) > 0) {
485                 _cleanup_free_ char *p = NULL;
486
487                 p = strjoin(pfrom, "/", fn, NULL);
488                 free(fn);
489                 if (!p)
490                         return -ENOMEM;
491
492                 r = cg_migrate_recursive(cfrom, p, cto, pto, flags);
493                 if (r != 0 && ret >= 0)
494                         ret = r;
495         }
496
497         if (r < 0 && ret >= 0)
498                 ret = r;
499
500         if (flags & CGROUP_REMOVE) {
501                 r = cg_rmdir(cfrom, pfrom);
502                 if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY)
503                         return r;
504         }
505
506         return ret;
507 }
508
509 int cg_migrate_recursive_fallback(
510                 const char *cfrom,
511                 const char *pfrom,
512                 const char *cto,
513                 const char *pto,
514                 CGroupFlags flags) {
515
516         int r;
517
518         assert(cfrom);
519         assert(pfrom);
520         assert(cto);
521         assert(pto);
522
523         r = cg_migrate_recursive(cfrom, pfrom, cto, pto, flags);
524         if (r < 0) {
525                 char prefix[strlen(pto) + 1];
526
527                 /* This didn't work? Then let's try all prefixes of the destination */
528
529                 PATH_FOREACH_PREFIX(prefix, pto) {
530                         int q;
531
532                         q = cg_migrate_recursive(cfrom, pfrom, cto, prefix, flags);
533                         if (q >= 0)
534                                 return q;
535                 }
536         }
537
538         return r;
539 }
540
541 static const char *controller_to_dirname(const char *controller) {
542         const char *e;
543
544         assert(controller);
545
546         /* Converts a controller name to the directory name below
547          * /sys/fs/cgroup/ we want to mount it to. Effectively, this
548          * just cuts off the name= prefixed used for named
549          * hierarchies, if it is specified. */
550
551         e = startswith(controller, "name=");
552         if (e)
553                 return e;
554
555         return controller;
556 }
557
558 static int join_path_legacy(const char *controller, const char *path, const char *suffix, char **fs) {
559         const char *dn;
560         char *t = NULL;
561
562         assert(fs);
563         assert(controller);
564
565         dn = controller_to_dirname(controller);
566
567         if (isempty(path) && isempty(suffix))
568                 t = strappend("/sys/fs/cgroup/", dn);
569         else if (isempty(path))
570                 t = strjoin("/sys/fs/cgroup/", dn, "/", suffix, NULL);
571         else if (isempty(suffix))
572                 t = strjoin("/sys/fs/cgroup/", dn, "/", path, NULL);
573         else
574                 t = strjoin("/sys/fs/cgroup/", dn, "/", path, "/", suffix, NULL);
575         if (!t)
576                 return -ENOMEM;
577
578         *fs = t;
579         return 0;
580 }
581
582 static int join_path_unified(const char *path, const char *suffix, char **fs) {
583         char *t;
584
585         assert(fs);
586
587         if (isempty(path) && isempty(suffix))
588                 t = strdup("/sys/fs/cgroup");
589         else if (isempty(path))
590                 t = strappend("/sys/fs/cgroup/", suffix);
591         else if (isempty(suffix))
592                 t = strappend("/sys/fs/cgroup/", path);
593         else
594                 t = strjoin("/sys/fs/cgroup/", path, "/", suffix, NULL);
595         if (!t)
596                 return -ENOMEM;
597
598         *fs = t;
599         return 0;
600 }
601
602 int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) {
603         int unified, r;
604
605         assert(fs);
606
607         if (!controller) {
608                 char *t;
609
610                 /* If no controller is specified, we return the path
611                  * *below* the controllers, without any prefix. */
612
613                 if (!path && !suffix)
614                         return -EINVAL;
615
616                 if (!suffix)
617                         t = strdup(path);
618                 else if (!path)
619                         t = strdup(suffix);
620                 else
621                         t = strjoin(path, "/", suffix, NULL);
622                 if (!t)
623                         return -ENOMEM;
624
625                 *fs = path_kill_slashes(t);
626                 return 0;
627         }
628
629         if (!cg_controller_is_valid(controller))
630                 return -EINVAL;
631
632         unified = cg_unified();
633         if (unified < 0)
634                 return unified;
635
636         if (unified > 0)
637                 r = join_path_unified(path, suffix, fs);
638         else
639                 r = join_path_legacy(controller, path, suffix, fs);
640         if (r < 0)
641                 return r;
642
643         path_kill_slashes(*fs);
644         return 0;
645 }
646
647 static int controller_is_accessible(const char *controller) {
648         int unified;
649
650         assert(controller);
651
652         /* Checks whether a specific controller is accessible,
653          * i.e. its hierarchy mounted. In the unified hierarchy all
654          * controllers are considered accessible, except for the named
655          * hierarchies */
656
657         if (!cg_controller_is_valid(controller))
658                 return -EINVAL;
659
660         unified = cg_unified();
661         if (unified < 0)
662                 return unified;
663         if (unified > 0) {
664                 /* We don't support named hierarchies if we are using
665                  * the unified hierarchy. */
666
667                 if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
668                         return 0;
669
670                 if (startswith(controller, "name="))
671                         return -EOPNOTSUPP;
672
673         } else {
674                 const char *cc, *dn;
675
676                 dn = controller_to_dirname(controller);
677                 cc = strjoina("/sys/fs/cgroup/", dn);
678
679                 if (laccess(cc, F_OK) < 0)
680                         return -errno;
681         }
682
683         return 0;
684 }
685
686 int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) {
687         int r;
688
689         assert(controller);
690         assert(fs);
691
692         /* Check if the specified controller is actually accessible */
693         r = controller_is_accessible(controller);
694         if (r < 0)
695                 return r;
696
697         return cg_get_path(controller, path, suffix, fs);
698 }
699
700 static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
701         assert(path);
702         assert(sb);
703         assert(ftwbuf);
704
705         if (typeflag != FTW_DP)
706                 return 0;
707
708         if (ftwbuf->level < 1)
709                 return 0;
710
711         (void) rmdir(path);
712         return 0;
713 }
714
715 int cg_trim(const char *controller, const char *path, bool delete_root) {
716         _cleanup_free_ char *fs = NULL;
717         int r = 0;
718
719         assert(path);
720
721         r = cg_get_path(controller, path, NULL, &fs);
722         if (r < 0)
723                 return r;
724
725         errno = 0;
726         if (nftw(fs, trim_cb, 64, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) != 0) {
727                 if (errno == ENOENT)
728                         r = 0;
729                 else if (errno > 0)
730                         r = -errno;
731                 else
732                         r = -EIO;
733         }
734
735         if (delete_root) {
736                 if (rmdir(fs) < 0 && errno != ENOENT)
737                         return -errno;
738         }
739
740         return r;
741 }
742
743 int cg_create(const char *controller, const char *path) {
744         _cleanup_free_ char *fs = NULL;
745         int r;
746
747         r = cg_get_path_and_check(controller, path, NULL, &fs);
748         if (r < 0)
749                 return r;
750
751         r = mkdir_parents(fs, 0755);
752         if (r < 0)
753                 return r;
754
755         if (mkdir(fs, 0755) < 0) {
756
757                 if (errno == EEXIST)
758                         return 0;
759
760                 return -errno;
761         }
762
763         return 1;
764 }
765
766 int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
767         int r, q;
768
769         assert(pid >= 0);
770
771         r = cg_create(controller, path);
772         if (r < 0)
773                 return r;
774
775         q = cg_attach(controller, path, pid);
776         if (q < 0)
777                 return q;
778
779         /* This does not remove the cgroup on failure */
780         return r;
781 }
782
783 int cg_attach(const char *controller, const char *path, pid_t pid) {
784         _cleanup_free_ char *fs = NULL;
785         char c[DECIMAL_STR_MAX(pid_t) + 2];
786         int r;
787
788         assert(path);
789         assert(pid >= 0);
790
791         r = cg_get_path_and_check(controller, path, "cgroup.procs", &fs);
792         if (r < 0)
793                 return r;
794
795         if (pid == 0)
796                 pid = getpid();
797
798         xsprintf(c, PID_FMT "\n", pid);
799
800         return write_string_file(fs, c, 0);
801 }
802
803 int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
804         int r;
805
806         assert(controller);
807         assert(path);
808         assert(pid >= 0);
809
810         r = cg_attach(controller, path, pid);
811         if (r < 0) {
812                 char prefix[strlen(path) + 1];
813
814                 /* This didn't work? Then let's try all prefixes of
815                  * the destination */
816
817                 PATH_FOREACH_PREFIX(prefix, path) {
818                         int q;
819
820                         q = cg_attach(controller, prefix, pid);
821                         if (q >= 0)
822                                 return q;
823                 }
824         }
825
826         return r;
827 }
828
829 #if 0 /// UNNEEDED by elogind
830 int cg_set_group_access(
831                 const char *controller,
832                 const char *path,
833                 mode_t mode,
834                 uid_t uid,
835                 gid_t gid) {
836
837         _cleanup_free_ char *fs = NULL;
838         int r;
839
840         if (mode == MODE_INVALID && uid == UID_INVALID && gid == GID_INVALID)
841                 return 0;
842
843         if (mode != MODE_INVALID)
844                 mode &= 0777;
845
846         r = cg_get_path(controller, path, NULL, &fs);
847         if (r < 0)
848                 return r;
849
850         return chmod_and_chown(fs, mode, uid, gid);
851 }
852
853 int cg_set_task_access(
854                 const char *controller,
855                 const char *path,
856                 mode_t mode,
857                 uid_t uid,
858                 gid_t gid) {
859
860         _cleanup_free_ char *fs = NULL, *procs = NULL;
861         int r, unified;
862
863         assert(path);
864
865         if (mode == MODE_INVALID && uid == UID_INVALID && gid == GID_INVALID)
866                 return 0;
867
868         if (mode != MODE_INVALID)
869                 mode &= 0666;
870
871         r = cg_get_path(controller, path, "cgroup.procs", &fs);
872         if (r < 0)
873                 return r;
874
875         r = chmod_and_chown(fs, mode, uid, gid);
876         if (r < 0)
877                 return r;
878
879         unified = cg_unified();
880         if (unified < 0)
881                 return unified;
882         if (unified)
883                 return 0;
884
885         /* Compatibility, Always keep values for "tasks" in sync with
886          * "cgroup.procs" */
887         if (cg_get_path(controller, path, "tasks", &procs) >= 0)
888                 (void) chmod_and_chown(procs, mode, uid, gid);
889
890         return 0;
891 }
892 #endif // 0
893
894 int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
895         _cleanup_fclose_ FILE *f = NULL;
896         char line[LINE_MAX];
897         const char *fs;
898         size_t cs = 0;
899         int unified;
900
901         assert(path);
902         assert(pid >= 0);
903
904         unified = cg_unified();
905         if (unified < 0)
906                 return unified;
907         if (unified == 0) {
908                 if (controller) {
909                         if (!cg_controller_is_valid(controller))
910                                 return -EINVAL;
911                 } else
912                         controller = SYSTEMD_CGROUP_CONTROLLER;
913
914                 cs = strlen(controller);
915         }
916
917         fs = procfs_file_alloca(pid, "cgroup");
918         log_debug_elogind("Searching for PID %u in \"%s\" (controller \"%s\")",
919                           pid, fs, controller);
920         f = fopen(fs, "re");
921         if (!f)
922                 return errno == ENOENT ? -ESRCH : -errno;
923
924         FOREACH_LINE(line, f, return -errno) {
925                 char *e, *p;
926
927                 truncate_nl(line);
928
929                 if (unified) {
930                         e = startswith(line, "0:");
931                         if (!e)
932                                 continue;
933
934                         e = strchr(e, ':');
935                         if (!e)
936                                 continue;
937                 } else {
938                         char *l;
939                         size_t k;
940                         const char *word, *state;
941                         bool found = false;
942
943                         l = strchr(line, ':');
944                         if (!l)
945                                 continue;
946
947                         l++;
948                         e = strchr(l, ':');
949                         if (!e)
950                                 continue;
951
952                         *e = 0;
953                         FOREACH_WORD_SEPARATOR(word, k, l, ",", state) {
954                                 if (k == cs && memcmp(word, controller, cs) == 0) {
955                                         found = true;
956                                         break;
957                                 }
958                         }
959
960                         if (!found)
961                                 continue;
962                 }
963
964                 log_debug_elogind("Found %s:%s", line, e+1);
965                 p = strdup(e + 1);
966                 if (!p)
967                         return -ENOMEM;
968
969                 *path = p;
970                 return 0;
971         }
972
973         return -ENODATA;
974 }
975
976 int cg_install_release_agent(const char *controller, const char *agent) {
977         _cleanup_free_ char *fs = NULL, *contents = NULL;
978         const char *sc;
979         int r, unified;
980
981         assert(agent);
982
983         unified = cg_unified();
984         if (unified < 0)
985                 return unified;
986         if (unified) /* doesn't apply to unified hierarchy */
987                 return -EOPNOTSUPP;
988
989         r = cg_get_path(controller, NULL, "release_agent", &fs);
990         if (r < 0)
991                 return r;
992
993         r = read_one_line_file(fs, &contents);
994         if (r < 0)
995                 return r;
996
997         sc = strstrip(contents);
998         if (isempty(sc)) {
999                 r = write_string_file(fs, agent, 0);
1000                 if (r < 0)
1001                         return r;
1002         } else if (!path_equal(sc, agent))
1003                 return -EEXIST;
1004
1005         fs = mfree(fs);
1006         r = cg_get_path(controller, NULL, "notify_on_release", &fs);
1007         if (r < 0)
1008                 return r;
1009
1010         contents = mfree(contents);
1011         r = read_one_line_file(fs, &contents);
1012         if (r < 0)
1013                 return r;
1014
1015         sc = strstrip(contents);
1016         if (streq(sc, "0")) {
1017                 r = write_string_file(fs, "1", 0);
1018                 if (r < 0)
1019                         return r;
1020
1021                 return 1;
1022         }
1023
1024         if (!streq(sc, "1"))
1025                 return -EIO;
1026
1027         return 0;
1028 }
1029
1030 int cg_uninstall_release_agent(const char *controller) {
1031         _cleanup_free_ char *fs = NULL;
1032         int r, unified;
1033
1034         unified = cg_unified();
1035         if (unified < 0)
1036                 return unified;
1037         if (unified) /* Doesn't apply to unified hierarchy */
1038                 return -EOPNOTSUPP;
1039
1040         r = cg_get_path(controller, NULL, "notify_on_release", &fs);
1041         if (r < 0)
1042                 return r;
1043
1044         r = write_string_file(fs, "0", 0);
1045         if (r < 0)
1046                 return r;
1047
1048         fs = mfree(fs);
1049
1050         r = cg_get_path(controller, NULL, "release_agent", &fs);
1051         if (r < 0)
1052                 return r;
1053
1054         r = write_string_file(fs, "", 0);
1055         if (r < 0)
1056                 return r;
1057
1058         return 0;
1059 }
1060
1061 int cg_is_empty(const char *controller, const char *path) {
1062         _cleanup_fclose_ FILE *f = NULL;
1063         pid_t pid;
1064         int r;
1065
1066         assert(path);
1067
1068         r = cg_enumerate_processes(controller, path, &f);
1069         if (r == -ENOENT)
1070                 return 1;
1071         if (r < 0)
1072                 return r;
1073
1074         r = cg_read_pid(f, &pid);
1075         if (r < 0)
1076                 return r;
1077
1078         return r == 0;
1079 }
1080
1081 int cg_is_empty_recursive(const char *controller, const char *path) {
1082         int unified, r;
1083
1084         assert(path);
1085
1086         /* The root cgroup is always populated */
1087         if (controller && (isempty(path) || path_equal(path, "/")))
1088                 return false;
1089
1090         unified = cg_unified();
1091         if (unified < 0)
1092                 return unified;
1093
1094         if (unified > 0) {
1095                 _cleanup_free_ char *t = NULL;
1096
1097                 /* On the unified hierarchy we can check empty state
1098                  * via the "populated" attribute of "cgroup.events". */
1099
1100                 r = cg_read_event(controller, path, "populated", &t);
1101                 if (r < 0)
1102                         return r;
1103
1104                 return streq(t, "0");
1105         } else {
1106                 _cleanup_closedir_ DIR *d = NULL;
1107                 char *fn;
1108
1109                 r = cg_is_empty(controller, path);
1110                 if (r <= 0)
1111                         return r;
1112
1113                 r = cg_enumerate_subgroups(controller, path, &d);
1114                 if (r == -ENOENT)
1115                         return 1;
1116                 if (r < 0)
1117                         return r;
1118
1119                 while ((r = cg_read_subgroup(d, &fn)) > 0) {
1120                         _cleanup_free_ char *p = NULL;
1121
1122                         p = strjoin(path, "/", fn, NULL);
1123                         free(fn);
1124                         if (!p)
1125                                 return -ENOMEM;
1126
1127                         r = cg_is_empty_recursive(controller, p);
1128                         if (r <= 0)
1129                                 return r;
1130                 }
1131                 if (r < 0)
1132                         return r;
1133
1134                 return true;
1135         }
1136 }
1137
1138 int cg_split_spec(const char *spec, char **controller, char **path) {
1139         char *t = NULL, *u = NULL;
1140         const char *e;
1141
1142         assert(spec);
1143
1144         if (*spec == '/') {
1145                 if (!path_is_safe(spec))
1146                         return -EINVAL;
1147
1148                 if (path) {
1149                         t = strdup(spec);
1150                         if (!t)
1151                                 return -ENOMEM;
1152
1153                         *path = path_kill_slashes(t);
1154                 }
1155
1156                 if (controller)
1157                         *controller = NULL;
1158
1159                 return 0;
1160         }
1161
1162         e = strchr(spec, ':');
1163         if (!e) {
1164                 if (!cg_controller_is_valid(spec))
1165                         return -EINVAL;
1166
1167                 if (controller) {
1168                         t = strdup(spec);
1169                         if (!t)
1170                                 return -ENOMEM;
1171
1172                         *controller = t;
1173                 }
1174
1175                 if (path)
1176                         *path = NULL;
1177
1178                 return 0;
1179         }
1180
1181         t = strndup(spec, e-spec);
1182         if (!t)
1183                 return -ENOMEM;
1184         if (!cg_controller_is_valid(t)) {
1185                 free(t);
1186                 return -EINVAL;
1187         }
1188
1189         if (isempty(e+1))
1190                 u = NULL;
1191         else {
1192                 u = strdup(e+1);
1193                 if (!u) {
1194                         free(t);
1195                         return -ENOMEM;
1196                 }
1197
1198                 if (!path_is_safe(u) ||
1199                     !path_is_absolute(u)) {
1200                         free(t);
1201                         free(u);
1202                         return -EINVAL;
1203                 }
1204
1205                 path_kill_slashes(u);
1206         }
1207
1208         if (controller)
1209                 *controller = t;
1210         else
1211                 free(t);
1212
1213         if (path)
1214                 *path = u;
1215         else
1216                 free(u);
1217
1218         return 0;
1219 }
1220
1221 int cg_mangle_path(const char *path, char **result) {
1222         _cleanup_free_ char *c = NULL, *p = NULL;
1223         char *t;
1224         int r;
1225
1226         assert(path);
1227         assert(result);
1228
1229         /* First, check if it already is a filesystem path */
1230         if (path_startswith(path, "/sys/fs/cgroup")) {
1231
1232                 t = strdup(path);
1233                 if (!t)
1234                         return -ENOMEM;
1235
1236                 *result = path_kill_slashes(t);
1237                 return 0;
1238         }
1239
1240         /* Otherwise, treat it as cg spec */
1241         r = cg_split_spec(path, &c, &p);
1242         if (r < 0)
1243                 return r;
1244
1245         return cg_get_path(c ?: SYSTEMD_CGROUP_CONTROLLER, p ?: "/", NULL, result);
1246 }
1247
1248 int cg_get_root_path(char **path) {
1249 #if 0 /// elogind does not support systemd scopes and slices
1250         char *p, *e;
1251         int r;
1252
1253         assert(path);
1254
1255         r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &p);
1256         if (r < 0)
1257                 return r;
1258
1259         e = endswith(p, "/" SPECIAL_INIT_SCOPE);
1260         if (!e)
1261                 e = endswith(p, "/" SPECIAL_SYSTEM_SLICE); /* legacy */
1262         if (!e)
1263                 e = endswith(p, "/system"); /* even more legacy */
1264         if (e)
1265                 *e = 0;
1266
1267         *path = p;
1268         return 0;
1269 #else
1270         assert(path);
1271         return cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, path);
1272 #endif // 0
1273 }
1274
1275 int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
1276         _cleanup_free_ char *rt = NULL;
1277         char *p;
1278         int r;
1279
1280         assert(cgroup);
1281         assert(shifted);
1282
1283         if (!root) {
1284                 /* If the root was specified let's use that, otherwise
1285                  * let's determine it from PID 1 */
1286
1287                 r = cg_get_root_path(&rt);
1288                 if (r < 0)
1289                         return r;
1290
1291                 root = rt;
1292                 log_debug_elogind("Determined root path: \"%s\"", root);
1293         }
1294
1295         p = path_startswith(cgroup, root);
1296         if (p && p[0] && (p > cgroup))
1297                 *shifted = p - 1;
1298         else
1299                 *shifted = cgroup;
1300
1301         return 0;
1302 }
1303
1304 int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
1305         _cleanup_free_ char *raw = NULL;
1306         const char *c;
1307         int r;
1308
1309         assert(pid >= 0);
1310         assert(cgroup);
1311
1312         r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &raw);
1313         if (r < 0)
1314                 return r;
1315
1316         log_debug_elogind("Shifting path: \"%s\" (PID %u, root: \"%s\")",
1317                           raw, pid, root ? root : "NULL");
1318         r = cg_shift_path(raw, root, &c);
1319         if (r < 0)
1320                 return r;
1321
1322         if (c == raw) {
1323                 *cgroup = raw;
1324                 raw = NULL;
1325         } else {
1326                 char *n;
1327
1328                 n = strdup(c);
1329                 if (!n)
1330                         return -ENOMEM;
1331
1332                 *cgroup = n;
1333         }
1334         log_debug_elogind("Resulting cgroup:\"%s\"", *cgroup);
1335
1336         return 0;
1337 }
1338
1339 #if 0 /// UNNEEDED by elogind
1340 int cg_path_decode_unit(const char *cgroup, char **unit) {
1341         char *c, *s;
1342         size_t n;
1343
1344         assert(cgroup);
1345         assert(unit);
1346
1347         n = strcspn(cgroup, "/");
1348         if (n < 3)
1349                 return -ENXIO;
1350
1351         c = strndupa(cgroup, n);
1352         c = cg_unescape(c);
1353
1354         if (!unit_name_is_valid(c, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
1355                 return -ENXIO;
1356
1357         s = strdup(c);
1358         if (!s)
1359                 return -ENOMEM;
1360
1361         *unit = s;
1362         return 0;
1363 }
1364
1365 static bool valid_slice_name(const char *p, size_t n) {
1366
1367         if (!p)
1368                 return false;
1369
1370         if (n < strlen("x.slice"))
1371                 return false;
1372
1373         if (memcmp(p + n - 6, ".slice", 6) == 0) {
1374                 char buf[n+1], *c;
1375
1376                 memcpy(buf, p, n);
1377                 buf[n] = 0;
1378
1379                 c = cg_unescape(buf);
1380
1381                 return unit_name_is_valid(c, UNIT_NAME_PLAIN);
1382         }
1383
1384         return false;
1385 }
1386
1387 static const char *skip_slices(const char *p) {
1388         assert(p);
1389
1390         /* Skips over all slice assignments */
1391
1392         for (;;) {
1393                 size_t n;
1394
1395                 p += strspn(p, "/");
1396
1397                 n = strcspn(p, "/");
1398                 if (!valid_slice_name(p, n))
1399                         return p;
1400
1401                 p += n;
1402         }
1403 }
1404
1405 int cg_path_get_unit(const char *path, char **ret) {
1406         const char *e;
1407         char *unit;
1408         int r;
1409
1410         assert(path);
1411         assert(ret);
1412
1413         e = skip_slices(path);
1414
1415         r = cg_path_decode_unit(e, &unit);
1416         if (r < 0)
1417                 return r;
1418
1419         /* We skipped over the slices, don't accept any now */
1420         if (endswith(unit, ".slice")) {
1421                 free(unit);
1422                 return -ENXIO;
1423         }
1424
1425         *ret = unit;
1426         return 0;
1427 }
1428
1429 int cg_pid_get_unit(pid_t pid, char **unit) {
1430         _cleanup_free_ char *cgroup = NULL;
1431         int r;
1432
1433         assert(unit);
1434
1435         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1436         if (r < 0)
1437                 return r;
1438
1439         return cg_path_get_unit(cgroup, unit);
1440 }
1441
1442 /**
1443  * Skip session-*.scope, but require it to be there.
1444  */
1445 static const char *skip_session(const char *p) {
1446         size_t n;
1447
1448         if (isempty(p))
1449                 return NULL;
1450
1451         p += strspn(p, "/");
1452
1453         n = strcspn(p, "/");
1454         if (n < strlen("session-x.scope"))
1455                 return NULL;
1456
1457         if (memcmp(p, "session-", 8) == 0 && memcmp(p + n - 6, ".scope", 6) == 0) {
1458                 char buf[n - 8 - 6 + 1];
1459
1460                 memcpy(buf, p + 8, n - 8 - 6);
1461                 buf[n - 8 - 6] = 0;
1462
1463                 /* Note that session scopes never need unescaping,
1464                  * since they cannot conflict with the kernel's own
1465                  * names, hence we don't need to call cg_unescape()
1466                  * here. */
1467
1468                 if (!session_id_valid(buf))
1469                         return false;
1470
1471                 p += n;
1472                 p += strspn(p, "/");
1473                 return p;
1474         }
1475
1476         return NULL;
1477 }
1478
1479 /**
1480  * Skip user@*.service, but require it to be there.
1481  */
1482 static const char *skip_user_manager(const char *p) {
1483         size_t n;
1484
1485         if (isempty(p))
1486                 return NULL;
1487
1488         p += strspn(p, "/");
1489
1490         n = strcspn(p, "/");
1491         if (n < strlen("user@x.service"))
1492                 return NULL;
1493
1494         if (memcmp(p, "user@", 5) == 0 && memcmp(p + n - 8, ".service", 8) == 0) {
1495                 char buf[n - 5 - 8 + 1];
1496
1497                 memcpy(buf, p + 5, n - 5 - 8);
1498                 buf[n - 5 - 8] = 0;
1499
1500                 /* Note that user manager services never need unescaping,
1501                  * since they cannot conflict with the kernel's own
1502                  * names, hence we don't need to call cg_unescape()
1503                  * here. */
1504
1505                 if (parse_uid(buf, NULL) < 0)
1506                         return NULL;
1507
1508                 p += n;
1509                 p += strspn(p, "/");
1510
1511                 return p;
1512         }
1513
1514         return NULL;
1515 }
1516
1517 static const char *skip_user_prefix(const char *path) {
1518         const char *e, *t;
1519
1520         assert(path);
1521
1522         /* Skip slices, if there are any */
1523         e = skip_slices(path);
1524
1525         /* Skip the user manager, if it's in the path now... */
1526         t = skip_user_manager(e);
1527         if (t)
1528                 return t;
1529
1530         /* Alternatively skip the user session if it is in the path... */
1531         return skip_session(e);
1532 }
1533
1534 int cg_path_get_user_unit(const char *path, char **ret) {
1535         const char *t;
1536
1537         assert(path);
1538         assert(ret);
1539
1540         t = skip_user_prefix(path);
1541         if (!t)
1542                 return -ENXIO;
1543
1544         /* And from here on it looks pretty much the same as for a
1545          * system unit, hence let's use the same parser from here
1546          * on. */
1547         return cg_path_get_unit(t, ret);
1548 }
1549
1550 int cg_pid_get_user_unit(pid_t pid, char **unit) {
1551         _cleanup_free_ char *cgroup = NULL;
1552         int r;
1553
1554         assert(unit);
1555
1556         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1557         if (r < 0)
1558                 return r;
1559
1560         return cg_path_get_user_unit(cgroup, unit);
1561 }
1562
1563 int cg_path_get_machine_name(const char *path, char **machine) {
1564         _cleanup_free_ char *u = NULL;
1565         const char *sl;
1566         int r;
1567
1568         r = cg_path_get_unit(path, &u);
1569         if (r < 0)
1570                 return r;
1571
1572         sl = strjoina("/run/systemd/machines/unit:", u);
1573         return readlink_malloc(sl, machine);
1574 }
1575
1576 int cg_pid_get_machine_name(pid_t pid, char **machine) {
1577         _cleanup_free_ char *cgroup = NULL;
1578         int r;
1579
1580         assert(machine);
1581
1582         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1583         if (r < 0)
1584                 return r;
1585
1586         return cg_path_get_machine_name(cgroup, machine);
1587 }
1588 #endif // 0
1589
1590 int cg_path_get_session(const char *path, char **session) {
1591 #if 0 /// UNNEEDED by elogind
1592         _cleanup_free_ char *unit = NULL;
1593         char *start, *end;
1594         int r;
1595
1596         assert(path);
1597
1598         r = cg_path_get_unit(path, &unit);
1599         if (r < 0)
1600                 return r;
1601
1602         start = startswith(unit, "session-");
1603         if (!start)
1604                 return -ENXIO;
1605         end = endswith(start, ".scope");
1606         if (!end)
1607                 return -ENXIO;
1608
1609         *end = 0;
1610         if (!session_id_valid(start))
1611                 return -ENXIO;
1612 #else
1613         /* Elogind uses a flat hierarchy, just "/SESSION".  The only
1614            wrinkle is that SESSION might be escaped.  */
1615         const char *e, *n, *start;
1616
1617         assert(path);
1618         log_debug_elogind("path is \"%s\"", path);
1619         assert(path[0] == '/');
1620
1621         e = path + 1;
1622         n = strchrnul(e, '/');
1623         if (e == n)
1624                 return -ENOENT;
1625
1626         start = strndupa(e, n - e);
1627         start = cg_unescape(start);
1628
1629         if (!start[0])
1630                 return -ENOENT;
1631 #endif // 0
1632
1633         if (session) {
1634                 char *rr;
1635
1636                 log_debug_elogind("found session: \"%s\"", start);
1637                 rr = strdup(start);
1638                 if (!rr)
1639                         return -ENOMEM;
1640
1641                 *session = rr;
1642         }
1643
1644         return 0;
1645 }
1646
1647 int cg_pid_get_session(pid_t pid, char **session) {
1648         _cleanup_free_ char *cgroup = NULL;
1649         int r;
1650
1651         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1652         if (r < 0)
1653                 return r;
1654
1655         return cg_path_get_session(cgroup, session);
1656 }
1657
1658 #if 0 /// UNNEEDED by elogind
1659 int cg_path_get_owner_uid(const char *path, uid_t *uid) {
1660         _cleanup_free_ char *slice = NULL;
1661         char *start, *end;
1662         int r;
1663
1664         assert(path);
1665
1666         r = cg_path_get_slice(path, &slice);
1667         if (r < 0)
1668                 return r;
1669
1670         start = startswith(slice, "user-");
1671         if (!start)
1672                 return -ENXIO;
1673         end = endswith(start, ".slice");
1674         if (!end)
1675                 return -ENXIO;
1676
1677         *end = 0;
1678         if (parse_uid(start, uid) < 0)
1679                 return -ENXIO;
1680
1681         return 0;
1682 }
1683
1684 int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) {
1685         _cleanup_free_ char *cgroup = NULL;
1686         int r;
1687
1688         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1689         if (r < 0)
1690                 return r;
1691
1692         return cg_path_get_owner_uid(cgroup, uid);
1693 }
1694
1695 int cg_path_get_slice(const char *p, char **slice) {
1696         const char *e = NULL;
1697
1698         assert(p);
1699         assert(slice);
1700
1701         /* Finds the right-most slice unit from the beginning, but
1702          * stops before we come to the first non-slice unit. */
1703
1704         for (;;) {
1705                 size_t n;
1706
1707                 p += strspn(p, "/");
1708
1709                 n = strcspn(p, "/");
1710                 if (!valid_slice_name(p, n)) {
1711
1712                         if (!e) {
1713                                 char *s;
1714
1715                                 s = strdup("-.slice");
1716                                 if (!s)
1717                                         return -ENOMEM;
1718
1719                                 *slice = s;
1720                                 return 0;
1721                         }
1722
1723                         return cg_path_decode_unit(e, slice);
1724                 }
1725
1726                 e = p;
1727                 p += n;
1728         }
1729 }
1730
1731 int cg_pid_get_slice(pid_t pid, char **slice) {
1732         _cleanup_free_ char *cgroup = NULL;
1733         int r;
1734
1735         assert(slice);
1736
1737         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1738         if (r < 0)
1739                 return r;
1740
1741         return cg_path_get_slice(cgroup, slice);
1742 }
1743
1744 int cg_path_get_user_slice(const char *p, char **slice) {
1745         const char *t;
1746         assert(p);
1747         assert(slice);
1748
1749         t = skip_user_prefix(p);
1750         if (!t)
1751                 return -ENXIO;
1752
1753         /* And now it looks pretty much the same as for a system
1754          * slice, so let's just use the same parser from here on. */
1755         return cg_path_get_slice(t, slice);
1756 }
1757
1758 int cg_pid_get_user_slice(pid_t pid, char **slice) {
1759         _cleanup_free_ char *cgroup = NULL;
1760         int r;
1761
1762         assert(slice);
1763
1764         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1765         if (r < 0)
1766                 return r;
1767
1768         return cg_path_get_user_slice(cgroup, slice);
1769 }
1770 #endif // 0
1771
1772 char *cg_escape(const char *p) {
1773         bool need_prefix = false;
1774
1775         /* This implements very minimal escaping for names to be used
1776          * as file names in the cgroup tree: any name which might
1777          * conflict with a kernel name or is prefixed with '_' is
1778          * prefixed with a '_'. That way, when reading cgroup names it
1779          * is sufficient to remove a single prefixing underscore if
1780          * there is one. */
1781
1782         /* The return value of this function (unlike cg_unescape())
1783          * needs free()! */
1784
1785         if (p[0] == 0 ||
1786             p[0] == '_' ||
1787             p[0] == '.' ||
1788             streq(p, "notify_on_release") ||
1789             streq(p, "release_agent") ||
1790             streq(p, "tasks") ||
1791             startswith(p, "cgroup."))
1792                 need_prefix = true;
1793         else {
1794                 const char *dot;
1795
1796                 dot = strrchr(p, '.');
1797                 if (dot) {
1798                         CGroupController c;
1799                         size_t l = dot - p;
1800
1801                         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
1802                                 const char *n;
1803
1804                                 n = cgroup_controller_to_string(c);
1805
1806                                 if (l != strlen(n))
1807                                         continue;
1808
1809                                 if (memcmp(p, n, l) != 0)
1810                                         continue;
1811
1812                                 need_prefix = true;
1813                                 break;
1814                         }
1815                 }
1816         }
1817
1818         if (need_prefix)
1819                 return strappend("_", p);
1820
1821         return strdup(p);
1822 }
1823
1824 char *cg_unescape(const char *p) {
1825         assert(p);
1826
1827         /* The return value of this function (unlike cg_escape())
1828          * doesn't need free()! */
1829
1830         if (p[0] == '_')
1831                 return (char*) p+1;
1832
1833         return (char*) p;
1834 }
1835
1836 #define CONTROLLER_VALID                        \
1837         DIGITS LETTERS                          \
1838         "_"
1839
1840 bool cg_controller_is_valid(const char *p) {
1841         const char *t, *s;
1842
1843         if (!p)
1844                 return false;
1845
1846         s = startswith(p, "name=");
1847         if (s)
1848                 p = s;
1849
1850         if (*p == 0 || *p == '_')
1851                 return false;
1852
1853         for (t = p; *t; t++)
1854                 if (!strchr(CONTROLLER_VALID, *t))
1855                         return false;
1856
1857         if (t - p > FILENAME_MAX)
1858                 return false;
1859
1860         return true;
1861 }
1862
1863 #if 0 /// UNNEEDED by elogind
1864 int cg_slice_to_path(const char *unit, char **ret) {
1865         _cleanup_free_ char *p = NULL, *s = NULL, *e = NULL;
1866         const char *dash;
1867         int r;
1868
1869         assert(unit);
1870         assert(ret);
1871
1872         if (streq(unit, "-.slice")) {
1873                 char *x;
1874
1875                 x = strdup("");
1876                 if (!x)
1877                         return -ENOMEM;
1878                 *ret = x;
1879                 return 0;
1880         }
1881
1882         if (!unit_name_is_valid(unit, UNIT_NAME_PLAIN))
1883                 return -EINVAL;
1884
1885         if (!endswith(unit, ".slice"))
1886                 return -EINVAL;
1887
1888         r = unit_name_to_prefix(unit, &p);
1889         if (r < 0)
1890                 return r;
1891
1892         dash = strchr(p, '-');
1893
1894         /* Don't allow initial dashes */
1895         if (dash == p)
1896                 return -EINVAL;
1897
1898         while (dash) {
1899                 _cleanup_free_ char *escaped = NULL;
1900                 char n[dash - p + sizeof(".slice")];
1901
1902                 /* Don't allow trailing or double dashes */
1903                 if (dash[1] == 0 || dash[1] == '-')
1904                         return -EINVAL;
1905
1906                 strcpy(stpncpy(n, p, dash - p), ".slice");
1907                 if (!unit_name_is_valid(n, UNIT_NAME_PLAIN))
1908                         return -EINVAL;
1909
1910                 escaped = cg_escape(n);
1911                 if (!escaped)
1912                         return -ENOMEM;
1913
1914                 if (!strextend(&s, escaped, "/", NULL))
1915                         return -ENOMEM;
1916
1917                 dash = strchr(dash+1, '-');
1918         }
1919
1920         e = cg_escape(unit);
1921         if (!e)
1922                 return -ENOMEM;
1923
1924         if (!strextend(&s, e, NULL))
1925                 return -ENOMEM;
1926
1927         *ret = s;
1928         s = NULL;
1929
1930         return 0;
1931 }
1932 #endif // 0
1933
1934 int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value) {
1935         _cleanup_free_ char *p = NULL;
1936         int r;
1937
1938         r = cg_get_path(controller, path, attribute, &p);
1939         if (r < 0)
1940                 return r;
1941
1942         return write_string_file(p, value, 0);
1943 }
1944
1945 int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret) {
1946         _cleanup_free_ char *p = NULL;
1947         int r;
1948
1949         r = cg_get_path(controller, path, attribute, &p);
1950         if (r < 0)
1951                 return r;
1952
1953         return read_one_line_file(p, ret);
1954 }
1955
1956 #if 0 /// UNNEEDED by elogind
1957 int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path) {
1958         CGroupController c;
1959         int r, unified;
1960
1961         /* This one will create a cgroup in our private tree, but also
1962          * duplicate it in the trees specified in mask, and remove it
1963          * in all others */
1964
1965         /* First create the cgroup in our own hierarchy. */
1966         r = cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
1967         if (r < 0)
1968                 return r;
1969
1970         /* If we are in the unified hierarchy, we are done now */
1971         unified = cg_unified();
1972         if (unified < 0)
1973                 return unified;
1974         if (unified > 0)
1975                 return 0;
1976
1977         /* Otherwise, do the same in the other hierarchies */
1978         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
1979                 CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c);
1980                 const char *n;
1981
1982                 n = cgroup_controller_to_string(c);
1983
1984                 if (mask & bit)
1985                         (void) cg_create(n, path);
1986                 else if (supported & bit)
1987                         (void) cg_trim(n, path, true);
1988         }
1989
1990         return 0;
1991 }
1992
1993 int cg_attach_everywhere(CGroupMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) {
1994         CGroupController c;
1995         int r, unified;
1996
1997         r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid);
1998         if (r < 0)
1999                 return r;
2000
2001         unified = cg_unified();
2002         if (unified < 0)
2003                 return unified;
2004         if (unified > 0)
2005                 return 0;
2006
2007         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
2008                 CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c);
2009                 const char *p = NULL;
2010
2011                 if (!(supported & bit))
2012                         continue;
2013
2014                 if (path_callback)
2015                         p = path_callback(bit, userdata);
2016
2017                 if (!p)
2018                         p = path;
2019
2020                 (void) cg_attach_fallback(cgroup_controller_to_string(c), p, pid);
2021         }
2022
2023         return 0;
2024 }
2025
2026 int cg_attach_many_everywhere(CGroupMask supported, const char *path, Set* pids, cg_migrate_callback_t path_callback, void *userdata) {
2027         Iterator i;
2028         void *pidp;
2029         int r = 0;
2030
2031         SET_FOREACH(pidp, pids, i) {
2032                 pid_t pid = PTR_TO_PID(pidp);
2033                 int q;
2034
2035                 q = cg_attach_everywhere(supported, path, pid, path_callback, userdata);
2036                 if (q < 0 && r >= 0)
2037                         r = q;
2038         }
2039
2040         return r;
2041 }
2042
2043 int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to, cg_migrate_callback_t to_callback, void *userdata) {
2044         CGroupController c;
2045         int r = 0, unified;
2046
2047         if (!path_equal(from, to))  {
2048                 r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, CGROUP_REMOVE);
2049                 if (r < 0)
2050                         return r;
2051         }
2052
2053         unified = cg_unified();
2054         if (unified < 0)
2055                 return unified;
2056         if (unified > 0)
2057                 return r;
2058
2059         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
2060                 CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c);
2061                 const char *p = NULL;
2062
2063                 if (!(supported & bit))
2064                         continue;
2065
2066                 if (to_callback)
2067                         p = to_callback(bit, userdata);
2068
2069                 if (!p)
2070                         p = to;
2071
2072                 (void) cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, cgroup_controller_to_string(c), p, 0);
2073         }
2074
2075         return 0;
2076 }
2077
2078 int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root) {
2079         CGroupController c;
2080         int r, unified;
2081
2082         r = cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root);
2083         if (r < 0)
2084                 return r;
2085
2086         unified = cg_unified();
2087         if (unified < 0)
2088                 return unified;
2089         if (unified > 0)
2090                 return r;
2091
2092         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
2093                 CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c);
2094
2095                 if (!(supported & bit))
2096                         continue;
2097
2098                 (void) cg_trim(cgroup_controller_to_string(c), path, delete_root);
2099         }
2100
2101         return 0;
2102 }
2103 #endif // 0
2104
2105 int cg_mask_supported(CGroupMask *ret) {
2106         CGroupMask mask = 0;
2107         int r, unified;
2108
2109         /* Determines the mask of supported cgroup controllers. Only
2110          * includes controllers we can make sense of and that are
2111          * actually accessible. */
2112
2113         unified = cg_unified();
2114         if (unified < 0)
2115                 return unified;
2116         if (unified > 0) {
2117                 _cleanup_free_ char *root = NULL, *controllers = NULL, *path = NULL;
2118                 const char *c;
2119
2120                 /* In the unified hierarchy we can read the supported
2121                  * and accessible controllers from a the top-level
2122                  * cgroup attribute */
2123
2124                 r = cg_get_root_path(&root);
2125                 if (r < 0)
2126                         return r;
2127
2128                 r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, root, "cgroup.controllers", &path);
2129                 if (r < 0)
2130                         return r;
2131
2132                 r = read_one_line_file(path, &controllers);
2133                 if (r < 0)
2134                         return r;
2135
2136                 c = controllers;
2137                 for (;;) {
2138                         _cleanup_free_ char *n = NULL;
2139                         CGroupController v;
2140
2141                         r = extract_first_word(&c, &n, NULL, 0);
2142                         if (r < 0)
2143                                 return r;
2144                         if (r == 0)
2145                                 break;
2146
2147                         v = cgroup_controller_from_string(n);
2148                         if (v < 0)
2149                                 continue;
2150
2151                         mask |= CGROUP_CONTROLLER_TO_MASK(v);
2152                 }
2153
2154                 /* Currently, we only support the memory, io and pids
2155                  * controller in the unified hierarchy, mask
2156                  * everything else off. */
2157                 mask &= CGROUP_MASK_MEMORY | CGROUP_MASK_IO | CGROUP_MASK_PIDS;
2158
2159         } else {
2160                 CGroupController c;
2161
2162                 /* In the legacy hierarchy, we check whether which
2163                  * hierarchies are mounted. */
2164
2165                 for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
2166                         const char *n;
2167
2168                         n = cgroup_controller_to_string(c);
2169                         if (controller_is_accessible(n) >= 0)
2170                                 mask |= CGROUP_CONTROLLER_TO_MASK(c);
2171                 }
2172         }
2173
2174         *ret = mask;
2175         return 0;
2176 }
2177
2178 #if 0 /// UNNEEDED by elogind
2179 int cg_kernel_controllers(Set *controllers) {
2180         _cleanup_fclose_ FILE *f = NULL;
2181         char buf[LINE_MAX];
2182         int r;
2183
2184         assert(controllers);
2185
2186         /* Determines the full list of kernel-known controllers. Might
2187          * include controllers we don't actually support, arbitrary
2188          * named hierarchies and controllers that aren't currently
2189          * accessible (because not mounted). */
2190
2191         f = fopen("/proc/cgroups", "re");
2192         if (!f) {
2193                 if (errno == ENOENT)
2194                         return 0;
2195                 return -errno;
2196         }
2197
2198         /* Ignore the header line */
2199         (void) fgets(buf, sizeof(buf), f);
2200
2201         for (;;) {
2202                 char *controller;
2203                 int enabled = 0;
2204
2205                 errno = 0;
2206                 if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) {
2207
2208                         if (feof(f))
2209                                 break;
2210
2211                         if (ferror(f) && errno > 0)
2212                                 return -errno;
2213
2214                         return -EBADMSG;
2215                 }
2216
2217                 if (!enabled) {
2218                         free(controller);
2219                         continue;
2220                 }
2221
2222                 if (!cg_controller_is_valid(controller)) {
2223                         free(controller);
2224                         return -EBADMSG;
2225                 }
2226
2227                 r = set_consume(controllers, controller);
2228                 if (r < 0)
2229                         return r;
2230         }
2231
2232         return 0;
2233 }
2234 #endif // 0
2235
2236 static thread_local int unified_cache = -1;
2237
2238 int cg_unified(void) {
2239         struct statfs fs;
2240
2241         /* Checks if we support the unified hierarchy. Returns an
2242          * error when the cgroup hierarchies aren't mounted yet or we
2243          * have any other trouble determining if the unified hierarchy
2244          * is supported. */
2245
2246         if (unified_cache >= 0)
2247                 return unified_cache;
2248
2249         if (statfs("/sys/fs/cgroup/", &fs) < 0)
2250                 return -errno;
2251
2252 #if 0 /// UNNEEDED by elogind
2253         if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC))
2254                 unified_cache = true;
2255         else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC))
2256 #else
2257         /* elogind can not support the unified hierarchy as a controller,
2258          * so always assume a classical hierarchy.
2259          * If, and only *if*, someone really wants to substitute systemd-login
2260          * in an environment managed by systemd with elogind, we might have to
2261          * add such a support. */
2262         if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC))
2263 #endif // 0
2264                 unified_cache = false;
2265         else
2266                 return -ENOMEDIUM;
2267
2268         return unified_cache;
2269 }
2270
2271 #if 0 /// UNNEEDED by elogind
2272 void cg_unified_flush(void) {
2273         unified_cache = -1;
2274 }
2275
2276 int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p) {
2277         _cleanup_free_ char *fs = NULL;
2278         CGroupController c;
2279         int r, unified;
2280
2281         assert(p);
2282
2283         if (supported == 0)
2284                 return 0;
2285
2286         unified = cg_unified();
2287         if (unified < 0)
2288                 return unified;
2289         if (!unified) /* on the legacy hiearchy there's no joining of controllers defined */
2290                 return 0;
2291
2292         r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, p, "cgroup.subtree_control", &fs);
2293         if (r < 0)
2294                 return r;
2295
2296         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
2297                 CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c);
2298                 const char *n;
2299
2300                 if (!(supported & bit))
2301                         continue;
2302
2303                 n = cgroup_controller_to_string(c);
2304                 {
2305                         char s[1 + strlen(n) + 1];
2306
2307                         s[0] = mask & bit ? '+' : '-';
2308                         strcpy(s + 1, n);
2309
2310                         r = write_string_file(fs, s, 0);
2311                         if (r < 0)
2312                                 log_debug_errno(r, "Failed to enable controller %s for %s (%s): %m", n, p, fs);
2313                 }
2314         }
2315
2316         return 0;
2317 }
2318
2319 bool cg_is_unified_wanted(void) {
2320         static thread_local int wanted = -1;
2321         int r, unified;
2322
2323         /* If the hierarchy is already mounted, then follow whatever
2324          * was chosen for it. */
2325         unified = cg_unified();
2326         if (unified >= 0)
2327                 return unified;
2328
2329         /* Otherwise, let's see what the kernel command line has to
2330          * say. Since checking that is expensive, let's cache the
2331          * result. */
2332         if (wanted >= 0)
2333                 return wanted;
2334
2335         r = get_proc_cmdline_key("systemd.unified_cgroup_hierarchy", NULL);
2336         if (r > 0)
2337                 return (wanted = true);
2338         else {
2339                 _cleanup_free_ char *value = NULL;
2340
2341                 r = get_proc_cmdline_key("systemd.unified_cgroup_hierarchy=", &value);
2342                 if (r < 0)
2343                         return false;
2344                 if (r == 0)
2345                         return (wanted = false);
2346
2347                 return (wanted = parse_boolean(value) > 0);
2348         }
2349 }
2350
2351 bool cg_is_legacy_wanted(void) {
2352         return !cg_is_unified_wanted();
2353 }
2354 #else
2355 bool cg_is_legacy_wanted(void) {
2356         return true;
2357 }
2358 #endif // 0
2359
2360 #if 0 /// UNNEEDED by elogind
2361 int cg_weight_parse(const char *s, uint64_t *ret) {
2362         uint64_t u;
2363         int r;
2364
2365         if (isempty(s)) {
2366                 *ret = CGROUP_WEIGHT_INVALID;
2367                 return 0;
2368         }
2369
2370         r = safe_atou64(s, &u);
2371         if (r < 0)
2372                 return r;
2373
2374         if (u < CGROUP_WEIGHT_MIN || u > CGROUP_WEIGHT_MAX)
2375                 return -ERANGE;
2376
2377         *ret = u;
2378         return 0;
2379 }
2380
2381 const uint64_t cgroup_io_limit_defaults[_CGROUP_IO_LIMIT_TYPE_MAX] = {
2382         [CGROUP_IO_RBPS_MAX]    = CGROUP_LIMIT_MAX,
2383         [CGROUP_IO_WBPS_MAX]    = CGROUP_LIMIT_MAX,
2384         [CGROUP_IO_RIOPS_MAX]   = CGROUP_LIMIT_MAX,
2385         [CGROUP_IO_WIOPS_MAX]   = CGROUP_LIMIT_MAX,
2386 };
2387
2388 static const char* const cgroup_io_limit_type_table[_CGROUP_IO_LIMIT_TYPE_MAX] = {
2389         [CGROUP_IO_RBPS_MAX]    = "IOReadBandwidthMax",
2390         [CGROUP_IO_WBPS_MAX]    = "IOWriteBandwidthMax",
2391         [CGROUP_IO_RIOPS_MAX]   = "IOReadIOPSMax",
2392         [CGROUP_IO_WIOPS_MAX]   = "IOWriteIOPSMax",
2393 };
2394
2395 DEFINE_STRING_TABLE_LOOKUP(cgroup_io_limit_type, CGroupIOLimitType);
2396
2397 int cg_cpu_shares_parse(const char *s, uint64_t *ret) {
2398         uint64_t u;
2399         int r;
2400
2401         if (isempty(s)) {
2402                 *ret = CGROUP_CPU_SHARES_INVALID;
2403                 return 0;
2404         }
2405
2406         r = safe_atou64(s, &u);
2407         if (r < 0)
2408                 return r;
2409
2410         if (u < CGROUP_CPU_SHARES_MIN || u > CGROUP_CPU_SHARES_MAX)
2411                 return -ERANGE;
2412
2413         *ret = u;
2414         return 0;
2415 }
2416
2417 int cg_blkio_weight_parse(const char *s, uint64_t *ret) {
2418         uint64_t u;
2419         int r;
2420
2421         if (isempty(s)) {
2422                 *ret = CGROUP_BLKIO_WEIGHT_INVALID;
2423                 return 0;
2424         }
2425
2426         r = safe_atou64(s, &u);
2427         if (r < 0)
2428                 return r;
2429
2430         if (u < CGROUP_BLKIO_WEIGHT_MIN || u > CGROUP_BLKIO_WEIGHT_MAX)
2431                 return -ERANGE;
2432
2433         *ret = u;
2434         return 0;
2435 }
2436 #endif // 0
2437
2438 static const char *cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
2439         [CGROUP_CONTROLLER_CPU] = "cpu",
2440         [CGROUP_CONTROLLER_CPUACCT] = "cpuacct",
2441         [CGROUP_CONTROLLER_IO] = "io",
2442         [CGROUP_CONTROLLER_BLKIO] = "blkio",
2443         [CGROUP_CONTROLLER_MEMORY] = "memory",
2444         [CGROUP_CONTROLLER_DEVICES] = "devices",
2445         [CGROUP_CONTROLLER_PIDS] = "pids",
2446 };
2447
2448 DEFINE_STRING_TABLE_LOOKUP(cgroup_controller, CGroupController);