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