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