chiark / gitweb /
Remove libidn checks/support
[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 "path-util.h"
37 #include "unit-name.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 "systemd";
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 < 0 ? r : -ENOENT;
492
493                 /* Cache this to save a few stat()s */
494                 good = true;
495         }
496
497         p = controller ? normalize_controller(controller) : NULL;
498
499         return join_path(p, path, suffix, fs);
500 }
501
502 static int check_hierarchy(const char *p) {
503         const char *cc;
504
505         assert(p);
506
507         if (!filename_is_valid(p))
508                 return 0;
509
510         /* Check if this controller actually really exists */
511         cc = strjoina("/sys/fs/cgroup/", p);
512         if (laccess(cc, F_OK) < 0)
513                 return -errno;
514
515         return 0;
516 }
517
518 int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) {
519         const char *p;
520         int r;
521
522         assert(fs);
523
524         if (!cg_controller_is_valid(controller, true))
525                 return -EINVAL;
526
527         /* Normalize the controller syntax */
528         p = normalize_controller(controller);
529
530         /* Check if this controller actually really exists */
531         r = check_hierarchy(p);
532         if (r < 0)
533                 return r;
534
535         return join_path(p, path, suffix, fs);
536 }
537
538 static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
539         assert(path);
540         assert(sb);
541         assert(ftwbuf);
542
543         if (typeflag != FTW_DP)
544                 return 0;
545
546         if (ftwbuf->level < 1)
547                 return 0;
548
549         rmdir(path);
550         return 0;
551 }
552
553 int cg_trim(const char *controller, const char *path, bool delete_root) {
554         _cleanup_free_ char *fs = NULL;
555         int r = 0;
556
557         assert(path);
558
559         r = cg_get_path(controller, path, NULL, &fs);
560         if (r < 0)
561                 return r;
562
563         errno = 0;
564         if (nftw(fs, trim_cb, 64, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) != 0)
565                 r = errno ? -errno : -EIO;
566
567         if (delete_root) {
568                 if (rmdir(fs) < 0 && errno != ENOENT)
569                         return -errno;
570         }
571
572         return r;
573 }
574
575 int cg_delete(const char *controller, const char *path) {
576         _cleanup_free_ char *parent = NULL;
577         int r;
578
579         assert(path);
580
581         r = path_get_parent(path, &parent);
582         if (r < 0)
583                 return r;
584
585         r = cg_migrate_recursive(controller, path, controller, parent, false, true);
586         return r == -ENOENT ? 0 : r;
587 }
588
589 int cg_create(const char *controller, const char *path) {
590         _cleanup_free_ char *fs = NULL;
591         int r;
592
593         r = cg_get_path_and_check(controller, path, NULL, &fs);
594         if (r < 0)
595                 return r;
596
597         r = mkdir_parents(fs, 0755);
598         if (r < 0)
599                 return r;
600
601         if (mkdir(fs, 0755) < 0) {
602
603                 if (errno == EEXIST)
604                         return 0;
605
606                 return -errno;
607         }
608
609         return 1;
610 }
611
612 int cg_create_and_attach(const char *controller, const char *path, pid_t pid) {
613         int r, q;
614
615         assert(pid >= 0);
616
617         r = cg_create(controller, path);
618         if (r < 0)
619                 return r;
620
621         q = cg_attach(controller, path, pid);
622         if (q < 0)
623                 return q;
624
625         /* This does not remove the cgroup on failure */
626         return r;
627 }
628
629 int cg_attach(const char *controller, const char *path, pid_t pid) {
630         _cleanup_free_ char *fs = NULL;
631         char c[DECIMAL_STR_MAX(pid_t) + 2];
632         int r;
633
634         assert(path);
635         assert(pid >= 0);
636
637         r = cg_get_path_and_check(controller, path, "cgroup.procs", &fs);
638         if (r < 0)
639                 return r;
640
641         if (pid == 0)
642                 pid = getpid();
643
644         snprintf(c, sizeof(c), PID_FMT"\n", pid);
645
646         return write_string_file_no_create(fs, c);
647 }
648
649 int cg_attach_fallback(const char *controller, const char *path, pid_t pid) {
650         int r;
651
652         assert(controller);
653         assert(path);
654         assert(pid >= 0);
655
656         r = cg_attach(controller, path, pid);
657         if (r < 0) {
658                 char prefix[strlen(path) + 1];
659
660                 /* This didn't work? Then let's try all prefixes of
661                  * the destination */
662
663                 PATH_FOREACH_PREFIX(prefix, path) {
664                         r = cg_attach(controller, prefix, pid);
665                         if (r >= 0)
666                                 break;
667                 }
668         }
669
670         return 0;
671 }
672
673 int cg_set_group_access(
674                 const char *controller,
675                 const char *path,
676                 mode_t mode,
677                 uid_t uid,
678                 gid_t gid) {
679
680         _cleanup_free_ char *fs = NULL;
681         int r;
682
683         assert(path);
684
685         if (mode != MODE_INVALID)
686                 mode &= 0777;
687
688         r = cg_get_path(controller, path, NULL, &fs);
689         if (r < 0)
690                 return r;
691
692         return chmod_and_chown(fs, mode, uid, gid);
693 }
694
695 int cg_set_task_access(
696                 const char *controller,
697                 const char *path,
698                 mode_t mode,
699                 uid_t uid,
700                 gid_t gid) {
701
702         _cleanup_free_ char *fs = NULL, *procs = NULL;
703         int r;
704
705         assert(path);
706
707         if (mode == MODE_INVALID && uid == UID_INVALID && gid == GID_INVALID)
708                 return 0;
709
710         if (mode != MODE_INVALID)
711                 mode &= 0666;
712
713         r = cg_get_path(controller, path, "cgroup.procs", &fs);
714         if (r < 0)
715                 return r;
716
717         r = chmod_and_chown(fs, mode, uid, gid);
718         if (r < 0)
719                 return r;
720
721         /* Compatibility, Always keep values for "tasks" in sync with
722          * "cgroup.procs" */
723         r = cg_get_path(controller, path, "tasks", &procs);
724         if (r < 0)
725                 return r;
726
727         return chmod_and_chown(procs, mode, uid, gid);
728 }
729
730 int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
731         _cleanup_fclose_ FILE *f = NULL;
732         char line[LINE_MAX];
733         const char *fs;
734         size_t cs;
735
736         assert(path);
737         assert(pid >= 0);
738
739         if (controller) {
740                 if (!cg_controller_is_valid(controller, true))
741                         return -EINVAL;
742
743                 controller = normalize_controller(controller);
744         } else
745                 controller = SYSTEMD_CGROUP_CONTROLLER;
746
747         fs = procfs_file_alloca(pid, "cgroup");
748
749         f = fopen(fs, "re");
750         if (!f)
751                 return errno == ENOENT ? -ESRCH : -errno;
752
753         cs = strlen(controller);
754
755         FOREACH_LINE(line, f, return -errno) {
756                 char *l, *p, *e;
757                 size_t k;
758                 const char *word, *state;
759                 bool found = false;
760
761                 truncate_nl(line);
762
763                 l = strchr(line, ':');
764                 if (!l)
765                         continue;
766
767                 l++;
768                 e = strchr(l, ':');
769                 if (!e)
770                         continue;
771
772                 *e = 0;
773
774                 FOREACH_WORD_SEPARATOR(word, k, l, ",", state) {
775
776                         if (k == cs && memcmp(word, controller, cs) == 0) {
777                                 found = true;
778                                 break;
779                         }
780
781                         if (k == 5 + cs &&
782                             memcmp(word, "name=", 5) == 0 &&
783                             memcmp(word+5, controller, cs) == 0) {
784                                 found = true;
785                                 break;
786                         }
787                 }
788
789                 if (!found)
790                         continue;
791
792                 p = strdup(e + 1);
793                 if (!p)
794                         return -ENOMEM;
795
796                 *path = p;
797                 return 0;
798         }
799
800         return -ENOENT;
801 }
802
803 int cg_install_release_agent(const char *controller, const char *agent) {
804         _cleanup_free_ char *fs = NULL, *contents = NULL;
805         char *sc;
806         int r;
807
808         assert(agent);
809
810         r = cg_get_path(controller, NULL, "release_agent", &fs);
811         if (r < 0)
812                 return r;
813
814         r = read_one_line_file(fs, &contents);
815         if (r < 0)
816                 return r;
817
818         sc = strstrip(contents);
819         if (sc[0] == 0) {
820                 r = write_string_file_no_create(fs, agent);
821                 if (r < 0)
822                         return r;
823         } else if (!streq(sc, agent))
824                 return -EEXIST;
825
826         free(fs);
827         fs = NULL;
828         r = cg_get_path(controller, NULL, "notify_on_release", &fs);
829         if (r < 0)
830                 return r;
831
832         free(contents);
833         contents = NULL;
834         r = read_one_line_file(fs, &contents);
835         if (r < 0)
836                 return r;
837
838         sc = strstrip(contents);
839         if (streq(sc, "0")) {
840                 r = write_string_file_no_create(fs, "1");
841                 if (r < 0)
842                         return r;
843
844                 return 1;
845         }
846
847         if (!streq(sc, "1"))
848                 return -EIO;
849
850         return 0;
851 }
852
853 int cg_uninstall_release_agent(const char *controller) {
854         _cleanup_free_ char *fs = NULL;
855         int r;
856
857         r = cg_get_path(controller, NULL, "notify_on_release", &fs);
858         if (r < 0)
859                 return r;
860
861         r = write_string_file_no_create(fs, "0");
862         if (r < 0)
863                 return r;
864
865         free(fs);
866         fs = NULL;
867
868         r = cg_get_path(controller, NULL, "release_agent", &fs);
869         if (r < 0)
870                 return r;
871
872         r = write_string_file_no_create(fs, "");
873         if (r < 0)
874                 return r;
875
876         return 0;
877 }
878
879 int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
880         _cleanup_fclose_ FILE *f = NULL;
881         pid_t pid = 0, self_pid;
882         bool found = false;
883         int r;
884
885         assert(path);
886
887         r = cg_enumerate_processes(controller, path, &f);
888         if (r < 0)
889                 return r == -ENOENT ? 1 : r;
890
891         self_pid = getpid();
892
893         while ((r = cg_read_pid(f, &pid)) > 0) {
894
895                 if (ignore_self && pid == self_pid)
896                         continue;
897
898                 found = true;
899                 break;
900         }
901
902         if (r < 0)
903                 return r;
904
905         return !found;
906 }
907
908 int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self) {
909         _cleanup_closedir_ DIR *d = NULL;
910         char *fn;
911         int r;
912
913         assert(path);
914
915         r = cg_is_empty(controller, path, ignore_self);
916         if (r <= 0)
917                 return r;
918
919         r = cg_enumerate_subgroups(controller, path, &d);
920         if (r < 0)
921                 return r == -ENOENT ? 1 : r;
922
923         while ((r = cg_read_subgroup(d, &fn)) > 0) {
924                 _cleanup_free_ char *p = NULL;
925
926                 p = strjoin(path, "/", fn, NULL);
927                 free(fn);
928                 if (!p)
929                         return -ENOMEM;
930
931                 r = cg_is_empty_recursive(controller, p, ignore_self);
932                 if (r <= 0)
933                         return r;
934         }
935
936         if (r < 0)
937                 return r;
938
939         return 1;
940 }
941
942 int cg_split_spec(const char *spec, char **controller, char **path) {
943         const char *e;
944         char *t = NULL, *u = NULL;
945         _cleanup_free_ char *v = NULL;
946
947         assert(spec);
948
949         if (*spec == '/') {
950                 if (!path_is_safe(spec))
951                         return -EINVAL;
952
953                 if (path) {
954                         t = strdup(spec);
955                         if (!t)
956                                 return -ENOMEM;
957
958                         *path = path_kill_slashes(t);
959                 }
960
961                 if (controller)
962                         *controller = NULL;
963
964                 return 0;
965         }
966
967         e = strchr(spec, ':');
968         if (!e) {
969                 if (!cg_controller_is_valid(spec, true))
970                         return -EINVAL;
971
972                 if (controller) {
973                         t = strdup(normalize_controller(spec));
974                         if (!t)
975                                 return -ENOMEM;
976
977                         *controller = t;
978                 }
979
980                 if (path)
981                         *path = NULL;
982
983                 return 0;
984         }
985
986         v = strndup(spec, e-spec);
987         if (!v)
988                 return -ENOMEM;
989         t = strdup(normalize_controller(v));
990         if (!t)
991                 return -ENOMEM;
992         if (!cg_controller_is_valid(t, true)) {
993                 free(t);
994                 return -EINVAL;
995         }
996
997         if (streq(e+1, "")) {
998                 u = strdup("/");
999                 if (!u) {
1000                         free(t);
1001                         return -ENOMEM;
1002                 }
1003         } else {
1004                 u = strdup(e+1);
1005                 if (!u) {
1006                         free(t);
1007                         return -ENOMEM;
1008                 }
1009
1010                 if (!path_is_safe(u) ||
1011                     !path_is_absolute(u)) {
1012                         free(t);
1013                         free(u);
1014                         return -EINVAL;
1015                 }
1016
1017                 path_kill_slashes(u);
1018         }
1019
1020         if (controller)
1021                 *controller = t;
1022         else
1023                 free(t);
1024
1025         if (path)
1026                 *path = u;
1027         else
1028                 free(u);
1029
1030         return 0;
1031 }
1032
1033 int cg_mangle_path(const char *path, char **result) {
1034         _cleanup_free_ char *c = NULL, *p = NULL;
1035         char *t;
1036         int r;
1037
1038         assert(path);
1039         assert(result);
1040
1041         /* First, check if it already is a filesystem path */
1042         if (path_startswith(path, "/sys/fs/cgroup")) {
1043
1044                 t = strdup(path);
1045                 if (!t)
1046                         return -ENOMEM;
1047
1048                 *result = path_kill_slashes(t);
1049                 return 0;
1050         }
1051
1052         /* Otherwise, treat it as cg spec */
1053         r = cg_split_spec(path, &c, &p);
1054         if (r < 0)
1055                 return r;
1056
1057         return cg_get_path(c ? c : SYSTEMD_CGROUP_CONTROLLER, p ? p : "/", NULL, result);
1058 }
1059
1060 int cg_get_root_path(char **path) {
1061         char *p, *e;
1062         int r;
1063
1064         assert(path);
1065
1066         r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 1, &p);
1067         if (r < 0)
1068                 return r;
1069
1070         e = endswith(p, "/" SPECIAL_SYSTEM_SLICE);
1071         if (e)
1072                 *e = 0;
1073
1074         *path = p;
1075         return 0;
1076 }
1077
1078 int cg_shift_path(const char *cgroup, const char *root, const char **shifted) {
1079         _cleanup_free_ char *rt = NULL;
1080         char *p;
1081         int r;
1082
1083         assert(cgroup);
1084         assert(shifted);
1085
1086         if (!root) {
1087                 /* If the root was specified let's use that, otherwise
1088                  * let's determine it from PID 1 */
1089
1090                 r = cg_get_root_path(&rt);
1091                 if (r < 0)
1092                         return r;
1093
1094                 root = rt;
1095         }
1096
1097         p = path_startswith(cgroup, root);
1098         if (p)
1099                 *shifted = p - 1;
1100         else
1101                 *shifted = cgroup;
1102
1103         return 0;
1104 }
1105
1106 int cg_pid_get_path_shifted(pid_t pid, const char *root, char **cgroup) {
1107         _cleanup_free_ char *raw = NULL;
1108         const char *c;
1109         int r;
1110
1111         assert(pid >= 0);
1112         assert(cgroup);
1113
1114         r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &raw);
1115         if (r < 0)
1116                 return r;
1117
1118         r = cg_shift_path(raw, root, &c);
1119         if (r < 0)
1120                 return r;
1121
1122         if (c == raw) {
1123                 *cgroup = raw;
1124                 raw = NULL;
1125         } else {
1126                 char *n;
1127
1128                 n = strdup(c);
1129                 if (!n)
1130                         return -ENOMEM;
1131
1132                 *cgroup = n;
1133         }
1134
1135         return 0;
1136 }
1137
1138 int cg_path_decode_unit(const char *cgroup, char **unit){
1139         char *e, *c, *s;
1140
1141         assert(cgroup);
1142         assert(unit);
1143
1144         e = strchrnul(cgroup, '/');
1145         c = strndupa(cgroup, e - cgroup);
1146         c = cg_unescape(c);
1147
1148         if (!unit_name_is_valid(c, TEMPLATE_INVALID))
1149                 return -EINVAL;
1150
1151         s = strdup(c);
1152         if (!s)
1153                 return -ENOMEM;
1154
1155         *unit = s;
1156         return 0;
1157 }
1158
1159 static const char *skip_slices(const char *p) {
1160         /* Skips over all slice assignments */
1161
1162         for (;;) {
1163                 size_t n;
1164
1165                 p += strspn(p, "/");
1166
1167                 n = strcspn(p, "/");
1168                 if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0)
1169                         return p;
1170
1171                 p += n;
1172         }
1173 }
1174
1175 int cg_path_get_unit(const char *path, char **unit) {
1176         const char *e;
1177
1178         assert(path);
1179         assert(unit);
1180
1181         e = skip_slices(path);
1182
1183         return cg_path_decode_unit(e, unit);
1184 }
1185
1186 int cg_pid_get_unit(pid_t pid, char **unit) {
1187         _cleanup_free_ char *cgroup = NULL;
1188         int r;
1189
1190         assert(unit);
1191
1192         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1193         if (r < 0)
1194                 return r;
1195
1196         return cg_path_get_unit(cgroup, unit);
1197 }
1198
1199 /**
1200  * Skip session-*.scope, but require it to be there.
1201  */
1202 static const char *skip_session(const char *p) {
1203         size_t n;
1204
1205         assert(p);
1206
1207         p += strspn(p, "/");
1208
1209         n = strcspn(p, "/");
1210         if (n < strlen("session-x.scope") || memcmp(p, "session-", 8) != 0 || memcmp(p + n - 6, ".scope", 6) != 0)
1211                 return NULL;
1212
1213         p += n;
1214         p += strspn(p, "/");
1215
1216         return p;
1217 }
1218
1219 /**
1220  * Skip user@*.service, but require it to be there.
1221  */
1222 static const char *skip_user_manager(const char *p) {
1223         size_t n;
1224
1225         assert(p);
1226
1227         p += strspn(p, "/");
1228
1229         n = strcspn(p, "/");
1230         if (n < strlen("user@x.service") || memcmp(p, "user@", 5) != 0 || memcmp(p + n - 8, ".service", 8) != 0)
1231                 return NULL;
1232
1233         p += n;
1234         p += strspn(p, "/");
1235
1236         return p;
1237 }
1238
1239 int cg_path_get_user_unit(const char *path, char **unit) {
1240         const char *e, *t;
1241
1242         assert(path);
1243         assert(unit);
1244
1245         /* We always have to parse the path from the beginning as unit
1246          * cgroups might have arbitrary child cgroups and we shouldn't get
1247          * confused by those */
1248
1249         /* Skip slices, if there are any */
1250         e = skip_slices(path);
1251
1252         /* Skip the session scope or user manager... */
1253         t = skip_session(e);
1254         if (!t)
1255                 t = skip_user_manager(e);
1256         if (!t)
1257                 return -ENOENT;
1258
1259         /* ... and skip more slices if there are any */
1260         e = skip_slices(t);
1261
1262         return cg_path_decode_unit(e, unit);
1263 }
1264
1265 int cg_pid_get_user_unit(pid_t pid, char **unit) {
1266         _cleanup_free_ char *cgroup = NULL;
1267         int r;
1268
1269         assert(unit);
1270
1271         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1272         if (r < 0)
1273                 return r;
1274
1275         return cg_path_get_user_unit(cgroup, unit);
1276 }
1277
1278 int cg_path_get_machine_name(const char *path, char **machine) {
1279         _cleanup_free_ char *u = NULL, *sl = NULL;
1280         int r;
1281
1282         r = cg_path_get_unit(path, &u);
1283         if (r < 0)
1284                 return r;
1285
1286         sl = strjoin("/run/systemd/machines/unit:", u, NULL);
1287         if (!sl)
1288                 return -ENOMEM;
1289
1290         return readlink_malloc(sl, machine);
1291 }
1292
1293 int cg_pid_get_machine_name(pid_t pid, char **machine) {
1294         _cleanup_free_ char *cgroup = NULL;
1295         int r;
1296
1297         assert(machine);
1298
1299         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1300         if (r < 0)
1301                 return r;
1302
1303         return cg_path_get_machine_name(cgroup, machine);
1304 }
1305
1306 int cg_path_get_session(const char *path, char **session) {
1307         const char *e, *n, *x, *y;
1308         char *s;
1309
1310         assert(path);
1311
1312         /* Skip slices, if there are any */
1313         e = skip_slices(path);
1314
1315         n = strchrnul(e, '/');
1316         if (e == n)
1317                 return -ENOENT;
1318
1319         s = strndupa(e, n - e);
1320         s = cg_unescape(s);
1321
1322         x = startswith(s, "session-");
1323         if (!x)
1324                 return -ENOENT;
1325         y = endswith(x, ".scope");
1326         if (!y || x == y)
1327                 return -ENOENT;
1328
1329         if (session) {
1330                 char *r;
1331
1332                 r = strndup(x, y - x);
1333                 if (!r)
1334                         return -ENOMEM;
1335
1336                 *session = r;
1337         }
1338
1339         return 0;
1340 }
1341
1342 int cg_pid_get_session(pid_t pid, char **session) {
1343         _cleanup_free_ char *cgroup = NULL;
1344         int r;
1345
1346         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1347         if (r < 0)
1348                 return r;
1349
1350         return cg_path_get_session(cgroup, session);
1351 }
1352
1353 int cg_path_get_owner_uid(const char *path, uid_t *uid) {
1354         _cleanup_free_ char *slice = NULL;
1355         const char *start, *end;
1356         char *s;
1357         uid_t u;
1358         int r;
1359
1360         assert(path);
1361
1362         r = cg_path_get_slice(path, &slice);
1363         if (r < 0)
1364                 return r;
1365
1366         start = startswith(slice, "user-");
1367         if (!start)
1368                 return -ENOENT;
1369         end = endswith(slice, ".slice");
1370         if (!end)
1371                 return -ENOENT;
1372
1373         s = strndupa(start, end - start);
1374         if (!s)
1375                 return -ENOENT;
1376
1377         if (parse_uid(s, &u) < 0)
1378                 return -EIO;
1379
1380         if (uid)
1381                 *uid = u;
1382
1383         return 0;
1384 }
1385
1386 int cg_pid_get_owner_uid(pid_t pid, uid_t *uid) {
1387         _cleanup_free_ char *cgroup = NULL;
1388         int r;
1389
1390         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1391         if (r < 0)
1392                 return r;
1393
1394         return cg_path_get_owner_uid(cgroup, uid);
1395 }
1396
1397 int cg_path_get_slice(const char *p, char **slice) {
1398         const char *e = NULL;
1399         size_t m = 0;
1400
1401         assert(p);
1402         assert(slice);
1403
1404         for (;;) {
1405                 size_t n;
1406
1407                 p += strspn(p, "/");
1408
1409                 n = strcspn(p, "/");
1410                 if (n <= 6 || memcmp(p + n - 6, ".slice", 6) != 0) {
1411                         char *s;
1412
1413                         if (!e)
1414                                 return -ENOENT;
1415
1416                         s = strndup(e, m);
1417                         if (!s)
1418                                 return -ENOMEM;
1419
1420                         *slice = s;
1421                         return 0;
1422                 }
1423
1424                 e = p;
1425                 m = n;
1426
1427                 p += n;
1428         }
1429 }
1430
1431 int cg_pid_get_slice(pid_t pid, char **slice) {
1432         _cleanup_free_ char *cgroup = NULL;
1433         int r;
1434
1435         assert(slice);
1436
1437         r = cg_pid_get_path_shifted(pid, NULL, &cgroup);
1438         if (r < 0)
1439                 return r;
1440
1441         return cg_path_get_slice(cgroup, slice);
1442 }
1443
1444 char *cg_escape(const char *p) {
1445         bool need_prefix = false;
1446
1447         /* This implements very minimal escaping for names to be used
1448          * as file names in the cgroup tree: any name which might
1449          * conflict with a kernel name or is prefixed with '_' is
1450          * prefixed with a '_'. That way, when reading cgroup names it
1451          * is sufficient to remove a single prefixing underscore if
1452          * there is one. */
1453
1454         /* The return value of this function (unlike cg_unescape())
1455          * needs free()! */
1456
1457         if (p[0] == 0 ||
1458             p[0] == '_' ||
1459             p[0] == '.' ||
1460             streq(p, "notify_on_release") ||
1461             streq(p, "release_agent") ||
1462             streq(p, "tasks"))
1463                 need_prefix = true;
1464         else {
1465                 const char *dot;
1466
1467                 dot = strrchr(p, '.');
1468                 if (dot) {
1469
1470                         if (dot - p == 6 && memcmp(p, "cgroup", 6) == 0)
1471                                 need_prefix = true;
1472                         else {
1473                                 char *n;
1474
1475                                 n = strndupa(p, dot - p);
1476
1477                                 if (check_hierarchy(n) >= 0)
1478                                         need_prefix = true;
1479                         }
1480                 }
1481         }
1482
1483         if (need_prefix)
1484                 return strappend("_", p);
1485         else
1486                 return strdup(p);
1487 }
1488
1489 char *cg_unescape(const char *p) {
1490         assert(p);
1491
1492         /* The return value of this function (unlike cg_escape())
1493          * doesn't need free()! */
1494
1495         if (p[0] == '_')
1496                 return (char*) p+1;
1497
1498         return (char*) p;
1499 }
1500
1501 #define CONTROLLER_VALID                        \
1502         DIGITS LETTERS                          \
1503         "_"
1504
1505 bool cg_controller_is_valid(const char *p, bool allow_named) {
1506         const char *t, *s;
1507
1508         if (!p)
1509                 return false;
1510
1511         if (allow_named) {
1512                 s = startswith(p, "name=");
1513                 if (s)
1514                         p = s;
1515         }
1516
1517         if (*p == 0 || *p == '_')
1518                 return false;
1519
1520         for (t = p; *t; t++)
1521                 if (!strchr(CONTROLLER_VALID, *t))
1522                         return false;
1523
1524         if (t - p > FILENAME_MAX)
1525                 return false;
1526
1527         return true;
1528 }
1529
1530 int cg_slice_to_path(const char *unit, char **ret) {
1531         _cleanup_free_ char *p = NULL, *s = NULL, *e = NULL;
1532         const char *dash;
1533
1534         assert(unit);
1535         assert(ret);
1536
1537         if (!unit_name_is_valid(unit, TEMPLATE_INVALID))
1538                 return -EINVAL;
1539
1540         if (!endswith(unit, ".slice"))
1541                 return -EINVAL;
1542
1543         p = unit_name_to_prefix(unit);
1544         if (!p)
1545                 return -ENOMEM;
1546
1547         dash = strchr(p, '-');
1548         while (dash) {
1549                 _cleanup_free_ char *escaped = NULL;
1550                 char n[dash - p + sizeof(".slice")];
1551
1552                 strcpy(stpncpy(n, p, dash - p), ".slice");
1553
1554                 if (!unit_name_is_valid(n, TEMPLATE_INVALID))
1555                         return -EINVAL;
1556
1557                 escaped = cg_escape(n);
1558                 if (!escaped)
1559                         return -ENOMEM;
1560
1561                 if (!strextend(&s, escaped, "/", NULL))
1562                         return -ENOMEM;
1563
1564                 dash = strchr(dash+1, '-');
1565         }
1566
1567         e = cg_escape(unit);
1568         if (!e)
1569                 return -ENOMEM;
1570
1571         if (!strextend(&s, e, NULL))
1572                 return -ENOMEM;
1573
1574         *ret = s;
1575         s = NULL;
1576
1577         return 0;
1578 }
1579
1580 int cg_set_attribute(const char *controller, const char *path, const char *attribute, const char *value) {
1581         _cleanup_free_ char *p = NULL;
1582         int r;
1583
1584         r = cg_get_path(controller, path, attribute, &p);
1585         if (r < 0)
1586                 return r;
1587
1588         return write_string_file_no_create(p, value);
1589 }
1590
1591 int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret) {
1592         _cleanup_free_ char *p = NULL;
1593         int r;
1594
1595         r = cg_get_path(controller, path, attribute, &p);
1596         if (r < 0)
1597                 return r;
1598
1599         return read_one_line_file(p, ret);
1600 }
1601
1602 static const char mask_names[] =
1603         "cpu\0"
1604         "cpuacct\0"
1605         "blkio\0"
1606         "memory\0"
1607         "devices\0";
1608
1609 int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask mask, const char *path) {
1610         CGroupControllerMask bit = 1;
1611         const char *n;
1612         int r;
1613
1614         /* This one will create a cgroup in our private tree, but also
1615          * duplicate it in the trees specified in mask, and remove it
1616          * in all others */
1617
1618         /* First create the cgroup in our own hierarchy. */
1619         r = cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
1620         if (r < 0)
1621                 return r;
1622
1623         /* Then, do the same in the other hierarchies */
1624         NULSTR_FOREACH(n, mask_names) {
1625                 if (mask & bit)
1626                         cg_create(n, path);
1627                 else if (supported & bit)
1628                         cg_trim(n, path, true);
1629
1630                 bit <<= 1;
1631         }
1632
1633         return 0;
1634 }
1635
1636 int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) {
1637         CGroupControllerMask bit = 1;
1638         const char *n;
1639         int r;
1640
1641         r = cg_attach(SYSTEMD_CGROUP_CONTROLLER, path, pid);
1642         if (r < 0)
1643                 return r;
1644
1645         NULSTR_FOREACH(n, mask_names) {
1646
1647                 if (supported & bit) {
1648                         const char *p = NULL;
1649
1650                         if (path_callback)
1651                                 p = path_callback(bit, userdata);
1652
1653                         if (!p)
1654                                 p = path;
1655
1656                         cg_attach_fallback(n, path, pid);
1657                 }
1658
1659                 bit <<= 1;
1660         }
1661
1662         return 0;
1663 }
1664
1665 int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids, cg_migrate_callback_t path_callback, void *userdata) {
1666         Iterator i;
1667         void *pidp;
1668         int r = 0;
1669
1670         SET_FOREACH(pidp, pids, i) {
1671                 pid_t pid = PTR_TO_LONG(pidp);
1672                 int q;
1673
1674                 q = cg_attach_everywhere(supported, path, pid, path_callback, userdata);
1675                 if (q < 0)
1676                         r = q;
1677         }
1678
1679         return r;
1680 }
1681
1682 int cg_migrate_everywhere(CGroupControllerMask supported, const char *from, const char *to, cg_migrate_callback_t to_callback, void *userdata) {
1683         CGroupControllerMask bit = 1;
1684         const char *n;
1685         int r;
1686
1687         if (!path_equal(from, to))  {
1688                 r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true);
1689                 if (r < 0)
1690                         return r;
1691         }
1692
1693         NULSTR_FOREACH(n, mask_names) {
1694                 if (supported & bit) {
1695                         const char *p = NULL;
1696
1697                         if (to_callback)
1698                                 p = to_callback(bit, userdata);
1699
1700                         if (!p)
1701                                 p = to;
1702
1703                         cg_migrate_recursive_fallback(SYSTEMD_CGROUP_CONTROLLER, to, n, p, false, false);
1704                 }
1705
1706                 bit <<= 1;
1707         }
1708
1709         return 0;
1710 }
1711
1712 int cg_trim_everywhere(CGroupControllerMask supported, const char *path, bool delete_root) {
1713         CGroupControllerMask bit = 1;
1714         const char *n;
1715         int r;
1716
1717         r = cg_trim(SYSTEMD_CGROUP_CONTROLLER, path, delete_root);
1718         if (r < 0)
1719                 return r;
1720
1721         NULSTR_FOREACH(n, mask_names) {
1722                 if (supported & bit)
1723                         cg_trim(n, path, delete_root);
1724
1725                 bit <<= 1;
1726         }
1727
1728         return 0;
1729 }
1730
1731 CGroupControllerMask cg_mask_supported(void) {
1732         CGroupControllerMask bit = 1, mask = 0;
1733         const char *n;
1734
1735         NULSTR_FOREACH(n, mask_names) {
1736                 if (check_hierarchy(n) >= 0)
1737                         mask |= bit;
1738
1739                 bit <<= 1;
1740         }
1741
1742         return mask;
1743 }
1744
1745 int cg_kernel_controllers(Set *controllers) {
1746         _cleanup_fclose_ FILE *f = NULL;
1747         char buf[LINE_MAX];
1748         int r;
1749
1750         assert(controllers);
1751
1752         f = fopen("/proc/cgroups", "re");
1753         if (!f) {
1754                 if (errno == ENOENT)
1755                         return 0;
1756                 return -errno;
1757         }
1758
1759         /* Ignore the header line */
1760         (void) fgets(buf, sizeof(buf), f);
1761
1762         for (;;) {
1763                 char *controller;
1764                 int enabled = 0;
1765
1766                 errno = 0;
1767                 if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) {
1768
1769                         if (feof(f))
1770                                 break;
1771
1772                         if (ferror(f) && errno)
1773                                 return -errno;
1774
1775                         return -EBADMSG;
1776                 }
1777
1778                 if (!enabled) {
1779                         free(controller);
1780                         continue;
1781                 }
1782
1783                 if (!filename_is_valid(controller)) {
1784                         free(controller);
1785                         return -EBADMSG;
1786                 }
1787
1788                 r = set_consume(controllers, controller);
1789                 if (r < 0)
1790                         return r;
1791         }
1792
1793         return 0;
1794 }