chiark / gitweb /
c746d606d9ff648c29cbcd530d579b5e87acd547
[elogind.git] / src / shared / cgroup-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <unistd.h>
24 #include <signal.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <dirent.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <ftw.h>
31
32 #include "cgroup-util.h"
33 #include "set.h"
34 #include "macro.h"
35 #include "util.h"
36 #include "formats-util.h"
37 #include "path-util.h"
38 #include "fileio.h"
39 #include "special.h"
40 #include "mkdir.h"
41
42 int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
43         _cleanup_free_ char *fs = NULL;
44         FILE *f;
45         int r;
46
47         assert(_f);
48
49         r = cg_get_path(controller, path, "cgroup.procs", &fs);
50         if (r < 0)
51                 return r;
52
53         f = fopen(fs, "re");
54         if (!f)
55                 return -errno;
56
57         *_f = f;
58         return 0;
59 }
60
61 int cg_read_pid(FILE *f, pid_t *_pid) {
62         unsigned long ul;
63
64         /* Note that the cgroup.procs might contain duplicates! See
65          * cgroups.txt for details. */
66
67         assert(f);
68         assert(_pid);
69
70         errno = 0;
71         if (fscanf(f, "%lu", &ul) != 1) {
72
73                 if (feof(f))
74                         return 0;
75
76                 return errno ? -errno : -EIO;
77         }
78
79         if (ul <= 0)
80                 return -EIO;
81
82         *_pid = (pid_t) ul;
83         return 1;
84 }
85
86 int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) {
87         _cleanup_free_ char *fs = NULL;
88         int r;
89         DIR *d;
90
91         assert(_d);
92
93         /* This is not recursive! */
94
95         r = cg_get_path(controller, path, NULL, &fs);
96         if (r < 0)
97                 return r;
98
99         d = opendir(fs);
100         if (!d)
101                 return -errno;
102
103         *_d = d;
104         return 0;
105 }
106
107 int cg_read_subgroup(DIR *d, char **fn) {
108         struct dirent *de;
109
110         assert(d);
111         assert(fn);
112
113         FOREACH_DIRENT(de, d, return -errno) {
114                 char *b;
115
116                 if (de->d_type != DT_DIR)
117                         continue;
118
119                 if (streq(de->d_name, ".") ||
120                     streq(de->d_name, ".."))
121                         continue;
122
123                 b = strdup(de->d_name);
124                 if (!b)
125                         return -ENOMEM;
126
127                 *fn = b;
128                 return 1;
129         }
130
131         return 0;
132 }
133
134 int cg_rmdir(const char *controller, const char *path) {
135         _cleanup_free_ char *p = NULL;
136         int r;
137
138         r = cg_get_path(controller, path, NULL, &p);
139         if (r < 0)
140                 return r;
141
142         r = rmdir(p);
143         if (r < 0 && errno != ENOENT)
144                 return -errno;
145
146         return 0;
147 }
148
149 int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) {
150         _cleanup_set_free_ Set *allocated_set = NULL;
151         bool done = false;
152         int r, ret = 0;
153         pid_t my_pid;
154
155         assert(sig >= 0);
156
157         /* This goes through the tasks list and kills them all. This
158          * is repeated until no further processes are added to the
159          * tasks list, to properly handle forking processes */
160
161         if (!s) {
162                 s = allocated_set = set_new(NULL);
163                 if (!s)
164                         return -ENOMEM;
165         }
166
167         my_pid = getpid();
168
169         do {
170                 _cleanup_fclose_ FILE *f = NULL;
171                 pid_t pid = 0;
172                 done = true;
173
174                 r = cg_enumerate_processes(controller, path, &f);
175                 if (r < 0) {
176                         if (ret >= 0 && r != -ENOENT)
177                                 return r;
178
179                         return ret;
180                 }
181
182                 while ((r = cg_read_pid(f, &pid)) > 0) {
183
184                         if (ignore_self && pid == my_pid)
185                                 continue;
186
187                         if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid))
188                                 continue;
189
190                         /* If we haven't killed this process yet, kill
191                          * it */
192                         if (kill(pid, sig) < 0) {
193                                 if (ret >= 0 && errno != ESRCH)
194                                         ret = -errno;
195                         } else {
196                                 if (sigcont && sig != SIGKILL)
197                                         kill(pid, SIGCONT);
198
199                                 if (ret == 0)
200                                         ret = 1;
201                         }
202
203                         done = false;
204
205                         r = set_put(s, LONG_TO_PTR(pid));
206                         if (r < 0) {
207                                 if (ret >= 0)
208                                         return r;
209
210                                 return ret;
211                         }
212                 }
213
214                 if (r < 0) {
215                         if (ret >= 0)
216                                 return r;
217
218                         return ret;
219                 }
220
221                 /* To avoid racing against processes which fork
222                  * quicker than we can kill them we repeat this until
223                  * no new pids need to be killed. */
224
225         } while (!done);
226
227         return ret;
228 }
229
230 int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool rem, Set *s) {
231         _cleanup_set_free_ Set *allocated_set = NULL;
232         _cleanup_closedir_ DIR *d = NULL;
233         int r, ret = 0;
234         char *fn;
235
236         assert(path);
237         assert(sig >= 0);
238
239         if (!s) {
240                 s = allocated_set = set_new(NULL);
241                 if (!s)
242                         return -ENOMEM;
243         }
244
245         ret = cg_kill(controller, path, sig, sigcont, ignore_self, s);
246
247         r = cg_enumerate_subgroups(controller, path, &d);
248         if (r < 0) {
249                 if (ret >= 0 && r != -ENOENT)
250                         return r;
251
252                 return ret;
253         }
254
255         while ((r = cg_read_subgroup(d, &fn)) > 0) {
256                 _cleanup_free_ char *p = NULL;
257
258                 p = strjoin(path, "/", fn, NULL);
259                 free(fn);
260                 if (!p)
261                         return -ENOMEM;
262
263                 r = cg_kill_recursive(controller, p, sig, sigcont, ignore_self, rem, s);
264                 if (ret >= 0 && r != 0)
265                         ret = r;
266         }
267
268         if (ret >= 0 && r < 0)
269                 ret = r;
270
271         if (rem) {
272                 r = cg_rmdir(controller, path);
273                 if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY)
274                         return r;
275         }
276
277         return ret;
278 }
279
280 int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self) {
281         bool done = false;
282         _cleanup_set_free_ Set *s = NULL;
283         int r, ret = 0;
284         pid_t my_pid;
285
286         assert(cfrom);
287         assert(pfrom);
288         assert(cto);
289         assert(pto);
290
291         s = set_new(NULL);
292         if (!s)
293                 return -ENOMEM;
294
295         my_pid = getpid();
296
297         do {
298                 _cleanup_fclose_ FILE *f = NULL;
299                 pid_t pid = 0;
300                 done = true;
301
302                 r = cg_enumerate_processes(cfrom, pfrom, &f);
303                 if (r < 0) {
304                         if (ret >= 0 && r != -ENOENT)
305                                 return r;
306
307                         return ret;
308                 }
309
310                 while ((r = cg_read_pid(f, &pid)) > 0) {
311
312                         /* This might do weird stuff if we aren't a
313                          * single-threaded program. However, we
314                          * luckily know we are not */
315                         if (ignore_self && pid == my_pid)
316                                 continue;
317
318                         if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid))
319                                 continue;
320
321                         r = cg_attach(cto, pto, pid);
322                         if (r < 0) {
323                                 if (ret >= 0 && r != -ESRCH)
324                                         ret = r;
325                         } else if (ret == 0)
326                                 ret = 1;
327
328                         done = false;
329
330                         r = set_put(s, LONG_TO_PTR(pid));
331                         if (r < 0) {
332                                 if (ret >= 0)
333                                         return r;
334
335                                 return ret;
336                         }
337                 }
338
339                 if (r < 0) {
340                         if (ret >= 0)
341                                 return r;
342
343                         return ret;
344                 }
345         } while (!done);
346
347         return ret;
348 }
349
350 int cg_migrate_recursive(
351                 const char *cfrom,
352                 const char *pfrom,
353                 const char *cto,
354                 const char *pto,
355                 bool ignore_self,
356                 bool rem) {
357
358         _cleanup_closedir_ DIR *d = NULL;
359         int r, ret = 0;
360         char *fn;
361
362         assert(cfrom);
363         assert(pfrom);
364         assert(cto);
365         assert(pto);
366
367         ret = cg_migrate(cfrom, pfrom, cto, pto, ignore_self);
368
369         r = cg_enumerate_subgroups(cfrom, pfrom, &d);
370         if (r < 0) {
371                 if (ret >= 0 && r != -ENOENT)
372                         return r;
373
374                 return ret;
375         }
376
377         while ((r = cg_read_subgroup(d, &fn)) > 0) {
378                 _cleanup_free_ char *p = NULL;
379
380                 p = strjoin(pfrom, "/", fn, NULL);
381                 free(fn);
382                 if (!p) {
383                         if (ret >= 0)
384                                 return -ENOMEM;
385
386                         return ret;
387                 }
388
389                 r = cg_migrate_recursive(cfrom, p, cto, pto, ignore_self, rem);
390                 if (r != 0 && ret >= 0)
391                         ret = r;
392         }
393
394         if (r < 0 && ret >= 0)
395                 ret = r;
396
397         if (rem) {
398                 r = cg_rmdir(cfrom, pfrom);
399                 if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY)
400                         return r;
401         }
402
403         return ret;
404 }
405
406 int cg_migrate_recursive_fallback(
407                 const char *cfrom,
408                 const char *pfrom,
409                 const char *cto,
410                 const char *pto,
411                 bool ignore_self,
412                 bool rem) {
413
414         int r;
415
416         assert(cfrom);
417         assert(pfrom);
418         assert(cto);
419         assert(pto);
420
421         r = cg_migrate_recursive(cfrom, pfrom, cto, pto, ignore_self, rem);
422         if (r < 0) {
423                 char prefix[strlen(pto) + 1];
424
425                 /* This didn't work? Then let's try all prefixes of the destination */
426
427                 PATH_FOREACH_PREFIX(prefix, pto) {
428                         r = cg_migrate_recursive(cfrom, pfrom, cto, prefix, ignore_self, rem);
429                         if (r >= 0)
430                                 break;
431                 }
432         }
433
434         return 0;
435 }
436
437 static const char *normalize_controller(const char *controller) {
438
439         assert(controller);
440
441         if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
442                 return "elogind";
443         else if (startswith(controller, "name="))
444                 return controller + 5;
445         else
446                 return controller;
447 }
448
449 static int join_path(const char *controller, const char *path, const char *suffix, char **fs) {
450         char *t = NULL;
451
452         if (!isempty(controller)) {
453                 if (!isempty(path) && !isempty(suffix))
454                         t = strjoin("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL);
455                 else if (!isempty(path))
456                         t = strjoin("/sys/fs/cgroup/", controller, "/", path, NULL);
457                 else if (!isempty(suffix))
458                         t = strjoin("/sys/fs/cgroup/", controller, "/", suffix, NULL);
459                 else
460                         t = strappend("/sys/fs/cgroup/", controller);
461         } else {
462                 if (!isempty(path) && !isempty(suffix))
463                         t = strjoin(path, "/", suffix, NULL);
464                 else if (!isempty(path))
465                         t = strdup(path);
466                 else
467                         return -EINVAL;
468         }
469
470         if (!t)
471                 return -ENOMEM;
472
473         *fs = path_kill_slashes(t);
474         return 0;
475 }
476
477 int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) {
478         const char *p;
479         static thread_local bool good = false;
480
481         assert(fs);
482
483         if (controller && !cg_controller_is_valid(controller, true))
484                 return -EINVAL;
485
486         if (_unlikely_(!good)) {
487                 int r;
488
489                 r = path_is_mount_point("/sys/fs/cgroup", false);
490                 if (r < 0)
491                         return r;
492                 if (r == 0)
493                         return -ENOENT;
494
495                 /* Cache this to save a few stat()s */
496                 good = true;
497         }
498
499         p = controller ? normalize_controller(controller) : NULL;
500
501         return join_path(p, path, suffix, fs);
502 }
503
504 static int check_hierarchy(const char *p) {
505         const char *cc;
506
507         assert(p);
508
509         if (!filename_is_valid(p))
510                 return 0;
511
512         /* Check if this controller actually really exists */
513         cc = strjoina("/sys/fs/cgroup/", p);
514         if (laccess(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), PID_FMT"\n", pid);
647
648         return write_string_file_no_create(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_INVALID)
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_INVALID && uid == UID_INVALID && gid == GID_INVALID)
710                 return 0;
711
712         if (mode != MODE_INVALID)
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, *e;
759                 size_t k;
760                 const char *word, *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(word, k, l, ",", state) {
777
778                         if (k == cs && memcmp(word, controller, cs) == 0) {
779                                 found = true;
780                                 break;
781                         }
782
783                         if (k == 5 + cs &&
784                             memcmp(word, "name=", 5) == 0 &&
785                             memcmp(word+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_no_create(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_no_create(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_no_create(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_no_create(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 = path_kill_slashes(t);
961                 }
962
963                 if (controller)
964                         *controller = NULL;
965
966                 return 0;
967         }
968
969         e = strchr(spec, ':');
970         if (!e) {
971                 if (!cg_controller_is_valid(spec, true))
972                         return -EINVAL;
973
974                 if (controller) {
975                         t = strdup(normalize_controller(spec));
976                         if (!t)
977                                 return -ENOMEM;
978
979                         *controller = t;
980                 }
981
982                 if (path)
983                         *path = NULL;
984
985                 return 0;
986         }
987
988         v = strndup(spec, e-spec);
989         if (!v)
990                 return -ENOMEM;
991         t = strdup(normalize_controller(v));
992         if (!t)
993                 return -ENOMEM;
994         if (!cg_controller_is_valid(t, true)) {
995                 free(t);
996                 return -EINVAL;
997         }
998
999         if (streq(e+1, "")) {
1000                 u = strdup("/");
1001                 if (!u) {
1002                         free(t);
1003                         return -ENOMEM;
1004                 }
1005         } else {
1006                 u = strdup(e+1);
1007                 if (!u) {
1008                         free(t);
1009                         return -ENOMEM;
1010                 }
1011
1012                 if (!path_is_safe(u) ||
1013                     !path_is_absolute(u)) {
1014                         free(t);
1015                         free(u);
1016                         return -EINVAL;
1017                 }
1018
1019                 path_kill_slashes(u);
1020         }
1021
1022         if (controller)
1023                 *controller = t;
1024         else
1025                 free(t);
1026
1027         if (path)
1028                 *path = u;
1029         else
1030                 free(u);
1031
1032         return 0;
1033 }
1034
1035 int cg_mangle_path(const char *path, char **result) {
1036         _cleanup_free_ char *c = NULL, *p = NULL;
1037         char *t;
1038         int r;
1039
1040         assert(path);
1041         assert(result);
1042
1043         /* First, check if it already is a filesystem path */
1044         if (path_startswith(path, "/sys/fs/cgroup")) {
1045
1046                 t = strdup(path);
1047                 if (!t)
1048                         return -ENOMEM;
1049
1050                 *result = path_kill_slashes(t);
1051                 return 0;
1052         }
1053
1054         /* Otherwise, treat it as cg spec */
1055         r = cg_split_spec(path, &c, &p);
1056         if (r < 0)
1057                 return r;
1058
1059         return cg_get_path(c ? c : SYSTEMD_CGROUP_CONTROLLER, p ? p : "/", NULL, result);
1060 }
1061
1062 int cg_get_root_path(char **path) {
1063         assert(path);
1064
1065         return cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, path);
1066 }
1067
1068 int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
1069         _cleanup_free_ char *rt = NULL;
1070         char *p;
1071         int r;
1072
1073         assert(cgroup);
1074         assert(shifted);
1075
1076         if (!root) {
1077                 /* If the root was specified let's use that, otherwise
1078                  * let's determine it from PID 1 */
1079
1080                 r = cg_get_root_path(&rt);
1081                 if (r < 0)
1082                         return r;
1083
1084                 root = rt;
1085         }
1086
1087         p = path_startswith(cgroup, root);
1088         if (p)
1089                 *shifted = p - 1;
1090         else
1091                 *shifted = cgroup;
1092
1093         return 0;
1094 }
1095
1096 int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
1097         _cleanup_free_ char *raw = NULL;
1098         const char *c;
1099         int r;
1100
1101         assert(pid >= 0);
1102         assert(cgroup);
1103
1104         r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &raw);
1105         if (r < 0)
1106                 return r;
1107
1108         r = cg_shift_path(raw, root, &c);
1109         if (r < 0)
1110                 return r;
1111
1112         if (c == raw) {
1113                 *cgroup = raw;
1114                 raw = NULL;
1115         } else {
1116                 char *n;
1117
1118                 n = strdup(c);
1119                 if (!n)
1120                         return -ENOMEM;
1121
1122                 *cgroup = n;
1123         }
1124
1125         return 0;
1126 }
1127
1128 int cg_path_get_session(const char *path, char **session) {
1129         const char *e, *n, *s;
1130
1131         /* Elogind uses a flat hierarchy, just "/SESSION".  The only
1132            wrinkle is that SESSION might be escaped.  */
1133
1134         assert(path);
1135         assert(path[0] == '/');
1136
1137         e = path + 1;
1138         n = strchrnul(e, '/');
1139         if (e == n)
1140                 return -ENOENT;
1141
1142         s = strndupa(e, n - e);
1143         s = cg_unescape(s);
1144
1145         if (!s[0])
1146                 return -ENOENT;
1147
1148         if (session) {
1149                 char *r;
1150
1151                 r = strdup(s);
1152                 if (!r)
1153                         return -ENOMEM;
1154
1155                 *session = r;
1156         }
1157
1158         return 0;
1159 }
1160
1161 int cg_pid_get_session(pid_t pid, char **session) {
1162         _cleanup_free_ char *cgroup = NULL;
1163         int r;
1164
1165         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1166         if (r < 0)
1167                 return r;
1168
1169         return cg_path_get_session(cgroup, session);
1170 }
1171
1172 char *cg_escape(const char *p) {
1173         bool need_prefix = false;
1174
1175         /* This implements very minimal escaping for names to be used
1176          * as file names in the cgroup tree: any name which might
1177          * conflict with a kernel name or is prefixed with '_' is
1178          * prefixed with a '_'. That way, when reading cgroup names it
1179          * is sufficient to remove a single prefixing underscore if
1180          * there is one. */
1181
1182         /* The return value of this function (unlike cg_unescape())
1183          * needs free()! */
1184
1185         if (p[0] == 0 ||
1186             p[0] == '_' ||
1187             p[0] == '.' ||
1188             streq(p, "notify_on_release") ||
1189             streq(p, "release_agent") ||
1190             streq(p, "tasks"))
1191                 need_prefix = true;
1192         else {
1193                 const char *dot;
1194
1195                 dot = strrchr(p, '.');
1196                 if (dot) {
1197
1198                         if (dot - p == 6 && memcmp(p, "cgroup", 6) == 0)
1199                                 need_prefix = true;
1200                         else {
1201                                 char *n;
1202
1203                                 n = strndupa(p, dot - p);
1204
1205                                 if (check_hierarchy(n) >= 0)
1206                                         need_prefix = true;
1207                         }
1208                 }
1209         }
1210
1211         if (need_prefix)
1212                 return strappend("_", p);
1213         else
1214                 return strdup(p);
1215 }
1216
1217 char *cg_unescape(const char *p) {
1218         assert(p);
1219
1220         /* The return value of this function (unlike cg_escape())
1221          * doesn't need free()! */
1222
1223         if (p[0] == '_')
1224                 return (char*) p+1;
1225
1226         return (char*) p;
1227 }
1228
1229 #define CONTROLLER_VALID                        \
1230         DIGITS LETTERS                          \
1231         "_"
1232
1233 bool cg_controller_is_valid(const char *p, bool allow_named) {
1234         const char *t, *s;
1235
1236         if (!p)
1237                 return false;
1238
1239         if (allow_named) {
1240                 s = startswith(p, "name=");
1241                 if (s)
1242                         p = s;
1243         }
1244
1245         if (*p == 0 || *p == '_')
1246                 return false;
1247
1248         for (t = p; *t; t++)
1249                 if (!strchr(CONTROLLER_VALID, *t))
1250                         return false;
1251
1252         if (t - p > FILENAME_MAX)
1253                 return false;
1254
1255         return true;
1256 }
1257
1258 int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value) {
1259         _cleanup_free_ char *p = NULL;
1260         int r;
1261
1262         r = cg_get_path(controller, path, attribute, &p);
1263         if (r < 0)
1264                 return r;
1265
1266         return write_string_file_no_create(p, value);
1267 }
1268
1269 int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret) {
1270         _cleanup_free_ char *p = NULL;
1271         int r;
1272
1273         r = cg_get_path(controller, path, attribute, &p);
1274         if (r < 0)
1275                 return r;
1276
1277         return read_one_line_file(p, ret);
1278 }
1279
1280 static const char mask_names[] =
1281         "cpu\0"
1282         "cpuacct\0"
1283         "blkio\0"
1284         "memory\0"
1285         "devices\0";
1286
1287 int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path) {
1288         CGroupControllerMask bit = 1;
1289         const char *n;
1290         int r;
1291
1292         /* This one will create a cgroup in our private tree, but also
1293          * duplicate it in the trees specified in mask, and remove it
1294          * in all others */
1295
1296         /* First create the cgroup in our own hierarchy. */
1297         r = cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
1298         if (r < 0)
1299                 return r;
1300
1301         /* Then, do the same in the other hierarchies */
1302         NULSTR_FOREACH(n, mask_names) {
1303                 if (mask & bit)
1304                         cg_create(n, path);
1305                 else if (supported & bit)
1306                         cg_trim(n, path, true);
1307
1308                 bit <<= 1;
1309         }
1310
1311         return 0;
1312 }
1313
1314 int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) {
1315         CGroupControllerMask bit = 1;
1316         const char *n;
1317         int r;
1318
1319         r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid);
1320         if (r < 0)
1321                 return r;
1322
1323         NULSTR_FOREACH(n, mask_names) {
1324
1325                 if (supported & bit) {
1326                         const char *p = NULL;
1327
1328                         if (path_callback)
1329                                 p = path_callback(bit, userdata);
1330
1331                         if (!p)
1332                                 p = path;
1333
1334                         cg_attach_fallback(n, path, pid);
1335                 }
1336
1337                 bit <<= 1;
1338         }
1339
1340         return 0;
1341 }
1342
1343 int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids, cg_migrate_callback_t path_callback, void *userdata) {
1344         Iterator i;
1345         void *pidp;
1346         int r = 0;
1347
1348         SET_FOREACH(pidp, pids, i) {
1349                 pid_t pid = PTR_TO_LONG(pidp);
1350                 int q;
1351
1352                 q = cg_attach_everywhere(supported, path, pid, path_callback, userdata);
1353                 if (q < 0)
1354                         r = q;
1355         }
1356
1357         return r;
1358 }
1359
1360 int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to, cg_migrate_callback_t to_callback, void *userdata) {
1361         CGroupControllerMask bit = 1;
1362         const char *n;
1363         int r;
1364
1365         if (!path_equal(from, to))  {
1366                 r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true);
1367                 if (r < 0)
1368                         return r;
1369         }
1370
1371         NULSTR_FOREACH(n, mask_names) {
1372                 if (supported & bit) {
1373                         const char *p = NULL;
1374
1375                         if (to_callback)
1376                                 p = to_callback(bit, userdata);
1377
1378                         if (!p)
1379                                 p = to;
1380
1381                         cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, p, false, false);
1382                 }
1383
1384                 bit <<= 1;
1385         }
1386
1387         return 0;
1388 }
1389
1390 int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root) {
1391         CGroupControllerMask bit = 1;
1392         const char *n;
1393         int r;
1394
1395         r = cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root);
1396         if (r < 0)
1397                 return r;
1398
1399         NULSTR_FOREACH(n, mask_names) {
1400                 if (supported & bit)
1401                         cg_trim(n, path, delete_root);
1402
1403                 bit <<= 1;
1404         }
1405
1406         return 0;
1407 }
1408
1409 CGroupControllerMask cg_mask_supported(void) {
1410         CGroupControllerMask bit = 1, mask = 0;
1411         const char *n;
1412
1413         NULSTR_FOREACH(n, mask_names) {
1414                 if (check_hierarchy(n) >= 0)
1415                         mask |= bit;
1416
1417                 bit <<= 1;
1418         }
1419
1420         return mask;
1421 }
1422
1423 int cg_kernel_controllers(Set *controllers) {
1424         _cleanup_fclose_ FILE *f = NULL;
1425         char buf[LINE_MAX];
1426         int r;
1427
1428         assert(controllers);
1429
1430         f = fopen("/proc/cgroups", "re");
1431         if (!f) {
1432                 if (errno == ENOENT)
1433                         return 0;
1434                 return -errno;
1435         }
1436
1437         /* Ignore the header line */
1438         (void) fgets(buf, sizeof(buf), f);
1439
1440         for (;;) {
1441                 char *controller;
1442                 int enabled = 0;
1443
1444                 errno = 0;
1445                 if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) {
1446
1447                         if (feof(f))
1448                                 break;
1449
1450                         if (ferror(f) && errno)
1451                                 return -errno;
1452
1453                         return -EBADMSG;
1454                 }
1455
1456                 if (!enabled) {
1457                         free(controller);
1458                         continue;
1459                 }
1460
1461                 if (!filename_is_valid(controller)) {
1462                         free(controller);
1463                         return -EBADMSG;
1464                 }
1465
1466                 r = set_consume(controllers, controller);
1467                 if (r < 0)
1468                         return r;
1469         }
1470
1471         return 0;
1472 }