chiark / gitweb /
bus: update kdbus.h (ABI break)
[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         fs = procfs_file_alloca(pid, "cgroup");
750
751         f = fopen(fs, "re");
752         if (!f)
753                 return errno == ENOENT ? -ESRCH : -errno;
754
755         cs = strlen(controller);
756
757         FOREACH_LINE(line, f, return -errno) {
758                 char *l, *p, *w, *e;
759                 size_t k;
760                 char *state;
761                 bool found = false;
762
763                 truncate_nl(line);
764
765                 l = strchr(line, ':');
766                 if (!l)
767                         continue;
768
769                 l++;
770                 e = strchr(l, ':');
771                 if (!e)
772                         continue;
773
774                 *e = 0;
775
776                 FOREACH_WORD_SEPARATOR(w, k, l, ",", state) {
777
778                         if (k == cs && memcmp(w, controller, cs) == 0) {
779                                 found = true;
780                                 break;
781                         }
782
783                         if (k == 5 + cs &&
784                             memcmp(w, "name=", 5) == 0 &&
785                             memcmp(w+5, controller, cs) == 0) {
786                                 found = true;
787                                 break;
788                         }
789                 }
790
791                 if (!found)
792                         continue;
793
794                 p = strdup(e + 1);
795                 if (!p)
796                         return -ENOMEM;
797
798                 *path = p;
799                 return 0;
800         }
801
802         return -ENOENT;
803 }
804
805 int cg_install_release_agent(const char *controller, const char *agent) {
806         _cleanup_free_ char *fs = NULL, *contents = NULL;
807         char *sc;
808         int r;
809
810         assert(agent);
811
812         r = cg_get_path(controller, NULL, "release_agent", &fs);
813         if (r < 0)
814                 return r;
815
816         r = read_one_line_file(fs, &contents);
817         if (r < 0)
818                 return r;
819
820         sc = strstrip(contents);
821         if (sc[0] == 0) {
822                 r = write_string_file(fs, agent);
823                 if (r < 0)
824                         return r;
825         } else if (!streq(sc, agent))
826                 return -EEXIST;
827
828         free(fs);
829         fs = NULL;
830         r = cg_get_path(controller, NULL, "notify_on_release", &fs);
831         if (r < 0)
832                 return r;
833
834         free(contents);
835         contents = NULL;
836         r = read_one_line_file(fs, &contents);
837         if (r < 0)
838                 return r;
839
840         sc = strstrip(contents);
841         if (streq(sc, "0")) {
842                 r = write_string_file(fs, "1");
843                 if (r < 0)
844                         return r;
845
846                 return 1;
847         }
848
849         if (!streq(sc, "1"))
850                 return -EIO;
851
852         return 0;
853 }
854
855 int cg_uninstall_release_agent(const char *controller) {
856         _cleanup_free_ char *fs = NULL;
857         int r;
858
859         r = cg_get_path(controller, NULL, "notify_on_release", &fs);
860         if (r < 0)
861                 return r;
862
863         r = write_string_file(fs, "0");
864         if (r < 0)
865                 return r;
866
867         free(fs);
868         fs = NULL;
869
870         r = cg_get_path(controller, NULL, "release_agent", &fs);
871         if (r < 0)
872                 return r;
873
874         r = write_string_file(fs, "");
875         if (r < 0)
876                 return r;
877
878         return 0;
879 }
880
881 int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
882         _cleanup_fclose_ FILE *f = NULL;
883         pid_t pid = 0, self_pid;
884         bool found = false;
885         int r;
886
887         assert(path);
888
889         r = cg_enumerate_processes(controller, path, &f);
890         if (r < 0)
891                 return r == -ENOENT ? 1 : r;
892
893         self_pid = getpid();
894
895         while ((r = cg_read_pid(f, &pid)) > 0) {
896
897                 if (ignore_self && pid == self_pid)
898                         continue;
899
900                 found = true;
901                 break;
902         }
903
904         if (r < 0)
905                 return r;
906
907         return !found;
908 }
909
910 int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self) {
911         _cleanup_closedir_ DIR *d = NULL;
912         char *fn;
913         int r;
914
915         assert(path);
916
917         r = cg_is_empty(controller, path, ignore_self);
918         if (r <= 0)
919                 return r;
920
921         r = cg_enumerate_subgroups(controller, path, &d);
922         if (r < 0)
923                 return r == -ENOENT ? 1 : r;
924
925         while ((r = cg_read_subgroup(d, &fn)) > 0) {
926                 _cleanup_free_ char *p = NULL;
927
928                 p = strjoin(path, "/", fn, NULL);
929                 free(fn);
930                 if (!p)
931                         return -ENOMEM;
932
933                 r = cg_is_empty_recursive(controller, p, ignore_self);
934                 if (r <= 0)
935                         return r;
936         }
937
938         if (r < 0)
939                 return r;
940
941         return 1;
942 }
943
944 int cg_split_spec(const char *spec, char **controller, char **path) {
945         const char *e;
946         char *t = NULL, *u = NULL;
947         _cleanup_free_ char *v = NULL;
948
949         assert(spec);
950
951         if (*spec == '/') {
952                 if (!path_is_safe(spec))
953                         return -EINVAL;
954
955                 if (path) {
956                         t = strdup(spec);
957                         if (!t)
958                                 return -ENOMEM;
959
960                         path_kill_slashes(t);
961                         *path = 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                 path_kill_slashes(t);
1052                 *result = t;
1053                 return 0;
1054         }
1055
1056         /* Otherwise treat it as cg spec */
1057         r = cg_split_spec(path, &c, &p);
1058         if (r < 0)
1059                 return r;
1060
1061         return cg_get_path(c ? c : SYSTEMD_CGROUP_CONTROLLER, p ? p : "/", NULL, result);
1062 }
1063
1064 int cg_get_root_path(char **path) {
1065         char *p, *e;
1066         int r;
1067
1068         assert(path);
1069
1070         r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &p);
1071         if (r < 0)
1072                 return r;
1073
1074         e = endswith(p, "/" SPECIAL_SYSTEM_SLICE);
1075         if (e)
1076                 *e = 0;
1077
1078         *path = p;
1079         return 0;
1080 }
1081
1082 int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
1083         _cleanup_free_ char *rt = NULL;
1084         char *p;
1085         int r;
1086
1087         assert(cgroup);
1088         assert(shifted);
1089
1090         if (!root) {
1091                 /* If the root was specified let's use that, otherwise
1092                  * let's determine it from PID 1 */
1093
1094                 r = cg_get_root_path(&rt);
1095                 if (r < 0)
1096                         return r;
1097
1098                 root = rt;
1099         }
1100
1101         p = path_startswith(cgroup, root);
1102         if (p)
1103                 *shifted = p - 1;
1104         else
1105                 *shifted = cgroup;
1106
1107         return 0;
1108 }
1109
1110 int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
1111         _cleanup_free_ char *raw = NULL;
1112         const char *c;
1113         int r;
1114
1115         assert(pid >= 0);
1116         assert(cgroup);
1117
1118         r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &raw);
1119         if (r < 0)
1120                 return r;
1121
1122         r = cg_shift_path(raw, root, &c);
1123         if (r < 0)
1124                 return r;
1125
1126         if (c == raw) {
1127                 *cgroup = raw;
1128                 raw = NULL;
1129         } else {
1130                 char *n;
1131
1132                 n = strdup(c);
1133                 if (!n)
1134                         return -ENOMEM;
1135
1136                 *cgroup = n;
1137         }
1138
1139         return 0;
1140 }
1141
1142 int cg_path_decode_unit(const char *cgroup, char **unit){
1143         char *e, *c, *s;
1144
1145         assert(cgroup);
1146         assert(unit);
1147
1148         e = strchrnul(cgroup, '/');
1149         c = strndupa(cgroup, e - cgroup);
1150         c = cg_unescape(c);
1151
1152         if (!unit_name_is_valid(c, TEMPLATE_INVALID))
1153                 return -EINVAL;
1154
1155         s = strdup(c);
1156         if (!s)
1157                 return -ENOMEM;
1158
1159         *unit = s;
1160         return 0;
1161 }
1162
1163 static const char *skip_slices(const char *p) {
1164         /* Skips over all slice assignments */
1165
1166         for (;;) {
1167                 size_t n;
1168
1169                 p += strspn(p, "/");
1170
1171                 n = strcspn(p, "/");
1172                 if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0)
1173                         return p;
1174
1175                 p += n;
1176         }
1177 }
1178
1179 int cg_path_get_unit(const char *path, char **unit) {
1180         const char *e;
1181
1182         assert(path);
1183         assert(unit);
1184
1185         e = skip_slices(path);
1186
1187         return cg_path_decode_unit(e, unit);
1188 }
1189
1190 int cg_pid_get_unit(pid_t pid, char **unit) {
1191         _cleanup_free_ char *cgroup = NULL;
1192         int r;
1193
1194         assert(unit);
1195
1196         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1197         if (r < 0)
1198                 return r;
1199
1200         return cg_path_get_unit(cgroup, unit);
1201 }
1202
1203 /**
1204  * Skip session-*.scope, but require it to be there.
1205  */
1206 static const char *skip_session(const char *p) {
1207         size_t n;
1208
1209         assert(p);
1210
1211         p += strspn(p, "/");
1212
1213         n = strcspn(p, "/");
1214         if (n < strlen("session-x.scope") || memcmp(p, "session-", 8) != 0 || memcmp(p + n - 6, ".scope", 6) != 0)
1215                 return NULL;
1216
1217         p += n;
1218         p += strspn(p, "/");
1219
1220         return p;
1221 }
1222
1223 /**
1224  * Skip user@*.service, but require it to be there.
1225  */
1226 static const char *skip_user_manager(const char *p) {
1227         size_t n;
1228
1229         assert(p);
1230
1231         p += strspn(p, "/");
1232
1233         n = strcspn(p, "/");
1234         if (n < strlen("user@x.service") || memcmp(p, "user@", 5) != 0 || memcmp(p + n - 8, ".service", 8) != 0)
1235                 return NULL;
1236
1237         p += n;
1238         p += strspn(p, "/");
1239
1240         return p;
1241 }
1242
1243 int cg_path_get_user_unit(const char *path, char **unit) {
1244         const char *e, *t;
1245
1246         assert(path);
1247         assert(unit);
1248
1249         /* We always have to parse the path from the beginning as unit
1250          * cgroups might have arbitrary child cgroups and we shouldn't get
1251          * confused by those */
1252
1253         /* Skip slices, if there are any */
1254         e = skip_slices(path);
1255
1256         /* Skip the session scope... */
1257         t = skip_session(e);
1258         if (t)
1259                 /* ... and skip more slices if there's one */
1260                 e = skip_slices(t);
1261         else {
1262                 /* ... or require a user manager unit to be there */
1263                 e = skip_user_manager(e);
1264                 if (!e)
1265                         return -ENOENT;
1266         }
1267
1268         return cg_path_decode_unit(e, unit);
1269 }
1270
1271 int cg_pid_get_user_unit(pid_t pid, char **unit) {
1272         _cleanup_free_ char *cgroup = NULL;
1273         int r;
1274
1275         assert(unit);
1276
1277         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1278         if (r < 0)
1279                 return r;
1280
1281         return cg_path_get_user_unit(cgroup, unit);
1282 }
1283
1284 int cg_path_get_machine_name(const char *path, char **machine) {
1285         const char *e, *n, *x;
1286         char *s, *r;
1287         size_t l;
1288
1289         assert(path);
1290         assert(machine);
1291
1292         /* Skip slices, if there are any */
1293         e = skip_slices(path);
1294
1295         n = strchrnul(e, '/');
1296         if (e == n)
1297                 return -ENOENT;
1298
1299         s = strndupa(e, n - e);
1300         s = cg_unescape(s);
1301
1302         x = startswith(s, "machine-");
1303         if (!x)
1304                 return -ENOENT;
1305         if (!endswith(x, ".scope"))
1306                 return -ENOENT;
1307
1308         l = strlen(x);
1309         if (l <= 6)
1310                 return -ENOENT;
1311
1312         r = strndup(x, l - 6);
1313         if (!r)
1314                 return -ENOMEM;
1315
1316         *machine = r;
1317         return 0;
1318 }
1319
1320 int cg_pid_get_machine_name(pid_t pid, char **machine) {
1321         _cleanup_free_ char *cgroup = NULL;
1322         int r;
1323
1324         assert(machine);
1325
1326         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1327         if (r < 0)
1328                 return r;
1329
1330         return cg_path_get_machine_name(cgroup, machine);
1331 }
1332
1333 int cg_path_get_session(const char *path, char **session) {
1334         const char *e, *n, *x;
1335         char *s, *r;
1336         size_t l;
1337
1338         assert(path);
1339         assert(session);
1340
1341         /* Skip slices, if there are any */
1342         e = skip_slices(path);
1343
1344         n = strchrnul(e, '/');
1345         if (e == n)
1346                 return -ENOENT;
1347
1348         s = strndupa(e, n - e);
1349         s = cg_unescape(s);
1350
1351         x = startswith(s, "session-");
1352         if (!x)
1353                 return -ENOENT;
1354         if (!endswith(x, ".scope"))
1355                 return -ENOENT;
1356
1357         l = strlen(x);
1358         if (l <= 6)
1359                 return -ENOENT;
1360
1361         r = strndup(x, l - 6);
1362         if (!r)
1363                 return -ENOMEM;
1364
1365         *session = r;
1366         return 0;
1367 }
1368
1369 int cg_pid_get_session(pid_t pid, char **session) {
1370         _cleanup_free_ char *cgroup = NULL;
1371         int r;
1372
1373         assert(session);
1374
1375         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1376         if (r < 0)
1377                 return r;
1378
1379         return cg_path_get_session(cgroup, session);
1380 }
1381
1382 int cg_path_get_owner_uid(const char *path, uid_t *uid) {
1383         _cleanup_free_ char *slice = NULL;
1384         const char *start, *end;
1385         char *s;
1386         uid_t u;
1387         int r;
1388
1389         assert(path);
1390
1391         r = cg_path_get_slice(path, &slice);
1392         if (r < 0)
1393                 return r;
1394
1395         start = startswith(slice, "user-");
1396         if (!start)
1397                 return -ENOENT;
1398         end = endswith(slice, ".slice");
1399         if (!end)
1400                 return -ENOENT;
1401
1402         s = strndupa(start, end - start);
1403         if (!s)
1404                 return -ENOENT;
1405
1406         if (parse_uid(s, &u) < 0)
1407                 return -EIO;
1408
1409         if (uid)
1410                 *uid = u;
1411
1412         return 0;
1413 }
1414
1415 int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) {
1416         _cleanup_free_ char *cgroup = NULL;
1417         int r;
1418
1419         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1420         if (r < 0)
1421                 return r;
1422
1423         return cg_path_get_owner_uid(cgroup, uid);
1424 }
1425
1426 int cg_path_get_slice(const char *p, char **slice) {
1427         const char *e = NULL;
1428         size_t m = 0;
1429
1430         assert(p);
1431         assert(slice);
1432
1433         for (;;) {
1434                 size_t n;
1435
1436                 p += strspn(p, "/");
1437
1438                 n = strcspn(p, "/");
1439                 if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0) {
1440                         char *s;
1441
1442                         if (!e)
1443                                 return -ENOENT;
1444
1445                         s = strndup(e, m);
1446                         if (!s)
1447                                 return -ENOMEM;
1448
1449                         *slice = s;
1450                         return 0;
1451                 }
1452
1453                 e = p;
1454                 m = n;
1455
1456                 p += n;
1457         }
1458 }
1459
1460 int cg_pid_get_slice(pid_t pid, char **slice) {
1461         _cleanup_free_ char *cgroup = NULL;
1462         int r;
1463
1464         assert(slice);
1465
1466         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1467         if (r < 0)
1468                 return r;
1469
1470         return cg_path_get_slice(cgroup, slice);
1471 }
1472
1473 char *cg_escape(const char *p) {
1474         bool need_prefix = false;
1475
1476         /* This implements very minimal escaping for names to be used
1477          * as file names in the cgroup tree: any name which might
1478          * conflict with a kernel name or is prefixed with '_' is
1479          * prefixed with a '_'. That way, when reading cgroup names it
1480          * is sufficient to remove a single prefixing underscore if
1481          * there is one. */
1482
1483         /* The return value of this function (unlike cg_unescape())
1484          * needs free()! */
1485
1486         if (p[0] == 0 ||
1487             p[0] == '_' ||
1488             p[0] == '.' ||
1489             streq(p, "notify_on_release") ||
1490             streq(p, "release_agent") ||
1491             streq(p, "tasks"))
1492                 need_prefix = true;
1493         else {
1494                 const char *dot;
1495
1496                 dot = strrchr(p, '.');
1497                 if (dot) {
1498
1499                         if (dot - p == 6 && memcmp(p, "cgroup", 6) == 0)
1500                                 need_prefix = true;
1501                         else {
1502                                 char *n;
1503
1504                                 n = strndupa(p, dot - p);
1505
1506                                 if (check_hierarchy(n) >= 0)
1507                                         need_prefix = true;
1508                         }
1509                 }
1510         }
1511
1512         if (need_prefix)
1513                 return strappend("_", p);
1514         else
1515                 return strdup(p);
1516 }
1517
1518 char *cg_unescape(const char *p) {
1519         assert(p);
1520
1521         /* The return value of this function (unlike cg_escape())
1522          * doesn't need free()! */
1523
1524         if (p[0] == '_')
1525                 return (char*) p+1;
1526
1527         return (char*) p;
1528 }
1529
1530 #define CONTROLLER_VALID                        \
1531         DIGITS LETTERS                          \
1532         "_"
1533
1534 bool cg_controller_is_valid(const char *p, bool allow_named) {
1535         const char *t, *s;
1536
1537         if (!p)
1538                 return false;
1539
1540         if (allow_named) {
1541                 s = startswith(p, "name=");
1542                 if (s)
1543                         p = s;
1544         }
1545
1546         if (*p == 0 || *p == '_')
1547                 return false;
1548
1549         for (t = p; *t; t++)
1550                 if (!strchr(CONTROLLER_VALID, *t))
1551                         return false;
1552
1553         if (t - p > FILENAME_MAX)
1554                 return false;
1555
1556         return true;
1557 }
1558
1559 int cg_slice_to_path(const char *unit, char **ret) {
1560         _cleanup_free_ char *p = NULL, *s = NULL, *e = NULL;
1561         const char *dash;
1562
1563         assert(unit);
1564         assert(ret);
1565
1566         if (!unit_name_is_valid(unit, TEMPLATE_INVALID))
1567                 return -EINVAL;
1568
1569         if (!endswith(unit, ".slice"))
1570                 return -EINVAL;
1571
1572         p = unit_name_to_prefix(unit);
1573         if (!p)
1574                 return -ENOMEM;
1575
1576         dash = strchr(p, '-');
1577         while (dash) {
1578                 _cleanup_free_ char *escaped = NULL;
1579                 char n[dash - p + sizeof(".slice")];
1580
1581                 strcpy(stpncpy(n, p, dash - p), ".slice");
1582
1583                 if (!unit_name_is_valid(n, TEMPLATE_INVALID))
1584                         return -EINVAL;
1585
1586                 escaped = cg_escape(n);
1587                 if (!escaped)
1588                         return -ENOMEM;
1589
1590                 if (!strextend(&s, escaped, "/", NULL))
1591                         return -ENOMEM;
1592
1593                 dash = strchr(dash+1, '-');
1594         }
1595
1596         e = cg_escape(unit);
1597         if (!e)
1598                 return -ENOMEM;
1599
1600         if (!strextend(&s, e, NULL))
1601                 return -ENOMEM;
1602
1603         *ret = s;
1604         s = NULL;
1605
1606         return 0;
1607 }
1608
1609 int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value) {
1610         _cleanup_free_ char *p = NULL;
1611         int r;
1612
1613         r = cg_get_path(controller, path, attribute, &p);
1614         if (r < 0)
1615                 return r;
1616
1617         return write_string_file(p, value);
1618 }
1619
1620 static const char mask_names[] =
1621         "cpu\0"
1622         "cpuacct\0"
1623         "blkio\0"
1624         "memory\0"
1625         "devices\0";
1626
1627 int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path) {
1628         CGroupControllerMask bit = 1;
1629         const char *n;
1630         int r;
1631
1632         /* This one will create a cgroup in our private tree, but also
1633          * duplicate it in the trees specified in mask, and remove it
1634          * in all others */
1635
1636         /* First create the cgroup in our own hierarchy. */
1637         r = cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
1638         if (r < 0)
1639                 return r;
1640
1641         /* Then, do the same in the other hierarchies */
1642         NULSTR_FOREACH(n, mask_names) {
1643                 if (mask & bit)
1644                         cg_create(n, path);
1645                 else if (supported & bit)
1646                         cg_trim(n, path, true);
1647
1648                 bit <<= 1;
1649         }
1650
1651         return 0;
1652 }
1653
1654 int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid) {
1655         CGroupControllerMask bit = 1;
1656         const char *n;
1657         int r;
1658
1659         r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid);
1660         if (r < 0)
1661                 return r;
1662
1663         NULSTR_FOREACH(n, mask_names) {
1664                 if (supported & bit)
1665                         cg_attach_fallback(n, path, pid);
1666
1667                 bit <<= 1;
1668         }
1669
1670         return 0;
1671 }
1672
1673 int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids) {
1674         Iterator i;
1675         void *pidp;
1676         int r = 0;
1677
1678         SET_FOREACH(pidp, pids, i) {
1679                 pid_t pid = PTR_TO_LONG(pidp);
1680                 int q;
1681
1682                 q = cg_attach_everywhere(supported, path, pid);
1683                 if (q < 0)
1684                         r = q;
1685         }
1686
1687         return r;
1688 }
1689
1690 int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to) {
1691         CGroupControllerMask bit = 1;
1692         const char *n;
1693         int r;
1694
1695         if (!path_equal(from, to))  {
1696                 r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true);
1697                 if (r < 0)
1698                         return r;
1699         }
1700
1701         NULSTR_FOREACH(n, mask_names) {
1702                 if (supported & bit)
1703                         cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, to, false, false);
1704
1705                 bit <<= 1;
1706         }
1707
1708         return 0;
1709 }
1710
1711 int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root) {
1712         CGroupControllerMask bit = 1;
1713         const char *n;
1714         int r;
1715
1716         r = cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root);
1717         if (r < 0)
1718                 return r;
1719
1720         NULSTR_FOREACH(n, mask_names) {
1721                 if (supported & bit)
1722                         cg_trim(n, path, delete_root);
1723
1724                 bit <<= 1;
1725         }
1726
1727         return 0;
1728 }
1729
1730 CGroupControllerMask cg_mask_supported(void) {
1731         CGroupControllerMask bit = 1, mask = 0;
1732         const char *n;
1733
1734         NULSTR_FOREACH(n, mask_names) {
1735                 if (check_hierarchy(n) >= 0)
1736                         mask |= bit;
1737
1738                 bit <<= 1;
1739         }
1740
1741         return mask;
1742 }