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