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