chiark / gitweb /
f8386f01c62a17e79440754b9f1bdf7463e0c714
[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 /// elogind does not support systemd scopes and slices
1168 #if 0
1169         e = endswith(p, "/" SPECIAL_INIT_SCOPE);
1170         if (!e)
1171                 e = endswith(p, "/" SPECIAL_SYSTEM_SLICE); /* legacy */
1172         if (!e)
1173                 e = endswith(p, "/system"); /* even more legacy */
1174         if (e)
1175                 *e = 0;
1176 #endif // 0
1177
1178         *path = p;
1179         return 0;
1180 }
1181
1182 int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
1183         _cleanup_free_ char *rt = NULL;
1184         char *p;
1185         int r;
1186
1187         assert(cgroup);
1188         assert(shifted);
1189
1190         if (!root) {
1191                 /* If the root was specified let's use that, otherwise
1192                  * let's determine it from PID 1 */
1193
1194                 r = cg_get_root_path(&rt);
1195                 if (r < 0)
1196                         return r;
1197
1198                 root = rt;
1199         }
1200
1201         p = path_startswith(cgroup, root);
1202         if (p && p > cgroup)
1203                 *shifted = p - 1;
1204         else
1205                 *shifted = cgroup;
1206
1207         return 0;
1208 }
1209
1210 int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
1211         _cleanup_free_ char *raw = NULL;
1212         const char *c;
1213         int r;
1214
1215         assert(pid >= 0);
1216         assert(cgroup);
1217
1218         r = cg_pid_get_path(ELOGIND_CGROUP_CONTROLLER, pid, &raw);
1219         if (r < 0)
1220                 return r;
1221
1222         r = cg_shift_path(raw, root, &c);
1223         if (r < 0)
1224                 return r;
1225
1226         if (c == raw) {
1227                 *cgroup = raw;
1228                 raw = NULL;
1229         } else {
1230                 char *n;
1231
1232                 n = strdup(c);
1233                 if (!n)
1234                         return -ENOMEM;
1235
1236                 *cgroup = n;
1237         }
1238
1239         return 0;
1240 }
1241
1242 int cg_path_decode_unit(const char *cgroup, char **unit){
1243         char *c, *s;
1244         size_t n;
1245
1246         assert(cgroup);
1247         assert(unit);
1248
1249         n = strcspn(cgroup, "/");
1250         if (n < 3)
1251                 return -ENXIO;
1252
1253         c = strndupa(cgroup, n);
1254         c = cg_unescape(c);
1255
1256         if (!unit_name_is_valid(c, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
1257                 return -ENXIO;
1258
1259         s = strdup(c);
1260         if (!s)
1261                 return -ENOMEM;
1262
1263         *unit = s;
1264         return 0;
1265 }
1266
1267 static bool valid_slice_name(const char *p, size_t n) {
1268
1269         if (!p)
1270                 return false;
1271
1272         if (n < strlen("x.slice"))
1273                 return false;
1274
1275         if (memcmp(p + n - 6, ".slice", 6) == 0) {
1276                 char buf[n+1], *c;
1277
1278                 memcpy(buf, p, n);
1279                 buf[n] = 0;
1280
1281                 c = cg_unescape(buf);
1282
1283                 return unit_name_is_valid(c, UNIT_NAME_PLAIN);
1284         }
1285
1286         return false;
1287 }
1288
1289 static const char *skip_slices(const char *p) {
1290         assert(p);
1291
1292         /* Skips over all slice assignments */
1293
1294         for (;;) {
1295                 size_t n;
1296
1297                 p += strspn(p, "/");
1298
1299                 n = strcspn(p, "/");
1300                 if (!valid_slice_name(p, n))
1301                         return p;
1302
1303                 p += n;
1304         }
1305 }
1306
1307 int cg_path_get_unit(const char *path, char **ret) {
1308         const char *e;
1309         char *unit;
1310         int r;
1311
1312         assert(path);
1313         assert(ret);
1314
1315         e = skip_slices(path);
1316
1317         r = cg_path_decode_unit(e, &unit);
1318         if (r < 0)
1319                 return r;
1320
1321         /* We skipped over the slices, don't accept any now */
1322         if (endswith(unit, ".slice")) {
1323                 free(unit);
1324                 return -ENXIO;
1325         }
1326
1327         *ret = unit;
1328         return 0;
1329 }
1330
1331 int cg_pid_get_unit(pid_t pid, char **unit) {
1332         _cleanup_free_ char *cgroup = NULL;
1333         int r;
1334
1335         assert(unit);
1336
1337         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1338         if (r < 0)
1339                 return r;
1340
1341         return cg_path_get_unit(cgroup, unit);
1342 }
1343
1344 /**
1345  * Skip session-*.scope, but require it to be there.
1346  */
1347 static const char *skip_session(const char *p) {
1348         size_t n;
1349
1350         if (isempty(p))
1351                 return NULL;
1352
1353         p += strspn(p, "/");
1354
1355         n = strcspn(p, "/");
1356         if (n < strlen("session-x.scope"))
1357                 return NULL;
1358
1359         if (memcmp(p, "session-", 8) == 0 && memcmp(p + n - 6, ".scope", 6) == 0) {
1360                 char buf[n - 8 - 6 + 1];
1361
1362                 memcpy(buf, p + 8, n - 8 - 6);
1363                 buf[n - 8 - 6] = 0;
1364
1365                 /* Note that session scopes never need unescaping,
1366                  * since they cannot conflict with the kernel's own
1367                  * names, hence we don't need to call cg_unescape()
1368                  * here. */
1369
1370                 if (!session_id_valid(buf))
1371                         return false;
1372
1373                 p += n;
1374                 p += strspn(p, "/");
1375                 return p;
1376         }
1377
1378         return NULL;
1379 }
1380
1381 /**
1382  * Skip user@*.service, but require it to be there.
1383  */
1384 static const char *skip_user_manager(const char *p) {
1385         size_t n;
1386
1387         if (isempty(p))
1388                 return NULL;
1389
1390         p += strspn(p, "/");
1391
1392         n = strcspn(p, "/");
1393         if (n < strlen("user@x.service"))
1394                 return NULL;
1395
1396         if (memcmp(p, "user@", 5) == 0 && memcmp(p + n - 8, ".service", 8) == 0) {
1397                 char buf[n - 5 - 8 + 1];
1398
1399                 memcpy(buf, p + 5, n - 5 - 8);
1400                 buf[n - 5 - 8] = 0;
1401
1402                 /* Note that user manager services never need unescaping,
1403                  * since they cannot conflict with the kernel's own
1404                  * names, hence we don't need to call cg_unescape()
1405                  * here. */
1406
1407                 if (parse_uid(buf, NULL) < 0)
1408                         return NULL;
1409
1410                 p += n;
1411                 p += strspn(p, "/");
1412
1413                 return p;
1414         }
1415
1416         return NULL;
1417 }
1418
1419 static const char *skip_user_prefix(const char *path) {
1420         const char *e, *t;
1421
1422         assert(path);
1423
1424         /* Skip slices, if there are any */
1425         e = skip_slices(path);
1426
1427         /* Skip the user manager, if it's in the path now... */
1428         t = skip_user_manager(e);
1429         if (t)
1430                 return t;
1431
1432         /* Alternatively skip the user session if it is in the path... */
1433         return skip_session(e);
1434 }
1435
1436 int cg_path_get_user_unit(const char *path, char **ret) {
1437         const char *t;
1438
1439         assert(path);
1440         assert(ret);
1441
1442         t = skip_user_prefix(path);
1443         if (!t)
1444                 return -ENXIO;
1445
1446         /* And from here on it looks pretty much the same as for a
1447          * system unit, hence let's use the same parser from here
1448          * on. */
1449         return cg_path_get_unit(t, ret);
1450 }
1451
1452 int cg_pid_get_user_unit(pid_t pid, char **unit) {
1453         _cleanup_free_ char *cgroup = NULL;
1454         int r;
1455
1456         assert(unit);
1457
1458         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1459         if (r < 0)
1460                 return r;
1461
1462         return cg_path_get_user_unit(cgroup, unit);
1463 }
1464
1465 int cg_path_get_machine_name(const char *path, char **machine) {
1466         _cleanup_free_ char *u = NULL;
1467         const char *sl;
1468         int r;
1469
1470         r = cg_path_get_unit(path, &u);
1471         if (r < 0)
1472                 return r;
1473
1474         sl = strjoina("/run/systemd/machines/unit:", u);
1475         return readlink_malloc(sl, machine);
1476 }
1477
1478 int cg_pid_get_machine_name(pid_t pid, char **machine) {
1479         _cleanup_free_ char *cgroup = NULL;
1480         int r;
1481
1482         assert(machine);
1483
1484         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1485         if (r < 0)
1486                 return r;
1487
1488         return cg_path_get_machine_name(cgroup, machine);
1489 }
1490
1491 int cg_path_get_session(const char *path, char **session) {
1492         _cleanup_free_ char *unit = NULL;
1493         char *start, *end;
1494         int r;
1495
1496         assert(path);
1497
1498         r = cg_path_get_unit(path, &unit);
1499         if (r < 0)
1500                 return r;
1501
1502         start = startswith(unit, "session-");
1503         if (!start)
1504                 return -ENXIO;
1505         end = endswith(start, ".scope");
1506         if (!end)
1507                 return -ENXIO;
1508
1509         *end = 0;
1510         if (!session_id_valid(start))
1511                 return -ENXIO;
1512
1513         if (session) {
1514                 char *rr;
1515
1516                 rr = strdup(start);
1517                 if (!rr)
1518                         return -ENOMEM;
1519
1520                 *session = rr;
1521         }
1522
1523         return 0;
1524 }
1525
1526 int cg_pid_get_session(pid_t pid, char **session) {
1527         _cleanup_free_ char *cgroup = NULL;
1528         int r;
1529
1530         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1531         if (r < 0)
1532                 return r;
1533
1534         return cg_path_get_session(cgroup, session);
1535 }
1536
1537 int cg_path_get_owner_uid(const char *path, uid_t *uid) {
1538         _cleanup_free_ char *slice = NULL;
1539         char *start, *end;
1540         int r;
1541
1542         assert(path);
1543
1544         r = cg_path_get_slice(path, &slice);
1545         if (r < 0)
1546                 return r;
1547
1548         start = startswith(slice, "user-");
1549         if (!start)
1550                 return -ENXIO;
1551         end = endswith(start, ".slice");
1552         if (!end)
1553                 return -ENXIO;
1554
1555         *end = 0;
1556         if (parse_uid(start, uid) < 0)
1557                 return -ENXIO;
1558
1559         return 0;
1560 }
1561
1562 int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) {
1563         _cleanup_free_ char *cgroup = NULL;
1564         int r;
1565
1566         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1567         if (r < 0)
1568                 return r;
1569
1570         return cg_path_get_owner_uid(cgroup, uid);
1571 }
1572
1573 int cg_path_get_slice(const char *p, char **slice) {
1574         const char *e = NULL;
1575
1576         assert(p);
1577         assert(slice);
1578
1579         /* Finds the right-most slice unit from the beginning, but
1580          * stops before we come to the first non-slice unit. */
1581
1582         for (;;) {
1583                 size_t n;
1584
1585                 p += strspn(p, "/");
1586
1587                 n = strcspn(p, "/");
1588                 if (!valid_slice_name(p, n)) {
1589
1590                         if (!e) {
1591                                 char *s;
1592
1593                                 s = strdup("-.slice");
1594                                 if (!s)
1595                                         return -ENOMEM;
1596
1597                                 *slice = s;
1598                                 return 0;
1599                         }
1600
1601                         return cg_path_decode_unit(e, slice);
1602                 }
1603
1604                 e = p;
1605                 p += n;
1606         }
1607 }
1608
1609 int cg_pid_get_slice(pid_t pid, char **slice) {
1610         _cleanup_free_ char *cgroup = NULL;
1611         int r;
1612
1613         assert(slice);
1614
1615         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1616         if (r < 0)
1617                 return r;
1618
1619         return cg_path_get_slice(cgroup, slice);
1620 }
1621
1622 int cg_path_get_user_slice(const char *p, char **slice) {
1623         const char *t;
1624         assert(p);
1625         assert(slice);
1626
1627         t = skip_user_prefix(p);
1628         if (!t)
1629                 return -ENXIO;
1630
1631         /* And now it looks pretty much the same as for a system
1632          * slice, so let's just use the same parser from here on. */
1633         return cg_path_get_slice(t, slice);
1634 }
1635
1636 int cg_pid_get_user_slice(pid_t pid, char **slice) {
1637         _cleanup_free_ char *cgroup = NULL;
1638         int r;
1639
1640         assert(slice);
1641
1642         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1643         if (r < 0)
1644                 return r;
1645
1646         return cg_path_get_user_slice(cgroup, slice);
1647 }
1648
1649 char *cg_escape(const char *p) {
1650         bool need_prefix = false;
1651
1652         /* This implements very minimal escaping for names to be used
1653          * as file names in the cgroup tree: any name which might
1654          * conflict with a kernel name or is prefixed with '_' is
1655          * prefixed with a '_'. That way, when reading cgroup names it
1656          * is sufficient to remove a single prefixing underscore if
1657          * there is one. */
1658
1659         /* The return value of this function (unlike cg_unescape())
1660          * needs free()! */
1661
1662         if (p[0] == 0 ||
1663             p[0] == '_' ||
1664             p[0] == '.' ||
1665             streq(p, "notify_on_release") ||
1666             streq(p, "release_agent") ||
1667             streq(p, "tasks") ||
1668             startswith(p, "cgroup."))
1669                 need_prefix = true;
1670         else {
1671                 const char *dot;
1672
1673                 dot = strrchr(p, '.');
1674                 if (dot) {
1675                         CGroupController c;
1676                         size_t l = dot - p;
1677
1678                         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
1679                                 const char *n;
1680
1681                                 n = cgroup_controller_to_string(c);
1682
1683                                 if (l != strlen(n))
1684                                         continue;
1685
1686                                 if (memcmp(p, n, l) != 0)
1687                                         continue;
1688
1689                                         need_prefix = true;
1690                                 break;
1691                         }
1692                 }
1693         }
1694
1695         if (need_prefix)
1696                 return strappend("_", p);
1697
1698                 return strdup(p);
1699 }
1700
1701 char *cg_unescape(const char *p) {
1702         assert(p);
1703
1704         /* The return value of this function (unlike cg_escape())
1705          * doesn't need free()! */
1706
1707         if (p[0] == '_')
1708                 return (char*) p+1;
1709
1710         return (char*) p;
1711 }
1712
1713 #define CONTROLLER_VALID                        \
1714         DIGITS LETTERS                          \
1715         "_"
1716
1717 bool cg_controller_is_valid(const char *p) {
1718         const char *t, *s;
1719
1720         if (!p)
1721                 return false;
1722
1723         s = startswith(p, "name=");
1724         if (s)
1725                 p = s;
1726
1727         if (*p == 0 || *p == '_')
1728                 return false;
1729
1730         for (t = p; *t; t++)
1731                 if (!strchr(CONTROLLER_VALID, *t))
1732                         return false;
1733
1734         if (t - p > FILENAME_MAX)
1735                 return false;
1736
1737         return true;
1738 }
1739
1740 /// UNNEEDED by elogind
1741 #if 0
1742 int cg_slice_to_path(const char *unit, char **ret) {
1743         _cleanup_free_ char *p = NULL, *s = NULL, *e = NULL;
1744         const char *dash;
1745         int r;
1746
1747         assert(unit);
1748         assert(ret);
1749
1750         if (streq(unit, "-.slice")) {
1751                 char *x;
1752
1753                 x = strdup("");
1754                 if (!x)
1755                         return -ENOMEM;
1756                 *ret = x;
1757                 return 0;
1758         }
1759
1760         if (!unit_name_is_valid(unit, UNIT_NAME_PLAIN))
1761                 return -EINVAL;
1762
1763         if (!endswith(unit, ".slice"))
1764                 return -EINVAL;
1765
1766         r = unit_name_to_prefix(unit, &p);
1767         if (r < 0)
1768                 return r;
1769
1770         dash = strchr(p, '-');
1771
1772         /* Don't allow initial dashes */
1773         if (dash == p)
1774                 return -EINVAL;
1775
1776         while (dash) {
1777                 _cleanup_free_ char *escaped = NULL;
1778                 char n[dash - p + sizeof(".slice")];
1779
1780                 /* Don't allow trailing or double dashes */
1781                 if (dash[1] == 0 || dash[1] == '-')
1782                         return -EINVAL;
1783
1784                 strcpy(stpncpy(n, p, dash - p), ".slice");
1785                 if (!unit_name_is_valid(n, UNIT_NAME_PLAIN))
1786                         return -EINVAL;
1787
1788                 escaped = cg_escape(n);
1789                 if (!escaped)
1790                         return -ENOMEM;
1791
1792                 if (!strextend(&s, escaped, "/", NULL))
1793                         return -ENOMEM;
1794
1795                 dash = strchr(dash+1, '-');
1796         }
1797
1798         e = cg_escape(unit);
1799         if (!e)
1800                 return -ENOMEM;
1801
1802         if (!strextend(&s, e, NULL))
1803                 return -ENOMEM;
1804
1805         *ret = s;
1806         s = NULL;
1807
1808         return 0;
1809 }
1810 #endif // 0
1811
1812 int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value) {
1813         _cleanup_free_ char *p = NULL;
1814         int r;
1815
1816         r = cg_get_path(controller, path, attribute, &p);
1817         if (r < 0)
1818                 return r;
1819
1820         return write_string_file_no_create(p, value);
1821 }
1822
1823 /// UNNEEDED by elogind
1824 #if 0
1825 int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret) {
1826         _cleanup_free_ char *p = NULL;
1827         int r;
1828
1829         r = cg_get_path(controller, path, attribute, &p);
1830         if (r < 0)
1831                 return r;
1832
1833         return read_one_line_file(p, ret);
1834 }
1835
1836 int cg_create_everywhere(CGroupMask supported, CGroupMask mask, const char *path) {
1837         CGroupController c;
1838         int r, unified;
1839
1840         /* This one will create a cgroup in our private tree, but also
1841          * duplicate it in the trees specified in mask, and remove it
1842          * in all others */
1843
1844         /* First create the cgroup in our own hierarchy. */
1845         r = cg_create(ELOGIND_CGROUP_CONTROLLER, path);
1846         if (r < 0)
1847                 return r;
1848
1849         /* If we are in the unified hierarchy, we are done now */
1850         unified = cg_unified();
1851         if (unified < 0)
1852                 return unified;
1853         if (unified > 0)
1854                 return 0;
1855
1856         /* Otherwise, do the same in the other hierarchies */
1857         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
1858                 CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c);
1859                 const char *n;
1860
1861                 n = cgroup_controller_to_string(c);
1862
1863                 if (mask & bit)
1864                         (void) cg_create(n, path);
1865                 else if (supported & bit)
1866                         (void) cg_trim(n, path, true);
1867         }
1868
1869         return 0;
1870 }
1871 #endif // 0
1872
1873 int cg_attach_everywhere(CGroupMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) {
1874         CGroupController c;
1875         int r, unified;
1876
1877         r = cg_attach(ELOGIND_CGROUP_CONTROLLER, path, pid);
1878         if (r < 0)
1879                 return r;
1880
1881         unified = cg_unified();
1882         if (unified < 0)
1883                 return unified;
1884         if (unified > 0)
1885                 return 0;
1886
1887         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
1888                 CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c);
1889                         const char *p = NULL;
1890
1891                 if (!(supported & bit))
1892                         continue;
1893
1894                         if (path_callback)
1895                                 p = path_callback(bit, userdata);
1896
1897                         if (!p)
1898                                 p = path;
1899
1900                 (void) cg_attach_fallback(cgroup_controller_to_string(c), p, pid);
1901         }
1902
1903         return 0;
1904 }
1905
1906 /// UNNEEDED by elogind
1907 #if 0
1908 int cg_attach_many_everywhere(CGroupMask supported, const char *path, Set* pids, cg_migrate_callback_t path_callback, void *userdata) {
1909         Iterator i;
1910         void *pidp;
1911         int r = 0;
1912
1913         SET_FOREACH(pidp, pids, i) {
1914                 pid_t pid = PTR_TO_PID(pidp);
1915                 int q;
1916
1917                 q = cg_attach_everywhere(supported, path, pid, path_callback, userdata);
1918                 if (q < 0 && r >= 0)
1919                         r = q;
1920         }
1921
1922         return r;
1923 }
1924
1925 int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to, cg_migrate_callback_t to_callback, void *userdata) {
1926         CGroupController c;
1927         int r = 0, unified;
1928
1929         if (!path_equal(from, to))  {
1930                 r = cg_migrate_recursive(ELOGIND_CGROUP_CONTROLLER, from, ELOGIND_CGROUP_CONTROLLER, to, false, true);
1931                 if (r < 0)
1932                         return r;
1933         }
1934
1935         unified = cg_unified();
1936         if (unified < 0)
1937                 return unified;
1938         if (unified > 0)
1939                 return r;
1940
1941         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
1942                 CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c);
1943                         const char *p = NULL;
1944
1945                 if (!(supported & bit))
1946                         continue;
1947
1948                         if (to_callback)
1949                                 p = to_callback(bit, userdata);
1950
1951                         if (!p)
1952                                 p = to;
1953
1954                 (void) cg_migrate_recursive_fallback(ELOGIND_CGROUP_CONTROLLER, to, cgroup_controller_to_string(c), p, false, false);
1955         }
1956
1957         return 0;
1958 }
1959
1960 int cg_trim_everywhere(CGroupMask supported, const char *path, bool delete_root) {
1961         CGroupController c;
1962         int r, unified;
1963
1964         r = cg_trim(ELOGIND_CGROUP_CONTROLLER, path, delete_root);
1965         if (r < 0)
1966                 return r;
1967
1968         unified = cg_unified();
1969         if (unified < 0)
1970                 return unified;
1971         if (unified > 0)
1972                 return r;
1973
1974         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
1975                 CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c);
1976
1977                 if (!(supported & bit))
1978                         continue;
1979
1980                 (void) cg_trim(cgroup_controller_to_string(c), path, delete_root);
1981         }
1982
1983         return 0;
1984 }
1985 #endif // 0
1986
1987 int cg_mask_supported(CGroupMask *ret) {
1988         CGroupMask mask = 0;
1989         int r, unified;
1990
1991         /* Determines the mask of supported cgroup controllers. Only
1992          * includes controllers we can make sense of and that are
1993          * actually accessible. */
1994
1995         unified = cg_unified();
1996         if (unified < 0)
1997                 return unified;
1998         if (unified > 0) {
1999                 _cleanup_free_ char *root = NULL, *controllers = NULL, *path = NULL;
2000                 const char *c;
2001
2002                 /* In the unified hierarchy we can read the supported
2003                  * and accessible controllers from a the top-level
2004                  * cgroup attribute */
2005
2006                 r = cg_get_root_path(&root);
2007                 if (r < 0)
2008                         return r;
2009
2010                 r = cg_get_path(ELOGIND_CGROUP_CONTROLLER, root, "cgroup.controllers", &path);
2011                 if (r < 0)
2012                         return r;
2013
2014                 r = read_one_line_file(path, &controllers);
2015                 if (r < 0)
2016                         return r;
2017
2018                 c = controllers;
2019                 for (;;) {
2020                         _cleanup_free_ char *n = NULL;
2021                         CGroupController v;
2022
2023                         r = extract_first_word(&c, &n, NULL, 0);
2024                         if (r < 0)
2025                                 return r;
2026                         if (r == 0)
2027                                 break;
2028
2029                         v = cgroup_controller_from_string(n);
2030                         if (v < 0)
2031                                 continue;
2032
2033                         mask |= CGROUP_CONTROLLER_TO_MASK(v);
2034         }
2035
2036                 /* Currently, we only support the memory controller in
2037                  * the unified hierarchy, mask everything else off. */
2038                 mask &= CGROUP_MASK_MEMORY;
2039
2040         } else {
2041                 CGroupController c;
2042
2043                 /* In the legacy hierarchy, we check whether which
2044                  * hierarchies are mounted. */
2045
2046                 for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
2047                         const char *n;
2048
2049                         n = cgroup_controller_to_string(c);
2050                         if (controller_is_accessible(n) >= 0)
2051                                 mask |= CGROUP_CONTROLLER_TO_MASK(c);
2052                 }
2053         }
2054
2055         *ret = mask;
2056         return 0;
2057 }
2058
2059 /// UNNEEDED by elogind
2060 #if 0
2061 int cg_kernel_controllers(Set *controllers) {
2062         _cleanup_fclose_ FILE *f = NULL;
2063         char buf[LINE_MAX];
2064         int r;
2065
2066         assert(controllers);
2067
2068         /* Determines the full list of kernel-known controllers. Might
2069          * include controllers we don't actually support, arbitrary
2070          * named hierarchies and controllers that aren't currently
2071          * accessible (because not mounted). */
2072
2073         f = fopen("/proc/cgroups", "re");
2074         if (!f) {
2075                 if (errno == ENOENT)
2076                         return 0;
2077                 return -errno;
2078         }
2079
2080         /* Ignore the header line */
2081         (void) fgets(buf, sizeof(buf), f);
2082
2083         for (;;) {
2084                 char *controller;
2085                 int enabled = 0;
2086
2087                 errno = 0;
2088                 if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) {
2089
2090                         if (feof(f))
2091                                 break;
2092
2093                         if (ferror(f) && errno != 0)
2094                                 return -errno;
2095
2096                         return -EBADMSG;
2097                 }
2098
2099                 if (!enabled) {
2100                         free(controller);
2101                         continue;
2102                 }
2103
2104                 if (!cg_controller_is_valid(controller)) {
2105                         free(controller);
2106                         return -EBADMSG;
2107                 }
2108
2109                 r = set_consume(controllers, controller);
2110                 if (r < 0)
2111                         return r;
2112         }
2113
2114         return 0;
2115 }
2116 #endif // 0
2117
2118 static thread_local int unified_cache = -1;
2119
2120 int cg_unified(void) {
2121         struct statfs fs;
2122
2123         /* Checks if we support the unified hierarchy. Returns an
2124          * error when the cgroup hierarchies aren't mounted yet or we
2125          * have any other trouble determining if the unified hierarchy
2126          * is supported. */
2127
2128         if (unified_cache >= 0)
2129                 return unified_cache;
2130
2131         if (statfs("/sys/fs/cgroup/", &fs) < 0)
2132                 return -errno;
2133
2134 /// elogind can not support the unified hierarchy as a controller,
2135 /// so always assume a classical hierarchy.
2136 /// If, ond only *if*, someone really wants to substitute systemd-login
2137 /// in an environment managed by systemd with elogin, we might have to
2138 /// add such a support.
2139 #if 0
2140         if (F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC))
2141                 unified_cache = true;
2142         else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC))
2143 #else
2144         if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC))
2145 #endif // elogind
2146                 unified_cache = false;
2147         else
2148                 return -ENOEXEC;
2149
2150         return unified_cache;
2151 }
2152
2153 /// UNNEEDED by elogind
2154 #if 0
2155 void cg_unified_flush(void) {
2156         unified_cache = -1;
2157 }
2158
2159 int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p) {
2160         _cleanup_free_ char *fs = NULL;
2161         CGroupController c;
2162         int r, unified;
2163
2164         assert(p);
2165
2166         if (supported == 0)
2167                 return 0;
2168
2169         unified = cg_unified();
2170         if (unified < 0)
2171                 return unified;
2172         if (!unified) /* on the legacy hiearchy there's no joining of controllers defined */
2173                 return 0;
2174
2175         r = cg_get_path(ELOGIND_CGROUP_CONTROLLER, p, "cgroup.subtree_control", &fs);
2176         if (r < 0)
2177                 return r;
2178
2179         for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
2180                 CGroupMask bit = CGROUP_CONTROLLER_TO_MASK(c);
2181                 const char *n;
2182
2183                 if (!(supported & bit))
2184                         continue;
2185
2186                 n = cgroup_controller_to_string(c);
2187                 {
2188                         char s[1 + strlen(n) + 1];
2189
2190                         s[0] = mask & bit ? '+' : '-';
2191                         strcpy(s + 1, n);
2192
2193                         r = write_string_file(fs, s, 0);
2194                         if (r < 0)
2195                                 log_debug_errno(r, "Failed to enable controller %s for %s (%s): %m", n, p, fs);
2196                 }
2197         }
2198
2199         return 0;
2200 }
2201 #endif // 0
2202
2203 bool cg_is_unified_wanted(void) {
2204         static thread_local int wanted = -1;
2205         int r, unified;
2206
2207         /* If the hierarchy is already mounted, then follow whatever
2208          * was chosen for it. */
2209         unified = cg_unified();
2210         if (unified >= 0)
2211                 return unified;
2212
2213         /* Otherwise, let's see what the kernel command line has to
2214          * say. Since checking that is expensive, let's cache the
2215          * result. */
2216         if (wanted >= 0)
2217                 return wanted;
2218
2219         r = get_proc_cmdline_key("systemd.unified_cgroup_hierarchy", NULL);
2220         if (r > 0)
2221                 return (wanted = true);
2222         else {
2223                 _cleanup_free_ char *value = NULL;
2224
2225                 r = get_proc_cmdline_key("systemd.unified_cgroup_hierarchy=", &value);
2226                 if (r < 0)
2227                         return false;
2228                 if (r == 0)
2229                         return (wanted = false);
2230
2231                 return (wanted = parse_boolean(value) > 0);
2232         }
2233 }
2234
2235 /// UNNEEDED by elogind
2236 #if 0
2237 bool cg_is_legacy_wanted(void) {
2238         return !cg_is_unified_wanted();
2239 }
2240 #endif // 0
2241
2242 static const char *cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
2243         [CGROUP_CONTROLLER_CPU] = "cpu",
2244         [CGROUP_CONTROLLER_CPUACCT] = "cpuacct",
2245         [CGROUP_CONTROLLER_BLKIO] = "blkio",
2246         [CGROUP_CONTROLLER_MEMORY] = "memory",
2247         [CGROUP_CONTROLLER_DEVICE] = "devices",
2248 };
2249
2250 DEFINE_STRING_TABLE_LOOKUP(cgroup_controller, CGroupController);