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