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