chiark / gitweb /
sd-bus: properly handle creds that are known but undefined for a process
[elogind.git] / src / shared / cgroup-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <unistd.h>
24 #include <signal.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <dirent.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <ftw.h>
31
32 #include "cgroup-util.h"
33 #include "set.h"
34 #include "macro.h"
35 #include "util.h"
36 #include "formats-util.h"
37 #include "path-util.h"
38 #include "unit-name.h"
39 #include "fileio.h"
40 #include "special.h"
41 #include "mkdir.h"
42
43 int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
44         _cleanup_free_ char *fs = NULL;
45         FILE *f;
46         int r;
47
48         assert(_f);
49
50         r = cg_get_path(controller, path, "cgroup.procs", &fs);
51         if (r < 0)
52                 return r;
53
54         f = fopen(fs, "re");
55         if (!f)
56                 return -errno;
57
58         *_f = f;
59         return 0;
60 }
61
62 int cg_read_pid(FILE *f, pid_t *_pid) {
63         unsigned long ul;
64
65         /* Note that the cgroup.procs might contain duplicates! See
66          * cgroups.txt for details. */
67
68         assert(f);
69         assert(_pid);
70
71         errno = 0;
72         if (fscanf(f, "%lu", &ul) != 1) {
73
74                 if (feof(f))
75                         return 0;
76
77                 return errno ? -errno : -EIO;
78         }
79
80         if (ul <= 0)
81                 return -EIO;
82
83         *_pid = (pid_t) ul;
84         return 1;
85 }
86
87 int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) {
88         _cleanup_free_ char *fs = NULL;
89         int r;
90         DIR *d;
91
92         assert(_d);
93
94         /* This is not recursive! */
95
96         r = cg_get_path(controller, path, NULL, &fs);
97         if (r < 0)
98                 return r;
99
100         d = opendir(fs);
101         if (!d)
102                 return -errno;
103
104         *_d = d;
105         return 0;
106 }
107
108 int cg_read_subgroup(DIR *d, char **fn) {
109         struct dirent *de;
110
111         assert(d);
112         assert(fn);
113
114         FOREACH_DIRENT(de, d, return -errno) {
115                 char *b;
116
117                 if (de->d_type != DT_DIR)
118                         continue;
119
120                 if (streq(de->d_name, ".") ||
121                     streq(de->d_name, ".."))
122                         continue;
123
124                 b = strdup(de->d_name);
125                 if (!b)
126                         return -ENOMEM;
127
128                 *fn = b;
129                 return 1;
130         }
131
132         return 0;
133 }
134
135 int cg_rmdir(const char *controller, const char *path) {
136         _cleanup_free_ char *p = NULL;
137         int r;
138
139         r = cg_get_path(controller, path, NULL, &p);
140         if (r < 0)
141                 return r;
142
143         r = rmdir(p);
144         if (r < 0 && errno != ENOENT)
145                 return -errno;
146
147         return 0;
148 }
149
150 int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) {
151         _cleanup_set_free_ Set *allocated_set = NULL;
152         bool done = false;
153         int r, ret = 0;
154         pid_t my_pid;
155
156         assert(sig >= 0);
157
158         /* This goes through the tasks list and kills them all. This
159          * is repeated until no further processes are added to the
160          * tasks list, to properly handle forking processes */
161
162         if (!s) {
163                 s = allocated_set = set_new(NULL);
164                 if (!s)
165                         return -ENOMEM;
166         }
167
168         my_pid = getpid();
169
170         do {
171                 _cleanup_fclose_ FILE *f = NULL;
172                 pid_t pid = 0;
173                 done = true;
174
175                 r = cg_enumerate_processes(controller, path, &f);
176                 if (r < 0) {
177                         if (ret >= 0 && r != -ENOENT)
178                                 return r;
179
180                         return ret;
181                 }
182
183                 while ((r = cg_read_pid(f, &pid)) > 0) {
184
185                         if (ignore_self && pid == my_pid)
186                                 continue;
187
188                         if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid))
189                                 continue;
190
191                         /* If we haven't killed this process yet, kill
192                          * it */
193                         if (kill(pid, sig) < 0) {
194                                 if (ret >= 0 && errno != ESRCH)
195                                         ret = -errno;
196                         } else {
197                                 if (sigcont && sig != SIGKILL)
198                                         kill(pid, SIGCONT);
199
200                                 if (ret == 0)
201                                         ret = 1;
202                         }
203
204                         done = false;
205
206                         r = set_put(s, LONG_TO_PTR(pid));
207                         if (r < 0) {
208                                 if (ret >= 0)
209                                         return r;
210
211                                 return ret;
212                         }
213                 }
214
215                 if (r < 0) {
216                         if (ret >= 0)
217                                 return r;
218
219                         return ret;
220                 }
221
222                 /* To avoid racing against processes which fork
223                  * quicker than we can kill them we repeat this until
224                  * no new pids need to be killed. */
225
226         } while (!done);
227
228         return ret;
229 }
230
231 int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool rem, Set *s) {
232         _cleanup_set_free_ Set *allocated_set = NULL;
233         _cleanup_closedir_ DIR *d = NULL;
234         int r, ret = 0;
235         char *fn;
236
237         assert(path);
238         assert(sig >= 0);
239
240         if (!s) {
241                 s = allocated_set = set_new(NULL);
242                 if (!s)
243                         return -ENOMEM;
244         }
245
246         ret = cg_kill(controller, path, sig, sigcont, ignore_self, s);
247
248         r = cg_enumerate_subgroups(controller, path, &d);
249         if (r < 0) {
250                 if (ret >= 0 && r != -ENOENT)
251                         return r;
252
253                 return ret;
254         }
255
256         while ((r = cg_read_subgroup(d, &fn)) > 0) {
257                 _cleanup_free_ char *p = NULL;
258
259                 p = strjoin(path, "/", fn, NULL);
260                 free(fn);
261                 if (!p)
262                         return -ENOMEM;
263
264                 r = cg_kill_recursive(controller, p, sig, sigcont, ignore_self, rem, s);
265                 if (ret >= 0 && r != 0)
266                         ret = r;
267         }
268
269         if (ret >= 0 && r < 0)
270                 ret = r;
271
272         if (rem) {
273                 r = cg_rmdir(controller, path);
274                 if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY)
275                         return r;
276         }
277
278         return ret;
279 }
280
281 int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self) {
282         bool done = false;
283         _cleanup_set_free_ Set *s = NULL;
284         int r, ret = 0;
285         pid_t my_pid;
286
287         assert(cfrom);
288         assert(pfrom);
289         assert(cto);
290         assert(pto);
291
292         s = set_new(NULL);
293         if (!s)
294                 return -ENOMEM;
295
296         my_pid = getpid();
297
298         do {
299                 _cleanup_fclose_ FILE *f = NULL;
300                 pid_t pid = 0;
301                 done = true;
302
303                 r = cg_enumerate_processes(cfrom, pfrom, &f);
304                 if (r < 0) {
305                         if (ret >= 0 && r != -ENOENT)
306                                 return r;
307
308                         return ret;
309                 }
310
311                 while ((r = cg_read_pid(f, &pid)) > 0) {
312
313                         /* This might do weird stuff if we aren't a
314                          * single-threaded program. However, we
315                          * luckily know we are not */
316                         if (ignore_self && pid == my_pid)
317                                 continue;
318
319                         if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid))
320                                 continue;
321
322                         r = cg_attach(cto, pto, pid);
323                         if (r < 0) {
324                                 if (ret >= 0 && r != -ESRCH)
325                                         ret = r;
326                         } else if (ret == 0)
327                                 ret = 1;
328
329                         done = false;
330
331                         r = set_put(s, LONG_TO_PTR(pid));
332                         if (r < 0) {
333                                 if (ret >= 0)
334                                         return r;
335
336                                 return ret;
337                         }
338                 }
339
340                 if (r < 0) {
341                         if (ret >= 0)
342                                 return r;
343
344                         return ret;
345                 }
346         } while (!done);
347
348         return ret;
349 }
350
351 int cg_migrate_recursive(
352                 const char *cfrom,
353                 const char *pfrom,
354                 const char *cto,
355                 const char *pto,
356                 bool ignore_self,
357                 bool rem) {
358
359         _cleanup_closedir_ DIR *d = NULL;
360         int r, ret = 0;
361         char *fn;
362
363         assert(cfrom);
364         assert(pfrom);
365         assert(cto);
366         assert(pto);
367
368         ret = cg_migrate(cfrom, pfrom, cto, pto, ignore_self);
369
370         r = cg_enumerate_subgroups(cfrom, pfrom, &d);
371         if (r < 0) {
372                 if (ret >= 0 && r != -ENOENT)
373                         return r;
374
375                 return ret;
376         }
377
378         while ((r = cg_read_subgroup(d, &fn)) > 0) {
379                 _cleanup_free_ char *p = NULL;
380
381                 p = strjoin(pfrom, "/", fn, NULL);
382                 free(fn);
383                 if (!p) {
384                         if (ret >= 0)
385                                 return -ENOMEM;
386
387                         return ret;
388                 }
389
390                 r = cg_migrate_recursive(cfrom, p, cto, pto, ignore_self, rem);
391                 if (r != 0 && ret >= 0)
392                         ret = r;
393         }
394
395         if (r < 0 && ret >= 0)
396                 ret = r;
397
398         if (rem) {
399                 r = cg_rmdir(cfrom, pfrom);
400                 if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY)
401                         return r;
402         }
403
404         return ret;
405 }
406
407 int cg_migrate_recursive_fallback(
408                 const char *cfrom,
409                 const char *pfrom,
410                 const char *cto,
411                 const char *pto,
412                 bool ignore_self,
413                 bool rem) {
414
415         int r;
416
417         assert(cfrom);
418         assert(pfrom);
419         assert(cto);
420         assert(pto);
421
422         r = cg_migrate_recursive(cfrom, pfrom, cto, pto, ignore_self, rem);
423         if (r < 0) {
424                 char prefix[strlen(pto) + 1];
425
426                 /* This didn't work? Then let's try all prefixes of the destination */
427
428                 PATH_FOREACH_PREFIX(prefix, pto) {
429                         r = cg_migrate_recursive(cfrom, pfrom, cto, prefix, ignore_self, rem);
430                         if (r >= 0)
431                                 break;
432                 }
433         }
434
435         return 0;
436 }
437
438 static const char *normalize_controller(const char *controller) {
439
440         assert(controller);
441
442         if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
443                 return "systemd";
444         else if (startswith(controller, "name="))
445                 return controller + 5;
446         else
447                 return controller;
448 }
449
450 static int join_path(const char *controller, const char *path, const char *suffix, char **fs) {
451         char *t = NULL;
452
453         if (!isempty(controller)) {
454                 if (!isempty(path) && !isempty(suffix))
455                         t = strjoin("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL);
456                 else if (!isempty(path))
457                         t = strjoin("/sys/fs/cgroup/", controller, "/", path, NULL);
458                 else if (!isempty(suffix))
459                         t = strjoin("/sys/fs/cgroup/", controller, "/", suffix, NULL);
460                 else
461                         t = strappend("/sys/fs/cgroup/", controller);
462         } else {
463                 if (!isempty(path) && !isempty(suffix))
464                         t = strjoin(path, "/", suffix, NULL);
465                 else if (!isempty(path))
466                         t = strdup(path);
467                 else
468                         return -EINVAL;
469         }
470
471         if (!t)
472                 return -ENOMEM;
473
474         *fs = path_kill_slashes(t);
475         return 0;
476 }
477
478 int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) {
479         const char *p;
480         static thread_local bool good = false;
481
482         assert(fs);
483
484         if (controller && !cg_controller_is_valid(controller, true))
485                 return -EINVAL;
486
487         if (_unlikely_(!good)) {
488                 int r;
489
490                 r = path_is_mount_point("/sys/fs/cgroup", false);
491                 if (r < 0)
492                         return r;
493                 if (r == 0)
494                         return -ENOENT;
495
496                 /* Cache this to save a few stat()s */
497                 good = true;
498         }
499
500         p = controller ? normalize_controller(controller) : NULL;
501
502         return join_path(p, path, suffix, fs);
503 }
504
505 static int check_hierarchy(const char *p) {
506         const char *cc;
507
508         assert(p);
509
510         if (!filename_is_valid(p))
511                 return 0;
512
513         /* Check if this controller actually really exists */
514         cc = strjoina("/sys/fs/cgroup/", p);
515         if (laccess(cc, F_OK) < 0)
516                 return -errno;
517
518         return 0;
519 }
520
521 int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) {
522         const char *p;
523         int r;
524
525         assert(fs);
526
527         if (!cg_controller_is_valid(controller, true))
528                 return -EINVAL;
529
530         /* Normalize the controller syntax */
531         p = normalize_controller(controller);
532
533         /* Check if this controller actually really exists */
534         r = check_hierarchy(p);
535         if (r < 0)
536                 return r;
537
538         return join_path(p, path, suffix, fs);
539 }
540
541 static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
542         assert(path);
543         assert(sb);
544         assert(ftwbuf);
545
546         if (typeflag != FTW_DP)
547                 return 0;
548
549         if (ftwbuf->level < 1)
550                 return 0;
551
552         rmdir(path);
553         return 0;
554 }
555
556 int cg_trim(const char *controller, const char *path, bool delete_root) {
557         _cleanup_free_ char *fs = NULL;
558         int r = 0;
559
560         assert(path);
561
562         r = cg_get_path(controller, path, NULL, &fs);
563         if (r < 0)
564                 return r;
565
566         errno = 0;
567         if (nftw(fs, trim_cb, 64, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) != 0)
568                 r = errno ? -errno : -EIO;
569
570         if (delete_root) {
571                 if (rmdir(fs) < 0 && errno != ENOENT)
572                         return -errno;
573         }
574
575         return r;
576 }
577
578 int cg_delete(const char *controller, const char *path) {
579         _cleanup_free_ char *parent = NULL;
580         int r;
581
582         assert(path);
583
584         r = path_get_parent(path, &parent);
585         if (r < 0)
586                 return r;
587
588         r = cg_migrate_recursive(controller, path, controller, parent, false, true);
589         return r == -ENOENT ? 0 : r;
590 }
591
592 int cg_create(const char *controller, const char *path) {
593         _cleanup_free_ char *fs = NULL;
594         int r;
595
596         r = cg_get_path_and_check(controller, path, NULL, &fs);
597         if (r < 0)
598                 return r;
599
600         r = mkdir_parents(fs, 0755);
601         if (r < 0)
602                 return r;
603
604         if (mkdir(fs, 0755) < 0) {
605
606                 if (errno == EEXIST)
607                         return 0;
608
609                 return -errno;
610         }
611
612         return 1;
613 }
614
615 int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
616         int r, q;
617
618         assert(pid >= 0);
619
620         r = cg_create(controller, path);
621         if (r < 0)
622                 return r;
623
624         q = cg_attach(controller, path, pid);
625         if (q < 0)
626                 return q;
627
628         /* This does not remove the cgroup on failure */
629         return r;
630 }
631
632 int cg_attach(const char *controller, const char *path, pid_t pid) {
633         _cleanup_free_ char *fs = NULL;
634         char c[DECIMAL_STR_MAX(pid_t) + 2];
635         int r;
636
637         assert(path);
638         assert(pid >= 0);
639
640         r = cg_get_path_and_check(controller, path, "cgroup.procs", &fs);
641         if (r < 0)
642                 return r;
643
644         if (pid == 0)
645                 pid = getpid();
646
647         snprintf(c, sizeof(c), PID_FMT"\n", pid);
648
649         return write_string_file_no_create(fs, c);
650 }
651
652 int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
653         int r;
654
655         assert(controller);
656         assert(path);
657         assert(pid >= 0);
658
659         r = cg_attach(controller, path, pid);
660         if (r < 0) {
661                 char prefix[strlen(path) + 1];
662
663                 /* This didn't work? Then let's try all prefixes of
664                  * the destination */
665
666                 PATH_FOREACH_PREFIX(prefix, path) {
667                         r = cg_attach(controller, prefix, pid);
668                         if (r >= 0)
669                                 break;
670                 }
671         }
672
673         return 0;
674 }
675
676 int cg_set_group_access(
677                 const char *controller,
678                 const char *path,
679                 mode_t mode,
680                 uid_t uid,
681                 gid_t gid) {
682
683         _cleanup_free_ char *fs = NULL;
684         int r;
685
686         assert(path);
687
688         if (mode != MODE_INVALID)
689                 mode &= 0777;
690
691         r = cg_get_path(controller, path, NULL, &fs);
692         if (r < 0)
693                 return r;
694
695         return chmod_and_chown(fs, mode, uid, gid);
696 }
697
698 int cg_set_task_access(
699                 const char *controller,
700                 const char *path,
701                 mode_t mode,
702                 uid_t uid,
703                 gid_t gid) {
704
705         _cleanup_free_ char *fs = NULL, *procs = NULL;
706         int r;
707
708         assert(path);
709
710         if (mode == MODE_INVALID && uid == UID_INVALID && gid == GID_INVALID)
711                 return 0;
712
713         if (mode != MODE_INVALID)
714                 mode &= 0666;
715
716         r = cg_get_path(controller, path, "cgroup.procs", &fs);
717         if (r < 0)
718                 return r;
719
720         r = chmod_and_chown(fs, mode, uid, gid);
721         if (r < 0)
722                 return r;
723
724         /* Compatibility, Always keep values for "tasks" in sync with
725          * "cgroup.procs" */
726         r = cg_get_path(controller, path, "tasks", &procs);
727         if (r < 0)
728                 return r;
729
730         return chmod_and_chown(procs, mode, uid, gid);
731 }
732
733 int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
734         _cleanup_fclose_ FILE *f = NULL;
735         char line[LINE_MAX];
736         const char *fs;
737         size_t cs;
738
739         assert(path);
740         assert(pid >= 0);
741
742         if (controller) {
743                 if (!cg_controller_is_valid(controller, true))
744                         return -EINVAL;
745
746                 controller = normalize_controller(controller);
747         } else
748                 controller = SYSTEMD_CGROUP_CONTROLLER;
749
750         fs = procfs_file_alloca(pid, "cgroup");
751
752         f = fopen(fs, "re");
753         if (!f)
754                 return errno == ENOENT ? -ESRCH : -errno;
755
756         cs = strlen(controller);
757
758         FOREACH_LINE(line, f, return -errno) {
759                 char *l, *p, *e;
760                 size_t k;
761                 const char *word, *state;
762                 bool found = false;
763
764                 truncate_nl(line);
765
766                 l = strchr(line, ':');
767                 if (!l)
768                         continue;
769
770                 l++;
771                 e = strchr(l, ':');
772                 if (!e)
773                         continue;
774
775                 *e = 0;
776
777                 FOREACH_WORD_SEPARATOR(word, k, l, ",", state) {
778
779                         if (k == cs && memcmp(word, controller, cs) == 0) {
780                                 found = true;
781                                 break;
782                         }
783
784                         if (k == 5 + cs &&
785                             memcmp(word, "name=", 5) == 0 &&
786                             memcmp(word+5, controller, cs) == 0) {
787                                 found = true;
788                                 break;
789                         }
790                 }
791
792                 if (!found)
793                         continue;
794
795                 p = strdup(e + 1);
796                 if (!p)
797                         return -ENOMEM;
798
799                 *path = p;
800                 return 0;
801         }
802
803         return -ENOENT;
804 }
805
806 int cg_install_release_agent(const char *controller, const char *agent) {
807         _cleanup_free_ char *fs = NULL, *contents = NULL;
808         char *sc;
809         int r;
810
811         assert(agent);
812
813         r = cg_get_path(controller, NULL, "release_agent", &fs);
814         if (r < 0)
815                 return r;
816
817         r = read_one_line_file(fs, &contents);
818         if (r < 0)
819                 return r;
820
821         sc = strstrip(contents);
822         if (sc[0] == 0) {
823                 r = write_string_file_no_create(fs, agent);
824                 if (r < 0)
825                         return r;
826         } else if (!streq(sc, agent))
827                 return -EEXIST;
828
829         free(fs);
830         fs = NULL;
831         r = cg_get_path(controller, NULL, "notify_on_release", &fs);
832         if (r < 0)
833                 return r;
834
835         free(contents);
836         contents = NULL;
837         r = read_one_line_file(fs, &contents);
838         if (r < 0)
839                 return r;
840
841         sc = strstrip(contents);
842         if (streq(sc, "0")) {
843                 r = write_string_file_no_create(fs, "1");
844                 if (r < 0)
845                         return r;
846
847                 return 1;
848         }
849
850         if (!streq(sc, "1"))
851                 return -EIO;
852
853         return 0;
854 }
855
856 int cg_uninstall_release_agent(const char *controller) {
857         _cleanup_free_ char *fs = NULL;
858         int r;
859
860         r = cg_get_path(controller, NULL, "notify_on_release", &fs);
861         if (r < 0)
862                 return r;
863
864         r = write_string_file_no_create(fs, "0");
865         if (r < 0)
866                 return r;
867
868         free(fs);
869         fs = NULL;
870
871         r = cg_get_path(controller, NULL, "release_agent", &fs);
872         if (r < 0)
873                 return r;
874
875         r = write_string_file_no_create(fs, "");
876         if (r < 0)
877                 return r;
878
879         return 0;
880 }
881
882 int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
883         _cleanup_fclose_ FILE *f = NULL;
884         pid_t pid = 0, self_pid;
885         bool found = false;
886         int r;
887
888         assert(path);
889
890         r = cg_enumerate_processes(controller, path, &f);
891         if (r < 0)
892                 return r == -ENOENT ? 1 : r;
893
894         self_pid = getpid();
895
896         while ((r = cg_read_pid(f, &pid)) > 0) {
897
898                 if (ignore_self && pid == self_pid)
899                         continue;
900
901                 found = true;
902                 break;
903         }
904
905         if (r < 0)
906                 return r;
907
908         return !found;
909 }
910
911 int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self) {
912         _cleanup_closedir_ DIR *d = NULL;
913         char *fn;
914         int r;
915
916         assert(path);
917
918         r = cg_is_empty(controller, path, ignore_self);
919         if (r <= 0)
920                 return r;
921
922         r = cg_enumerate_subgroups(controller, path, &d);
923         if (r < 0)
924                 return r == -ENOENT ? 1 : r;
925
926         while ((r = cg_read_subgroup(d, &fn)) > 0) {
927                 _cleanup_free_ char *p = NULL;
928
929                 p = strjoin(path, "/", fn, NULL);
930                 free(fn);
931                 if (!p)
932                         return -ENOMEM;
933
934                 r = cg_is_empty_recursive(controller, p, ignore_self);
935                 if (r <= 0)
936                         return r;
937         }
938
939         if (r < 0)
940                 return r;
941
942         return 1;
943 }
944
945 int cg_split_spec(const char *spec, char **controller, char **path) {
946         const char *e;
947         char *t = NULL, *u = NULL;
948         _cleanup_free_ char *v = NULL;
949
950         assert(spec);
951
952         if (*spec == '/') {
953                 if (!path_is_safe(spec))
954                         return -EINVAL;
955
956                 if (path) {
957                         t = strdup(spec);
958                         if (!t)
959                                 return -ENOMEM;
960
961                         *path = path_kill_slashes(t);
962                 }
963
964                 if (controller)
965                         *controller = NULL;
966
967                 return 0;
968         }
969
970         e = strchr(spec, ':');
971         if (!e) {
972                 if (!cg_controller_is_valid(spec, true))
973                         return -EINVAL;
974
975                 if (controller) {
976                         t = strdup(normalize_controller(spec));
977                         if (!t)
978                                 return -ENOMEM;
979
980                         *controller = t;
981                 }
982
983                 if (path)
984                         *path = NULL;
985
986                 return 0;
987         }
988
989         v = strndup(spec, e-spec);
990         if (!v)
991                 return -ENOMEM;
992         t = strdup(normalize_controller(v));
993         if (!t)
994                 return -ENOMEM;
995         if (!cg_controller_is_valid(t, true)) {
996                 free(t);
997                 return -EINVAL;
998         }
999
1000         if (streq(e+1, "")) {
1001                 u = strdup("/");
1002                 if (!u) {
1003                         free(t);
1004                         return -ENOMEM;
1005                 }
1006         } else {
1007                 u = strdup(e+1);
1008                 if (!u) {
1009                         free(t);
1010                         return -ENOMEM;
1011                 }
1012
1013                 if (!path_is_safe(u) ||
1014                     !path_is_absolute(u)) {
1015                         free(t);
1016                         free(u);
1017                         return -EINVAL;
1018                 }
1019
1020                 path_kill_slashes(u);
1021         }
1022
1023         if (controller)
1024                 *controller = t;
1025         else
1026                 free(t);
1027
1028         if (path)
1029                 *path = u;
1030         else
1031                 free(u);
1032
1033         return 0;
1034 }
1035
1036 int cg_mangle_path(const char *path, char **result) {
1037         _cleanup_free_ char *c = NULL, *p = NULL;
1038         char *t;
1039         int r;
1040
1041         assert(path);
1042         assert(result);
1043
1044         /* First, check if it already is a filesystem path */
1045         if (path_startswith(path, "/sys/fs/cgroup")) {
1046
1047                 t = strdup(path);
1048                 if (!t)
1049                         return -ENOMEM;
1050
1051                 *result = path_kill_slashes(t);
1052                 return 0;
1053         }
1054
1055         /* Otherwise, treat it as cg spec */
1056         r = cg_split_spec(path, &c, &p);
1057         if (r < 0)
1058                 return r;
1059
1060         return cg_get_path(c ? c : SYSTEMD_CGROUP_CONTROLLER, p ? p : "/", NULL, result);
1061 }
1062
1063 int cg_get_root_path(char **path) {
1064         char *p, *e;
1065         int r;
1066
1067         assert(path);
1068
1069         r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &p);
1070         if (r < 0)
1071                 return r;
1072
1073         e = endswith(p, "/" SPECIAL_SYSTEM_SLICE);
1074         if (e)
1075                 *e = 0;
1076
1077         *path = p;
1078         return 0;
1079 }
1080
1081 int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
1082         _cleanup_free_ char *rt = NULL;
1083         char *p;
1084         int r;
1085
1086         assert(cgroup);
1087         assert(shifted);
1088
1089         if (!root) {
1090                 /* If the root was specified let's use that, otherwise
1091                  * let's determine it from PID 1 */
1092
1093                 r = cg_get_root_path(&rt);
1094                 if (r < 0)
1095                         return r;
1096
1097                 root = rt;
1098         }
1099
1100         p = path_startswith(cgroup, root);
1101         if (p)
1102                 *shifted = p - 1;
1103         else
1104                 *shifted = cgroup;
1105
1106         return 0;
1107 }
1108
1109 int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
1110         _cleanup_free_ char *raw = NULL;
1111         const char *c;
1112         int r;
1113
1114         assert(pid >= 0);
1115         assert(cgroup);
1116
1117         r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &raw);
1118         if (r < 0)
1119                 return r;
1120
1121         r = cg_shift_path(raw, root, &c);
1122         if (r < 0)
1123                 return r;
1124
1125         if (c == raw) {
1126                 *cgroup = raw;
1127                 raw = NULL;
1128         } else {
1129                 char *n;
1130
1131                 n = strdup(c);
1132                 if (!n)
1133                         return -ENOMEM;
1134
1135                 *cgroup = n;
1136         }
1137
1138         return 0;
1139 }
1140
1141 int cg_path_decode_unit(const char *cgroup, char **unit){
1142         char *e, *c, *s;
1143
1144         assert(cgroup);
1145         assert(unit);
1146
1147         e = strchrnul(cgroup, '/');
1148         c = strndupa(cgroup, e - cgroup);
1149         c = cg_unescape(c);
1150
1151         if (!unit_name_is_valid(c, TEMPLATE_INVALID))
1152                 return -ENXIO;
1153
1154         s = strdup(c);
1155         if (!s)
1156                 return -ENOMEM;
1157
1158         *unit = s;
1159         return 0;
1160 }
1161
1162 static const char *skip_slices(const char *p) {
1163         /* Skips over all slice assignments */
1164
1165         for (;;) {
1166                 size_t n;
1167
1168                 p += strspn(p, "/");
1169
1170                 n = strcspn(p, "/");
1171                 if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0)
1172                         return p;
1173
1174                 p += n;
1175         }
1176 }
1177
1178 int cg_path_get_unit(const char *path, char **unit) {
1179         const char *e;
1180
1181         assert(path);
1182         assert(unit);
1183
1184         e = skip_slices(path);
1185
1186         return cg_path_decode_unit(e, unit);
1187 }
1188
1189 int cg_pid_get_unit(pid_t pid, char **unit) {
1190         _cleanup_free_ char *cgroup = NULL;
1191         int r;
1192
1193         assert(unit);
1194
1195         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1196         if (r < 0)
1197                 return r;
1198
1199         return cg_path_get_unit(cgroup, unit);
1200 }
1201
1202 /**
1203  * Skip session-*.scope, but require it to be there.
1204  */
1205 static const char *skip_session(const char *p) {
1206         size_t n;
1207
1208         assert(p);
1209
1210         p += strspn(p, "/");
1211
1212         n = strcspn(p, "/");
1213         if (n < strlen("session-x.scope") || memcmp(p, "session-", 8) != 0 || memcmp(p + n - 6, ".scope", 6) != 0)
1214                 return NULL;
1215
1216         p += n;
1217         p += strspn(p, "/");
1218
1219         return p;
1220 }
1221
1222 /**
1223  * Skip user@*.service, but require it to be there.
1224  */
1225 static const char *skip_user_manager(const char *p) {
1226         size_t n;
1227
1228         assert(p);
1229
1230         p += strspn(p, "/");
1231
1232         n = strcspn(p, "/");
1233         if (n < strlen("user@x.service") || memcmp(p, "user@", 5) != 0 || memcmp(p + n - 8, ".service", 8) != 0)
1234                 return NULL;
1235
1236         p += n;
1237         p += strspn(p, "/");
1238
1239         return p;
1240 }
1241
1242 int cg_path_get_user_unit(const char *path, char **unit) {
1243         const char *e, *t;
1244
1245         assert(path);
1246         assert(unit);
1247
1248         /* We always have to parse the path from the beginning as unit
1249          * cgroups might have arbitrary child cgroups and we shouldn't get
1250          * confused by those */
1251
1252         /* Skip slices, if there are any */
1253         e = skip_slices(path);
1254
1255         /* Skip the session scope or user manager... */
1256         t = skip_session(e);
1257         if (!t)
1258                 t = skip_user_manager(e);
1259         if (!t)
1260                 return -ENXIO;
1261
1262         /* ... and skip more slices if there are any */
1263         e = skip_slices(t);
1264
1265         return cg_path_decode_unit(e, unit);
1266 }
1267
1268 int cg_pid_get_user_unit(pid_t pid, char **unit) {
1269         _cleanup_free_ char *cgroup = NULL;
1270         int r;
1271
1272         assert(unit);
1273
1274         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1275         if (r < 0)
1276                 return r;
1277
1278         return cg_path_get_user_unit(cgroup, unit);
1279 }
1280
1281 int cg_path_get_machine_name(const char *path, char **machine) {
1282         _cleanup_free_ char *u = NULL, *sl = NULL;
1283         int r;
1284
1285         r = cg_path_get_unit(path, &u);
1286         if (r < 0)
1287                 return r;
1288
1289         sl = strjoin("/run/systemd/machines/unit:", u, NULL);
1290         if (!sl)
1291                 return -ENOMEM;
1292
1293         return readlink_malloc(sl, machine);
1294 }
1295
1296 int cg_pid_get_machine_name(pid_t pid, char **machine) {
1297         _cleanup_free_ char *cgroup = NULL;
1298         int r;
1299
1300         assert(machine);
1301
1302         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1303         if (r < 0)
1304                 return r;
1305
1306         return cg_path_get_machine_name(cgroup, machine);
1307 }
1308
1309 int cg_path_get_session(const char *path, char **session) {
1310         const char *e, *n, *x, *y;
1311         char *s;
1312
1313         assert(path);
1314
1315         /* Skip slices, if there are any */
1316         e = skip_slices(path);
1317
1318         n = strchrnul(e, '/');
1319         if (e == n)
1320                 return -ENXIO;
1321
1322         s = strndupa(e, n - e);
1323         s = cg_unescape(s);
1324
1325         x = startswith(s, "session-");
1326         if (!x)
1327                 return -ENXIO;
1328         y = endswith(x, ".scope");
1329         if (!y || x == y)
1330                 return -ENXIO;
1331
1332         if (session) {
1333                 char *r;
1334
1335                 r = strndup(x, y - x);
1336                 if (!r)
1337                         return -ENOMEM;
1338
1339                 *session = r;
1340         }
1341
1342         return 0;
1343 }
1344
1345 int cg_pid_get_session(pid_t pid, char **session) {
1346         _cleanup_free_ char *cgroup = NULL;
1347         int r;
1348
1349         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1350         if (r < 0)
1351                 return r;
1352
1353         return cg_path_get_session(cgroup, session);
1354 }
1355
1356 int cg_path_get_owner_uid(const char *path, uid_t *uid) {
1357         _cleanup_free_ char *slice = NULL;
1358         const char *start, *end;
1359         char *s;
1360         uid_t u;
1361         int r;
1362
1363         assert(path);
1364
1365         r = cg_path_get_slice(path, &slice);
1366         if (r < 0)
1367                 return r;
1368
1369         start = startswith(slice, "user-");
1370         if (!start)
1371                 return -ENXIO;
1372         end = endswith(slice, ".slice");
1373         if (!end)
1374                 return -ENXIO;
1375
1376         s = strndupa(start, end - start);
1377         if (!s)
1378                 return -ENXIO;
1379
1380         if (parse_uid(s, &u) < 0)
1381                 return -ENXIO;
1382
1383         if (uid)
1384                 *uid = u;
1385
1386         return 0;
1387 }
1388
1389 int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) {
1390         _cleanup_free_ char *cgroup = NULL;
1391         int r;
1392
1393         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1394         if (r < 0)
1395                 return r;
1396
1397         return cg_path_get_owner_uid(cgroup, uid);
1398 }
1399
1400 int cg_path_get_slice(const char *p, char **slice) {
1401         const char *e = NULL;
1402         size_t m = 0;
1403
1404         assert(p);
1405         assert(slice);
1406
1407         for (;;) {
1408                 size_t n;
1409
1410                 p += strspn(p, "/");
1411
1412                 n = strcspn(p, "/");
1413                 if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0) {
1414                         char *s;
1415
1416                         if (!e)
1417                                 return -ENXIO;
1418
1419                         s = strndup(e, m);
1420                         if (!s)
1421                                 return -ENOMEM;
1422
1423                         *slice = s;
1424                         return 0;
1425                 }
1426
1427                 e = p;
1428                 m = n;
1429
1430                 p += n;
1431         }
1432 }
1433
1434 int cg_pid_get_slice(pid_t pid, char **slice) {
1435         _cleanup_free_ char *cgroup = NULL;
1436         int r;
1437
1438         assert(slice);
1439
1440         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1441         if (r < 0)
1442                 return r;
1443
1444         return cg_path_get_slice(cgroup, slice);
1445 }
1446
1447 char *cg_escape(const char *p) {
1448         bool need_prefix = false;
1449
1450         /* This implements very minimal escaping for names to be used
1451          * as file names in the cgroup tree: any name which might
1452          * conflict with a kernel name or is prefixed with '_' is
1453          * prefixed with a '_'. That way, when reading cgroup names it
1454          * is sufficient to remove a single prefixing underscore if
1455          * there is one. */
1456
1457         /* The return value of this function (unlike cg_unescape())
1458          * needs free()! */
1459
1460         if (p[0] == 0 ||
1461             p[0] == '_' ||
1462             p[0] == '.' ||
1463             streq(p, "notify_on_release") ||
1464             streq(p, "release_agent") ||
1465             streq(p, "tasks"))
1466                 need_prefix = true;
1467         else {
1468                 const char *dot;
1469
1470                 dot = strrchr(p, '.');
1471                 if (dot) {
1472
1473                         if (dot - p == 6 && memcmp(p, "cgroup", 6) == 0)
1474                                 need_prefix = true;
1475                         else {
1476                                 char *n;
1477
1478                                 n = strndupa(p, dot - p);
1479
1480                                 if (check_hierarchy(n) >= 0)
1481                                         need_prefix = true;
1482                         }
1483                 }
1484         }
1485
1486         if (need_prefix)
1487                 return strappend("_", p);
1488         else
1489                 return strdup(p);
1490 }
1491
1492 char *cg_unescape(const char *p) {
1493         assert(p);
1494
1495         /* The return value of this function (unlike cg_escape())
1496          * doesn't need free()! */
1497
1498         if (p[0] == '_')
1499                 return (char*) p+1;
1500
1501         return (char*) p;
1502 }
1503
1504 #define CONTROLLER_VALID                        \
1505         DIGITS LETTERS                          \
1506         "_"
1507
1508 bool cg_controller_is_valid(const char *p, bool allow_named) {
1509         const char *t, *s;
1510
1511         if (!p)
1512                 return false;
1513
1514         if (allow_named) {
1515                 s = startswith(p, "name=");
1516                 if (s)
1517                         p = s;
1518         }
1519
1520         if (*p == 0 || *p == '_')
1521                 return false;
1522
1523         for (t = p; *t; t++)
1524                 if (!strchr(CONTROLLER_VALID, *t))
1525                         return false;
1526
1527         if (t - p > FILENAME_MAX)
1528                 return false;
1529
1530         return true;
1531 }
1532
1533 int cg_slice_to_path(const char *unit, char **ret) {
1534         _cleanup_free_ char *p = NULL, *s = NULL, *e = NULL;
1535         const char *dash;
1536
1537         assert(unit);
1538         assert(ret);
1539
1540         if (!unit_name_is_valid(unit, TEMPLATE_INVALID))
1541                 return -EINVAL;
1542
1543         if (!endswith(unit, ".slice"))
1544                 return -EINVAL;
1545
1546         p = unit_name_to_prefix(unit);
1547         if (!p)
1548                 return -ENOMEM;
1549
1550         dash = strchr(p, '-');
1551         while (dash) {
1552                 _cleanup_free_ char *escaped = NULL;
1553                 char n[dash - p + sizeof(".slice")];
1554
1555                 strcpy(stpncpy(n, p, dash - p), ".slice");
1556
1557                 if (!unit_name_is_valid(n, TEMPLATE_INVALID))
1558                         return -EINVAL;
1559
1560                 escaped = cg_escape(n);
1561                 if (!escaped)
1562                         return -ENOMEM;
1563
1564                 if (!strextend(&s, escaped, "/", NULL))
1565                         return -ENOMEM;
1566
1567                 dash = strchr(dash+1, '-');
1568         }
1569
1570         e = cg_escape(unit);
1571         if (!e)
1572                 return -ENOMEM;
1573
1574         if (!strextend(&s, e, NULL))
1575                 return -ENOMEM;
1576
1577         *ret = s;
1578         s = NULL;
1579
1580         return 0;
1581 }
1582
1583 int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value) {
1584         _cleanup_free_ char *p = NULL;
1585         int r;
1586
1587         r = cg_get_path(controller, path, attribute, &p);
1588         if (r < 0)
1589                 return r;
1590
1591         return write_string_file_no_create(p, value);
1592 }
1593
1594 int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret) {
1595         _cleanup_free_ char *p = NULL;
1596         int r;
1597
1598         r = cg_get_path(controller, path, attribute, &p);
1599         if (r < 0)
1600                 return r;
1601
1602         return read_one_line_file(p, ret);
1603 }
1604
1605 static const char mask_names[] =
1606         "cpu\0"
1607         "cpuacct\0"
1608         "blkio\0"
1609         "memory\0"
1610         "devices\0";
1611
1612 int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path) {
1613         CGroupControllerMask bit = 1;
1614         const char *n;
1615         int r;
1616
1617         /* This one will create a cgroup in our private tree, but also
1618          * duplicate it in the trees specified in mask, and remove it
1619          * in all others */
1620
1621         /* First create the cgroup in our own hierarchy. */
1622         r = cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
1623         if (r < 0)
1624                 return r;
1625
1626         /* Then, do the same in the other hierarchies */
1627         NULSTR_FOREACH(n, mask_names) {
1628                 if (mask & bit)
1629                         cg_create(n, path);
1630                 else if (supported & bit)
1631                         cg_trim(n, path, true);
1632
1633                 bit <<= 1;
1634         }
1635
1636         return 0;
1637 }
1638
1639 int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) {
1640         CGroupControllerMask bit = 1;
1641         const char *n;
1642         int r;
1643
1644         r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid);
1645         if (r < 0)
1646                 return r;
1647
1648         NULSTR_FOREACH(n, mask_names) {
1649
1650                 if (supported & bit) {
1651                         const char *p = NULL;
1652
1653                         if (path_callback)
1654                                 p = path_callback(bit, userdata);
1655
1656                         if (!p)
1657                                 p = path;
1658
1659                         cg_attach_fallback(n, path, pid);
1660                 }
1661
1662                 bit <<= 1;
1663         }
1664
1665         return 0;
1666 }
1667
1668 int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids, cg_migrate_callback_t path_callback, void *userdata) {
1669         Iterator i;
1670         void *pidp;
1671         int r = 0;
1672
1673         SET_FOREACH(pidp, pids, i) {
1674                 pid_t pid = PTR_TO_LONG(pidp);
1675                 int q;
1676
1677                 q = cg_attach_everywhere(supported, path, pid, path_callback, userdata);
1678                 if (q < 0)
1679                         r = q;
1680         }
1681
1682         return r;
1683 }
1684
1685 int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to, cg_migrate_callback_t to_callback, void *userdata) {
1686         CGroupControllerMask bit = 1;
1687         const char *n;
1688         int r;
1689
1690         if (!path_equal(from, to))  {
1691                 r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true);
1692                 if (r < 0)
1693                         return r;
1694         }
1695
1696         NULSTR_FOREACH(n, mask_names) {
1697                 if (supported & bit) {
1698                         const char *p = NULL;
1699
1700                         if (to_callback)
1701                                 p = to_callback(bit, userdata);
1702
1703                         if (!p)
1704                                 p = to;
1705
1706                         cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, p, false, false);
1707                 }
1708
1709                 bit <<= 1;
1710         }
1711
1712         return 0;
1713 }
1714
1715 int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root) {
1716         CGroupControllerMask bit = 1;
1717         const char *n;
1718         int r;
1719
1720         r = cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root);
1721         if (r < 0)
1722                 return r;
1723
1724         NULSTR_FOREACH(n, mask_names) {
1725                 if (supported & bit)
1726                         cg_trim(n, path, delete_root);
1727
1728                 bit <<= 1;
1729         }
1730
1731         return 0;
1732 }
1733
1734 CGroupControllerMask cg_mask_supported(void) {
1735         CGroupControllerMask bit = 1, mask = 0;
1736         const char *n;
1737
1738         NULSTR_FOREACH(n, mask_names) {
1739                 if (check_hierarchy(n) >= 0)
1740                         mask |= bit;
1741
1742                 bit <<= 1;
1743         }
1744
1745         return mask;
1746 }
1747
1748 int cg_kernel_controllers(Set *controllers) {
1749         _cleanup_fclose_ FILE *f = NULL;
1750         char buf[LINE_MAX];
1751         int r;
1752
1753         assert(controllers);
1754
1755         f = fopen("/proc/cgroups", "re");
1756         if (!f) {
1757                 if (errno == ENOENT)
1758                         return 0;
1759                 return -errno;
1760         }
1761
1762         /* Ignore the header line */
1763         (void) fgets(buf, sizeof(buf), f);
1764
1765         for (;;) {
1766                 char *controller;
1767                 int enabled = 0;
1768
1769                 errno = 0;
1770                 if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) {
1771
1772                         if (feof(f))
1773                                 break;
1774
1775                         if (ferror(f) && errno)
1776                                 return -errno;
1777
1778                         return -EBADMSG;
1779                 }
1780
1781                 if (!enabled) {
1782                         free(controller);
1783                         continue;
1784                 }
1785
1786                 if (!filename_is_valid(controller)) {
1787                         free(controller);
1788                         return -EBADMSG;
1789                 }
1790
1791                 r = set_consume(controllers, controller);
1792                 if (r < 0)
1793                         return r;
1794         }
1795
1796         return 0;
1797 }