chiark / gitweb /
cgroup: additional validity checks for cgroup attribute names
[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
41 int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
42         char *fs;
43         int r;
44         FILE *f;
45
46         assert(path);
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         free(fs);
55
56         if (!f)
57                 return -errno;
58
59         *_f = f;
60         return 0;
61 }
62
63 int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f) {
64         char *fs;
65         int r;
66         FILE *f;
67
68         assert(path);
69         assert(_f);
70
71         r = cg_get_path(controller, path, "tasks", &fs);
72         if (r < 0)
73                 return r;
74
75         f = fopen(fs, "re");
76         free(fs);
77
78         if (!f)
79                 return -errno;
80
81         *_f = f;
82         return 0;
83 }
84
85 int cg_read_pid(FILE *f, pid_t *_pid) {
86         unsigned long ul;
87
88         /* Note that the cgroup.procs might contain duplicates! See
89          * cgroups.txt for details. */
90
91         errno = 0;
92         if (fscanf(f, "%lu", &ul) != 1) {
93
94                 if (feof(f))
95                         return 0;
96
97                 return errno ? -errno : -EIO;
98         }
99
100         if (ul <= 0)
101                 return -EIO;
102
103         *_pid = (pid_t) ul;
104         return 1;
105 }
106
107 int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) {
108         char *fs;
109         int r;
110         DIR *d;
111
112         assert(path);
113         assert(_d);
114
115         /* This is not recursive! */
116
117         r = cg_get_path(controller, path, NULL, &fs);
118         if (r < 0)
119                 return r;
120
121         d = opendir(fs);
122         free(fs);
123
124         if (!d)
125                 return -errno;
126
127         *_d = d;
128         return 0;
129 }
130
131 int cg_read_subgroup(DIR *d, char **fn) {
132         struct dirent *de;
133
134         assert(d);
135
136         errno = 0;
137         while ((de = readdir(d))) {
138                 char *b;
139
140                 if (de->d_type != DT_DIR)
141                         continue;
142
143                 if (streq(de->d_name, ".") ||
144                     streq(de->d_name, ".."))
145                         continue;
146
147                 if (!(b = strdup(de->d_name)))
148                         return -ENOMEM;
149
150                 *fn = b;
151                 return 1;
152         }
153
154         if (errno)
155                 return -errno;
156
157         return 0;
158 }
159
160 int cg_rmdir(const char *controller, const char *path, bool honour_sticky) {
161         char *p;
162         int r;
163
164         r = cg_get_path(controller, path, NULL, &p);
165         if (r < 0)
166                 return r;
167
168         if (honour_sticky) {
169                 char *tasks;
170
171                 /* If the sticky bit is set don't remove the directory */
172
173                 tasks = strappend(p, "/tasks");
174                 if (!tasks) {
175                         free(p);
176                         return -ENOMEM;
177                 }
178
179                 r = file_is_priv_sticky(tasks);
180                 free(tasks);
181
182                 if (r > 0) {
183                         free(p);
184                         return 0;
185                 }
186         }
187
188         r = rmdir(p);
189         free(p);
190
191         return (r < 0 && errno != ENOENT) ? -errno : 0;
192 }
193
194 int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) {
195         bool done = false;
196         int r, ret = 0;
197         pid_t my_pid;
198         FILE *f = NULL;
199         Set *allocated_set = NULL;
200
201         assert(controller);
202         assert(path);
203         assert(sig >= 0);
204
205         /* This goes through the tasks list and kills them all. This
206          * is repeated until no further processes are added to the
207          * tasks list, to properly handle forking processes */
208
209         if (!s)
210                 if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
211                         return -ENOMEM;
212
213         my_pid = getpid();
214
215         do {
216                 pid_t pid = 0;
217                 done = true;
218
219                 if ((r = cg_enumerate_processes(controller, path, &f)) < 0) {
220                         if (ret >= 0 && r != -ENOENT)
221                                 ret = r;
222
223                         goto finish;
224                 }
225
226                 while ((r = cg_read_pid(f, &pid)) > 0) {
227
228                         if (pid == my_pid && ignore_self)
229                                 continue;
230
231                         if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid))
232                                 continue;
233
234                         /* If we haven't killed this process yet, kill
235                          * it */
236                         if (kill(pid, sig) < 0) {
237                                 if (ret >= 0 && errno != ESRCH)
238                                         ret = -errno;
239                         } else if (ret == 0) {
240
241                                 if (sigcont)
242                                         kill(pid, SIGCONT);
243
244                                 ret = 1;
245                         }
246
247                         done = false;
248
249                         if ((r = set_put(s, LONG_TO_PTR(pid))) < 0) {
250                                 if (ret >= 0)
251                                         ret = r;
252
253                                 goto finish;
254                         }
255                 }
256
257                 if (r < 0) {
258                         if (ret >= 0)
259                                 ret = r;
260
261                         goto finish;
262                 }
263
264                 fclose(f);
265                 f = NULL;
266
267                 /* To avoid racing against processes which fork
268                  * quicker than we can kill them we repeat this until
269                  * no new pids need to be killed. */
270
271         } while (!done);
272
273 finish:
274         if (allocated_set)
275                 set_free(allocated_set);
276
277         if (f)
278                 fclose(f);
279
280         return ret;
281 }
282
283 int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool rem, Set *s) {
284         int r, ret = 0;
285         DIR *d = NULL;
286         char *fn;
287         Set *allocated_set = NULL;
288
289         assert(path);
290         assert(controller);
291         assert(sig >= 0);
292
293         if (!s)
294                 if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
295                         return -ENOMEM;
296
297         ret = cg_kill(controller, path, sig, sigcont, ignore_self, s);
298
299         if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) {
300                 if (ret >= 0 && r != -ENOENT)
301                         ret = r;
302
303                 goto finish;
304         }
305
306         while ((r = cg_read_subgroup(d, &fn)) > 0) {
307                 char *p = NULL;
308
309                 r = asprintf(&p, "%s/%s", path, fn);
310                 free(fn);
311
312                 if (r < 0) {
313                         if (ret >= 0)
314                                 ret = -ENOMEM;
315
316                         goto finish;
317                 }
318
319                 r = cg_kill_recursive(controller, p, sig, sigcont, ignore_self, rem, s);
320                 free(p);
321
322                 if (r != 0 && ret >= 0)
323                         ret = r;
324         }
325
326         if (r < 0 && ret >= 0)
327                 ret = r;
328
329         if (rem)
330                 if ((r = cg_rmdir(controller, path, true)) < 0) {
331                         if (ret >= 0 &&
332                             r != -ENOENT &&
333                             r != -EBUSY)
334                                 ret = r;
335                 }
336
337 finish:
338         if (d)
339                 closedir(d);
340
341         if (allocated_set)
342                 set_free(allocated_set);
343
344         return ret;
345 }
346
347 int cg_kill_recursive_and_wait(const char *controller, const char *path, bool rem) {
348         unsigned i;
349
350         assert(path);
351         assert(controller);
352
353         /* This safely kills all processes; first it sends a SIGTERM,
354          * then checks 8 times after 200ms whether the group is now
355          * empty, then kills everything that is left with SIGKILL and
356          * finally checks 5 times after 200ms each whether the group
357          * is finally empty. */
358
359         for (i = 0; i < 15; i++) {
360                 int sig, r;
361
362                 if (i <= 0)
363                         sig = SIGTERM;
364                 else if (i == 9)
365                         sig = SIGKILL;
366                 else
367                         sig = 0;
368
369                 if ((r = cg_kill_recursive(controller, path, sig, true, true, rem, NULL)) <= 0)
370                         return r;
371
372                 usleep(200 * USEC_PER_MSEC);
373         }
374
375         return 0;
376 }
377
378 int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self) {
379         bool done = false;
380         _cleanup_set_free_ Set *s = NULL;
381         int r, ret = 0;
382         pid_t my_pid;
383         _cleanup_fclose_ FILE *f = NULL;
384
385         assert(cfrom);
386         assert(pfrom);
387         assert(cto);
388         assert(pto);
389
390         s = set_new(trivial_hash_func, trivial_compare_func);
391         if (!s)
392                 return -ENOMEM;
393
394         my_pid = getpid();
395
396         do {
397                 pid_t pid = 0;
398                 done = true;
399
400                 r = cg_enumerate_tasks(cfrom, pfrom, &f);
401                 if (r < 0) {
402                         if (ret >= 0 && r != -ENOENT)
403                                 ret = r;
404
405                         return ret;
406                 }
407
408                 while ((r = cg_read_pid(f, &pid)) > 0) {
409
410                         /* This might do weird stuff if we aren't a
411                          * single-threaded program. However, we
412                          * luckily know we are not */
413                         if (pid == my_pid && ignore_self)
414                                 continue;
415
416                         if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid))
417                                 continue;
418
419                         r = cg_attach(cto, pto, pid);
420                         if (r < 0) {
421                                 if (ret >= 0 && r != -ESRCH)
422                                         ret = r;
423                         } else if (ret == 0)
424                                 ret = 1;
425
426                         done = false;
427
428                         r = set_put(s, LONG_TO_PTR(pid));
429                         if (r < 0) {
430                                 if (ret >= 0)
431                                         ret = r;
432
433                                 return ret;
434                         }
435                 }
436
437                 if (r < 0) {
438                         if (ret >= 0)
439                                 ret = r;
440
441                         return ret;
442                 }
443
444                 fclose(f);
445                 f = NULL;
446         } while (!done);
447
448         return ret;
449 }
450
451 int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool rem) {
452         int r, ret = 0;
453         _cleanup_closedir_ DIR *d = NULL;
454         char *fn;
455
456         assert(cfrom);
457         assert(pfrom);
458         assert(cto);
459         assert(pto);
460
461         ret = cg_migrate(cfrom, pfrom, cto, pto, ignore_self);
462
463         r = cg_enumerate_subgroups(cfrom, pfrom, &d);
464         if (r < 0) {
465                 if (ret >= 0 && r != -ENOENT)
466                         ret = r;
467                 return ret;
468         }
469
470         while ((r = cg_read_subgroup(d, &fn)) > 0) {
471                 _cleanup_free_ char *p = NULL;
472
473                 p = strjoin(pfrom, "/", fn, NULL);
474                 free(fn);
475                 if (!p) {
476                         if (ret >= 0)
477                                 ret = -ENOMEM;
478
479                         return ret;
480                 }
481
482                 r = cg_migrate_recursive(cfrom, p, cto, pto, ignore_self, rem);
483                 if (r != 0 && ret >= 0)
484                         ret = r;
485         }
486
487         if (r < 0 && ret >= 0)
488                 ret = r;
489
490         if (rem) {
491                 r = cg_rmdir(cfrom, pfrom, true);
492                 if (r < 0 && ret >= 0 && r != -ENOENT && r != -EBUSY)
493                         return r;
494         }
495
496         return ret;
497 }
498
499 static const char *normalize_controller(const char *controller) {
500
501         if (streq(controller, SYSTEMD_CGROUP_CONTROLLER))
502                 return "systemd";
503         else if (startswith(controller, "name="))
504                 return controller + 5;
505         else
506                 return controller;
507 }
508
509 static int join_path(const char *controller, const char *path, const char *suffix, char **fs) {
510         char *t = NULL;
511
512         if (!(controller || path))
513                 return -EINVAL;
514
515         if (controller) {
516                 if (path && suffix)
517                         t = strjoin("/sys/fs/cgroup/", controller, "/", path, "/", suffix, NULL);
518                 else if (path)
519                         t = strjoin("/sys/fs/cgroup/", controller, "/", path, NULL);
520                 else if (suffix)
521                         t = strjoin("/sys/fs/cgroup/", controller, "/", suffix, NULL);
522                 else
523                         t = strjoin("/sys/fs/cgroup/", controller, NULL);
524         } else {
525                 if (path && suffix)
526                         t = strjoin(path, "/", suffix, NULL);
527                 else if (path)
528                         t = strdup(path);
529         }
530
531         if (!t)
532                 return -ENOMEM;
533
534         path_kill_slashes(t);
535
536         *fs = t;
537         return 0;
538 }
539
540 int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) {
541         const char *p;
542         static __thread bool good = false;
543
544         assert(fs);
545
546         if (_unlikely_(!good)) {
547                 int r;
548
549                 r = path_is_mount_point("/sys/fs/cgroup", false);
550                 if (r <= 0)
551                         return r < 0 ? r : -ENOENT;
552
553                 /* Cache this to save a few stat()s */
554                 good = true;
555         }
556
557         p = controller ? normalize_controller(controller) : NULL;
558         return join_path(p, path, suffix, fs);
559 }
560
561 static int check(const char *p) {
562         char *cc;
563
564         assert(p);
565
566         /* Check if this controller actually really exists */
567         cc = alloca(sizeof("/sys/fs/cgroup/") + strlen(p));
568         strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p);
569         if (access(cc, F_OK) < 0)
570                 return -errno;
571
572         return 0;
573 }
574
575 int cg_get_path_and_check(const char *controller, const char *path, const char *suffix, char **fs) {
576         const char *p;
577         int r;
578
579         assert(controller);
580         assert(fs);
581
582         if (isempty(controller))
583                 return -EINVAL;
584
585         /* Normalize the controller syntax */
586         p = normalize_controller(controller);
587
588         /* Check if this controller actually really exists */
589         r = check(p);
590         if (r < 0)
591                 return r;
592
593         return join_path(p, path, suffix, fs);
594 }
595
596 static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
597         char *p;
598         bool is_sticky;
599
600         if (typeflag != FTW_DP)
601                 return 0;
602
603         if (ftwbuf->level < 1)
604                 return 0;
605
606         p = strappend(path, "/tasks");
607         if (!p) {
608                 errno = ENOMEM;
609                 return 1;
610         }
611
612         is_sticky = file_is_priv_sticky(p) > 0;
613         free(p);
614
615         if (is_sticky)
616                 return 0;
617
618         rmdir(path);
619         return 0;
620 }
621
622 int cg_trim(const char *controller, const char *path, bool delete_root) {
623         char *fs;
624         int r = 0;
625
626         assert(controller);
627         assert(path);
628
629         r = cg_get_path(controller, path, NULL, &fs);
630         if (r < 0)
631                 return r;
632
633         errno = 0;
634         if (nftw(fs, trim_cb, 64, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0)
635                 r = errno ? -errno : -EIO;
636
637         if (delete_root) {
638                 bool is_sticky;
639                 char *p;
640
641                 p = strappend(fs, "/tasks");
642                 if (!p) {
643                         free(fs);
644                         return -ENOMEM;
645                 }
646
647                 is_sticky = file_is_priv_sticky(p) > 0;
648                 free(p);
649
650                 if (!is_sticky)
651                         if (rmdir(fs) < 0 && errno != ENOENT) {
652                                 if (r == 0)
653                                         r = -errno;
654                         }
655         }
656
657         free(fs);
658
659         return r;
660 }
661
662 int cg_delete(const char *controller, const char *path) {
663         char *parent;
664         int r;
665
666         assert(controller);
667         assert(path);
668
669         if ((r = path_get_parent(path, &parent)) < 0)
670                 return r;
671
672         r = cg_migrate_recursive(controller, path, controller, parent, false, true);
673         free(parent);
674
675         return r == -ENOENT ? 0 : r;
676 }
677
678 int cg_attach(const char *controller, const char *path, pid_t pid) {
679         char *fs;
680         int r;
681         char c[32];
682
683         assert(controller);
684         assert(path);
685         assert(pid >= 0);
686
687         r = cg_get_path_and_check(controller, path, "tasks", &fs);
688         if (r < 0)
689                 return r;
690
691         if (pid == 0)
692                 pid = getpid();
693
694         snprintf(c, sizeof(c), "%lu\n", (unsigned long) pid);
695         char_array_0(c);
696
697         r = write_one_line_file(fs, c);
698         free(fs);
699
700         return r;
701 }
702
703 int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid) {
704         char *fs;
705         int r;
706
707         assert(controller);
708         assert(path);
709
710         if (mode != (mode_t) -1)
711                 mode &= 0777;
712
713         r = cg_get_path(controller, path, NULL, &fs);
714         if (r < 0)
715                 return r;
716
717         r = chmod_and_chown(fs, mode, uid, gid);
718         free(fs);
719
720         return r;
721 }
722
723 int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid, int sticky) {
724         char *fs;
725         int r;
726
727         assert(controller);
728         assert(path);
729
730         if (mode == (mode_t) -1 && uid == (uid_t) -1 && gid == (gid_t) -1 && sticky < 0)
731                 return 0;
732
733         if (mode != (mode_t) -1)
734                 mode &= 0666;
735
736         r = cg_get_path(controller, path, "tasks", &fs);
737         if (r < 0)
738                 return r;
739
740         if (sticky >= 0 && mode != (mode_t) -1)
741                 /* Both mode and sticky param are passed */
742                 mode |= (sticky ? S_ISVTX : 0);
743         else if ((sticky >= 0 && mode == (mode_t) -1) ||
744                  (mode != (mode_t) -1 && sticky < 0)) {
745                 struct stat st;
746
747                 /* Only one param is passed, hence read the current
748                  * mode from the file itself */
749
750                 r = lstat(fs, &st);
751                 if (r < 0) {
752                         free(fs);
753                         return -errno;
754                 }
755
756                 if (mode == (mode_t) -1)
757                         /* No mode set, we just shall set the sticky bit */
758                         mode = (st.st_mode & ~S_ISVTX) | (sticky ? S_ISVTX : 0);
759                 else
760                         /* Only mode set, leave sticky bit untouched */
761                         mode = (st.st_mode & ~0777) | mode;
762         }
763
764         r = chmod_and_chown(fs, mode, uid, gid);
765         free(fs);
766
767         return r;
768 }
769
770 int cg_get_by_pid(const char *controller, pid_t pid, char **path) {
771         int r;
772         char *p = NULL;
773         FILE *f;
774         char *fs;
775         size_t cs;
776
777         assert(controller);
778         assert(path);
779         assert(pid >= 0);
780
781         if (pid == 0)
782                 pid = getpid();
783
784         if (asprintf(&fs, "/proc/%lu/cgroup", (unsigned long) pid) < 0)
785                 return -ENOMEM;
786
787         f = fopen(fs, "re");
788         free(fs);
789
790         if (!f)
791                 return errno == ENOENT ? -ESRCH : -errno;
792
793         cs = strlen(controller);
794
795         while (!feof(f)) {
796                 char line[LINE_MAX];
797                 char *l;
798
799                 errno = 0;
800                 if (!(fgets(line, sizeof(line), f))) {
801                         if (feof(f))
802                                 break;
803
804                         r = errno ? -errno : -EIO;
805                         goto finish;
806                 }
807
808                 truncate_nl(line);
809
810                 if (!(l = strchr(line, ':')))
811                         continue;
812
813                 l++;
814                 if (strncmp(l, controller, cs) != 0)
815                         continue;
816
817                 if (l[cs] != ':')
818                         continue;
819
820                 if (!(p = strdup(l + cs + 1))) {
821                         r = -ENOMEM;
822                         goto finish;
823                 }
824
825                 *path = p;
826                 r = 0;
827                 goto finish;
828         }
829
830         r = -ENOENT;
831
832 finish:
833         fclose(f);
834
835         return r;
836 }
837
838 int cg_install_release_agent(const char *controller, const char *agent) {
839         char *fs = NULL, *contents = NULL, *line = NULL, *sc;
840         int r;
841
842         assert(controller);
843         assert(agent);
844
845         if ((r = cg_get_path(controller, NULL, "release_agent", &fs)) < 0)
846                 return r;
847
848         if ((r = read_one_line_file(fs, &contents)) < 0)
849                 goto finish;
850
851         sc = strstrip(contents);
852         if (sc[0] == 0) {
853
854                 if (asprintf(&line, "%s\n", agent) < 0) {
855                         r = -ENOMEM;
856                         goto finish;
857                 }
858
859                 if ((r = write_one_line_file(fs, line)) < 0)
860                         goto finish;
861
862         } else if (!streq(sc, agent)) {
863                 r = -EEXIST;
864                 goto finish;
865         }
866
867         free(fs);
868         fs = NULL;
869         if ((r = cg_get_path(controller, NULL, "notify_on_release", &fs)) < 0)
870                 goto finish;
871
872         free(contents);
873         contents = NULL;
874         if ((r = read_one_line_file(fs, &contents)) < 0)
875                 goto finish;
876
877         sc = strstrip(contents);
878
879         if (streq(sc, "0")) {
880                 if ((r = write_one_line_file(fs, "1\n")) < 0)
881                         goto finish;
882
883                 r = 1;
884         } else if (!streq(sc, "1")) {
885                 r = -EIO;
886                 goto finish;
887         } else
888                 r = 0;
889
890 finish:
891         free(fs);
892         free(contents);
893         free(line);
894
895         return r;
896 }
897
898 int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
899         pid_t pid = 0, self_pid;
900         int r;
901         FILE *f = NULL;
902         bool found = false;
903
904         assert(path);
905
906         r = cg_enumerate_tasks(controller, path, &f);
907         if (r < 0)
908                 return r == -ENOENT ? 1 : r;
909
910         self_pid = getpid();
911
912         while ((r = cg_read_pid(f, &pid)) > 0) {
913
914                 if (ignore_self && pid == self_pid)
915                         continue;
916
917                 found = true;
918                 break;
919         }
920
921         fclose(f);
922
923         if (r < 0)
924                 return r;
925
926         return !found;
927 }
928
929 int cg_is_empty_by_spec(const char *spec, bool ignore_self) {
930         int r;
931         _cleanup_free_ char *controller = NULL, *path = NULL;
932
933         assert(spec);
934
935         r = cg_split_spec(spec, &controller, &path);
936         if (r < 0)
937                 return r;
938
939         return cg_is_empty(controller, path, ignore_self);
940 }
941
942 int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self) {
943         int r;
944         DIR *d = NULL;
945         char *fn;
946
947         assert(path);
948
949         r = cg_is_empty(controller, path, ignore_self);
950         if (r <= 0)
951                 return r;
952
953         r = cg_enumerate_subgroups(controller, path, &d);
954         if (r < 0)
955                 return r == -ENOENT ? 1 : r;
956
957         while ((r = cg_read_subgroup(d, &fn)) > 0) {
958                 char *p = NULL;
959
960                 r = asprintf(&p, "%s/%s", path, fn);
961                 free(fn);
962
963                 if (r < 0) {
964                         r = -ENOMEM;
965                         goto finish;
966                 }
967
968                 r = cg_is_empty_recursive(controller, p, ignore_self);
969                 free(p);
970
971                 if (r <= 0)
972                         goto finish;
973         }
974
975         if (r >= 0)
976                 r = 1;
977
978 finish:
979
980         if (d)
981                 closedir(d);
982
983         return r;
984 }
985
986 int cg_split_spec(const char *spec, char **controller, char **path) {
987         const char *e;
988         char *t = NULL, *u = NULL;
989
990         assert(spec);
991
992         if (*spec == '/') {
993                 if (!path_is_safe(spec))
994                         return -EINVAL;
995
996                 if (path) {
997                         t = strdup(spec);
998                         if (!t)
999                                 return -ENOMEM;
1000
1001                         *path = t;
1002                 }
1003
1004                 if (controller)
1005                         *controller = NULL;
1006
1007                 return 0;
1008         }
1009
1010         e = strchr(spec, ':');
1011         if (!e) {
1012                 if (!filename_is_safe(spec))
1013                         return -EINVAL;
1014
1015                 if (controller) {
1016                         t = strdup(spec);
1017                         if (!t)
1018                                 return -ENOMEM;
1019
1020                         *controller = t;
1021                 }
1022
1023                 if (path)
1024                         *path = NULL;
1025
1026                 return 0;
1027         }
1028
1029         t = strndup(spec, e-spec);
1030         if (!t)
1031                 return -ENOMEM;
1032         if (!filename_is_safe(t)) {
1033                 free(t);
1034                 return -EINVAL;
1035         }
1036
1037         u = strdup(e+1);
1038         if (!u) {
1039                 free(t);
1040                 return -ENOMEM;
1041         }
1042         if (!path_is_safe(u)) {
1043                 free(t);
1044                 free(u);
1045                 return -EINVAL;
1046         }
1047
1048         if (controller)
1049                 *controller = t;
1050         else
1051                 free(t);
1052
1053         if (path)
1054                 *path = u;
1055         else
1056                 free(u);
1057
1058         return 0;
1059 }
1060
1061 int cg_join_spec(const char *controller, const char *path, char **spec) {
1062         assert(controller);
1063         assert(path);
1064
1065         if (!path_is_absolute(path) ||
1066             controller[0] == 0 ||
1067             strchr(controller, ':') ||
1068             strchr(controller, '/'))
1069                 return -EINVAL;
1070
1071         if (asprintf(spec, "%s:%s", controller, path) < 0)
1072                 return -ENOMEM;
1073
1074         return 0;
1075 }
1076
1077 int cg_fix_path(const char *path, char **result) {
1078         char *t, *c, *p;
1079         int r;
1080
1081         assert(path);
1082         assert(result);
1083
1084         /* First check if it already is a filesystem path */
1085         if (path_startswith(path, "/sys/fs/cgroup") &&
1086             access(path, F_OK) >= 0) {
1087
1088                 t = strdup(path);
1089                 if (!t)
1090                         return -ENOMEM;
1091
1092                 *result = t;
1093                 return 0;
1094         }
1095
1096         /* Otherwise treat it as cg spec */
1097         r = cg_split_spec(path, &c, &p);
1098         if (r < 0)
1099                 return r;
1100
1101         r = cg_get_path(c ? c : SYSTEMD_CGROUP_CONTROLLER, p ? p : "/", NULL, result);
1102         free(c);
1103         free(p);
1104
1105         return r;
1106 }
1107
1108 int cg_get_user_path(char **path) {
1109         char *root, *p;
1110
1111         assert(path);
1112
1113         /* Figure out the place to put user cgroups below. We use the
1114          * same as PID 1 has but with the "/system" suffix replaced by
1115          * "/user" */
1116
1117         if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root) < 0)
1118                 p = strdup("/user");
1119         else {
1120                 if (endswith(root, "/system"))
1121                         root[strlen(root) - 7] = 0;
1122                 else if (streq(root, "/"))
1123                         root[0] = 0;
1124
1125                 p = strappend(root, "/user");
1126                 free(root);
1127         }
1128
1129         if (!p)
1130                 return -ENOMEM;
1131
1132         *path = p;
1133         return 0;
1134 }
1135
1136 char **cg_shorten_controllers(char **controllers) {
1137         char **f, **t;
1138
1139         controllers = strv_uniq(controllers);
1140
1141         if (!controllers)
1142                 return controllers;
1143
1144         for (f = controllers, t = controllers; *f; f++) {
1145                 int r;
1146                 const char *p;
1147
1148                 if (streq(*f, "systemd") || streq(*f, SYSTEMD_CGROUP_CONTROLLER)) {
1149                         free(*f);
1150                         continue;
1151                 }
1152
1153                 p = normalize_controller(*f);
1154
1155                 r = check(p);
1156                 if (r < 0) {
1157                         log_debug("Controller %s is not available, removing from controllers list.", *f);
1158                         free(*f);
1159                         continue;
1160                 }
1161
1162                 *(t++) = *f;
1163         }
1164
1165         *t = NULL;
1166         return controllers;
1167 }
1168
1169 int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) {
1170         char *cg_process, *cg_init, *p;
1171         int r;
1172
1173         assert(pid >= 0);
1174
1175         if (pid == 0)
1176                 pid = getpid();
1177
1178         r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &cg_process);
1179         if (r < 0)
1180                 return r;
1181
1182         r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &cg_init);
1183         if (r < 0) {
1184                 free(cg_process);
1185                 return r;
1186         }
1187
1188         if (endswith(cg_init, "/system"))
1189                 cg_init[strlen(cg_init)-7] = 0;
1190         else if (streq(cg_init, "/"))
1191                 cg_init[0] = 0;
1192
1193         if (startswith(cg_process, cg_init))
1194                 p = cg_process + strlen(cg_init);
1195         else
1196                 p = cg_process;
1197
1198         free(cg_init);
1199
1200         if (cgroup) {
1201                 char* c;
1202
1203                 c = strdup(p);
1204                 if (!c) {
1205                         free(cg_process);
1206                         return -ENOMEM;
1207                 }
1208
1209                 *cgroup = c;
1210         }
1211
1212         if (root) {
1213                 cg_process[p-cg_process] = 0;
1214                 *root = cg_process;
1215         } else
1216                 free(cg_process);
1217
1218         return 0;
1219 }
1220
1221 static int instance_unit_from_cgroup(char *cgroup){
1222         char *at;
1223
1224         assert(cgroup);
1225
1226         at = strstr(cgroup, "@.");
1227         if (at) {
1228                 /* This is a templated service */
1229
1230                 char *i;
1231                 char _cleanup_free_ *i2 = NULL, *s = NULL;
1232
1233                 i = strchr(at, '/');
1234                 if (!i || !i[1]) /* disallow empty instances */
1235                         return -EINVAL;
1236
1237                 s = strndup(at + 1, i - at - 1);
1238                 i2 = strdup(i + 1);
1239                 if (!s || !i2)
1240                         return -ENOMEM;
1241
1242                 strcpy(at + 1, i2);
1243                 strcat(at + 1, s);
1244         }
1245
1246         return 0;
1247 }
1248
1249 /* non-static only for testing purposes */
1250 int cgroup_to_unit(char *cgroup, char **unit){
1251         int r;
1252         char *p;
1253
1254         assert(cgroup);
1255         assert(unit);
1256
1257         r = instance_unit_from_cgroup(cgroup);
1258         if (r < 0)
1259                 return r;
1260
1261         p = strrchr(cgroup, '/');
1262         assert(p);
1263
1264         r = unit_name_is_valid(p + 1, true);
1265         if (!r)
1266                 return -EINVAL;
1267
1268         *unit = strdup(p + 1);
1269         if (!*unit)
1270                 return -ENOMEM;
1271
1272         return 0;
1273 }
1274
1275 static int cg_pid_get(const char *prefix, pid_t pid, char **unit) {
1276         int r;
1277         char _cleanup_free_ *cgroup = NULL;
1278
1279         assert(pid >= 0);
1280         assert(unit);
1281
1282         r = cg_pid_get_cgroup(pid, NULL, &cgroup);
1283         if (r < 0)
1284                 return r;
1285
1286         if (!startswith(cgroup, prefix))
1287                 return -ENOENT;
1288
1289         r = cgroup_to_unit(cgroup, unit);
1290         return r;
1291 }
1292
1293 int cg_pid_get_unit(pid_t pid, char **unit) {
1294         return cg_pid_get("/system/", pid, unit);
1295 }
1296
1297 int cg_pid_get_user_unit(pid_t pid, char **unit) {
1298         return cg_pid_get("/user/", pid, unit);
1299 }
1300
1301 int cg_controller_from_attr(const char *attr, char **controller) {
1302         const char *dot;
1303         char *c;
1304
1305         assert(attr);
1306         assert(controller);
1307
1308         if (!filename_is_safe(attr))
1309                 return -EINVAL;
1310
1311         dot = strchr(attr, '.');
1312         if (!dot) {
1313                 *controller = NULL;
1314                 return 0;
1315         }
1316
1317         c = strndup(attr, dot - attr);
1318         if (!c)
1319                 return -ENOMEM;
1320
1321         if (!filename_is_safe(c)) {
1322                 free(c);
1323                 return -EINVAL;
1324         }
1325
1326         *controller = c;
1327         return 1;
1328 }