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