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