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