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