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