chiark / gitweb /
cgroup: clean-ups
[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         _cleanup_free_ char *fs = NULL;
681         char c[DECIMAL_STR_MAX(pid_t) + 2];
682         int r;
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
697         return write_string_file(fs, c);
698 }
699
700 int cg_set_group_access(
701                 const char *controller,
702                 const char *path,
703                 mode_t mode,
704                 uid_t uid,
705                 gid_t gid) {
706
707         _cleanup_free_ char *fs = NULL;
708         int r;
709
710         assert(controller);
711         assert(path);
712
713         if (mode != (mode_t) -1)
714                 mode &= 0777;
715
716         r = cg_get_path(controller, path, NULL, &fs);
717         if (r < 0)
718                 return r;
719
720         return chmod_and_chown(fs, mode, uid, gid);
721 }
722
723 int cg_set_task_access(
724                 const char *controller,
725                 const char *path,
726                 mode_t mode,
727                 uid_t uid,
728                 gid_t gid,
729                 int sticky) {
730
731         _cleanup_free_ char *fs = NULL, *procs = NULL;
732         int r;
733
734         assert(controller);
735         assert(path);
736
737         if (mode == (mode_t) -1 && uid == (uid_t) -1 && gid == (gid_t) -1 && sticky < 0)
738                 return 0;
739
740         if (mode != (mode_t) -1)
741                 mode &= 0666;
742
743         r = cg_get_path(controller, path, "tasks", &fs);
744         if (r < 0)
745                 return r;
746
747         if (sticky >= 0 && mode != (mode_t) -1)
748                 /* Both mode and sticky param are passed */
749                 mode |= (sticky ? S_ISVTX : 0);
750         else if ((sticky >= 0 && mode == (mode_t) -1) ||
751                  (mode != (mode_t) -1 && sticky < 0)) {
752                 struct stat st;
753
754                 /* Only one param is passed, hence read the current
755                  * mode from the file itself */
756
757                 r = lstat(fs, &st);
758                 if (r < 0)
759                         return -errno;
760
761                 if (mode == (mode_t) -1)
762                         /* No mode set, we just shall set the sticky bit */
763                         mode = (st.st_mode & ~S_ISVTX) | (sticky ? S_ISVTX : 0);
764                 else
765                         /* Only mode set, leave sticky bit untouched */
766                         mode = (st.st_mode & ~0777) | mode;
767         }
768
769         r = chmod_and_chown(fs, mode, uid, gid);
770         if (r < 0)
771                 return r;
772
773         /* Always keep values for "cgroup.procs" in sync with "tasks" */
774         r = cg_get_path(controller, path, "cgroup.procs", &procs);
775         if (r < 0)
776                 return r;
777
778         return chmod_and_chown(procs, mode, uid, gid);
779 }
780
781 int cg_get_by_pid(const char *controller, pid_t pid, char **path) {
782         int r;
783         char *p = NULL;
784         FILE *f;
785         char *fs;
786         size_t cs;
787
788         assert(controller);
789         assert(path);
790         assert(pid >= 0);
791
792         if (pid == 0)
793                 pid = getpid();
794
795         if (asprintf(&fs, "/proc/%lu/cgroup", (unsigned long) pid) < 0)
796                 return -ENOMEM;
797
798         f = fopen(fs, "re");
799         free(fs);
800
801         if (!f)
802                 return errno == ENOENT ? -ESRCH : -errno;
803
804         cs = strlen(controller);
805
806         while (!feof(f)) {
807                 char line[LINE_MAX];
808                 char *l;
809
810                 errno = 0;
811                 if (!(fgets(line, sizeof(line), f))) {
812                         if (feof(f))
813                                 break;
814
815                         r = errno ? -errno : -EIO;
816                         goto finish;
817                 }
818
819                 truncate_nl(line);
820
821                 if (!(l = strchr(line, ':')))
822                         continue;
823
824                 l++;
825                 if (!strneq(l, controller, cs))
826                         continue;
827
828                 if (l[cs] != ':')
829                         continue;
830
831                 if (!(p = strdup(l + cs + 1))) {
832                         r = -ENOMEM;
833                         goto finish;
834                 }
835
836                 *path = p;
837                 r = 0;
838                 goto finish;
839         }
840
841         r = -ENOENT;
842
843 finish:
844         fclose(f);
845
846         return r;
847 }
848
849 int cg_install_release_agent(const char *controller, const char *agent) {
850         char *fs = NULL, *contents = NULL, *line = NULL, *sc;
851         int r;
852
853         assert(controller);
854         assert(agent);
855
856         if ((r = cg_get_path(controller, NULL, "release_agent", &fs)) < 0)
857                 return r;
858
859         if ((r = read_one_line_file(fs, &contents)) < 0)
860                 goto finish;
861
862         sc = strstrip(contents);
863         if (sc[0] == 0) {
864
865                 if (asprintf(&line, "%s\n", agent) < 0) {
866                         r = -ENOMEM;
867                         goto finish;
868                 }
869
870                 r = write_string_file(fs, line);
871                 if (r < 0)
872                         goto finish;
873
874         } else if (!streq(sc, agent)) {
875                 r = -EEXIST;
876                 goto finish;
877         }
878
879         free(fs);
880         fs = NULL;
881         if ((r = cg_get_path(controller, NULL, "notify_on_release", &fs)) < 0)
882                 goto finish;
883
884         free(contents);
885         contents = NULL;
886         if ((r = read_one_line_file(fs, &contents)) < 0)
887                 goto finish;
888
889         sc = strstrip(contents);
890
891         if (streq(sc, "0")) {
892                 if ((r = write_string_file(fs, "1\n")) < 0)
893                         goto finish;
894
895                 r = 1;
896         } else if (!streq(sc, "1")) {
897                 r = -EIO;
898                 goto finish;
899         } else
900                 r = 0;
901
902 finish:
903         free(fs);
904         free(contents);
905         free(line);
906
907         return r;
908 }
909
910 int cg_is_empty(const char *controller, const char *path, bool ignore_self) {
911         pid_t pid = 0, self_pid;
912         int r;
913         FILE *f = NULL;
914         bool found = false;
915
916         assert(path);
917
918         r = cg_enumerate_tasks(controller, path, &f);
919         if (r < 0)
920                 return r == -ENOENT ? 1 : r;
921
922         self_pid = getpid();
923
924         while ((r = cg_read_pid(f, &pid)) > 0) {
925
926                 if (ignore_self && pid == self_pid)
927                         continue;
928
929                 found = true;
930                 break;
931         }
932
933         fclose(f);
934
935         if (r < 0)
936                 return r;
937
938         return !found;
939 }
940
941 int cg_is_empty_by_spec(const char *spec, bool ignore_self) {
942         int r;
943         _cleanup_free_ char *controller = NULL, *path = NULL;
944
945         assert(spec);
946
947         r = cg_split_spec(spec, &controller, &path);
948         if (r < 0)
949                 return r;
950
951         return cg_is_empty(controller, path, ignore_self);
952 }
953
954 int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self) {
955         int r;
956         DIR *d = NULL;
957         char *fn;
958
959         assert(path);
960
961         r = cg_is_empty(controller, path, ignore_self);
962         if (r <= 0)
963                 return r;
964
965         r = cg_enumerate_subgroups(controller, path, &d);
966         if (r < 0)
967                 return r == -ENOENT ? 1 : r;
968
969         while ((r = cg_read_subgroup(d, &fn)) > 0) {
970                 char *p = NULL;
971
972                 r = asprintf(&p, "%s/%s", path, fn);
973                 free(fn);
974
975                 if (r < 0) {
976                         r = -ENOMEM;
977                         goto finish;
978                 }
979
980                 r = cg_is_empty_recursive(controller, p, ignore_self);
981                 free(p);
982
983                 if (r <= 0)
984                         goto finish;
985         }
986
987         if (r >= 0)
988                 r = 1;
989
990 finish:
991
992         if (d)
993                 closedir(d);
994
995         return r;
996 }
997
998 int cg_split_spec(const char *spec, char **controller, char **path) {
999         const char *e;
1000         char *t = NULL, *u = NULL;
1001
1002         assert(spec);
1003
1004         if (*spec == '/') {
1005                 if (!path_is_safe(spec))
1006                         return -EINVAL;
1007
1008                 if (path) {
1009                         t = strdup(spec);
1010                         if (!t)
1011                                 return -ENOMEM;
1012
1013                         *path = t;
1014                 }
1015
1016                 if (controller)
1017                         *controller = NULL;
1018
1019                 return 0;
1020         }
1021
1022         e = strchr(spec, ':');
1023         if (!e) {
1024                 if (!filename_is_safe(spec))
1025                         return -EINVAL;
1026
1027                 if (controller) {
1028                         t = strdup(spec);
1029                         if (!t)
1030                                 return -ENOMEM;
1031
1032                         *controller = t;
1033                 }
1034
1035                 if (path)
1036                         *path = NULL;
1037
1038                 return 0;
1039         }
1040
1041         t = strndup(spec, e-spec);
1042         if (!t)
1043                 return -ENOMEM;
1044         if (!filename_is_safe(t)) {
1045                 free(t);
1046                 return -EINVAL;
1047         }
1048
1049         u = strdup(e+1);
1050         if (!u) {
1051                 free(t);
1052                 return -ENOMEM;
1053         }
1054         if (!path_is_safe(u)) {
1055                 free(t);
1056                 free(u);
1057                 return -EINVAL;
1058         }
1059
1060         if (controller)
1061                 *controller = t;
1062         else
1063                 free(t);
1064
1065         if (path)
1066                 *path = u;
1067         else
1068                 free(u);
1069
1070         return 0;
1071 }
1072
1073 int cg_join_spec(const char *controller, const char *path, char **spec) {
1074         assert(controller);
1075         assert(path);
1076
1077         if (!path_is_absolute(path) ||
1078             controller[0] == 0 ||
1079             strchr(controller, ':') ||
1080             strchr(controller, '/'))
1081                 return -EINVAL;
1082
1083         if (asprintf(spec, "%s:%s", controller, path) < 0)
1084                 return -ENOMEM;
1085
1086         return 0;
1087 }
1088
1089 int cg_fix_path(const char *path, char **result) {
1090         char *t, *c, *p;
1091         int r;
1092
1093         assert(path);
1094         assert(result);
1095
1096         /* First check if it already is a filesystem path */
1097         if (path_startswith(path, "/sys/fs/cgroup") &&
1098             access(path, F_OK) >= 0) {
1099
1100                 t = strdup(path);
1101                 if (!t)
1102                         return -ENOMEM;
1103
1104                 *result = t;
1105                 return 0;
1106         }
1107
1108         /* Otherwise treat it as cg spec */
1109         r = cg_split_spec(path, &c, &p);
1110         if (r < 0)
1111                 return r;
1112
1113         r = cg_get_path(c ? c : SYSTEMD_CGROUP_CONTROLLER, p ? p : "/", NULL, result);
1114         free(c);
1115         free(p);
1116
1117         return r;
1118 }
1119
1120 int cg_get_user_path(char **path) {
1121         char *root, *p;
1122
1123         assert(path);
1124
1125         /* Figure out the place to put user cgroups below. We use the
1126          * same as PID 1 has but with the "/system" suffix replaced by
1127          * "/user" */
1128
1129         if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root) < 0)
1130                 p = strdup("/user");
1131         else {
1132                 if (endswith(root, "/system"))
1133                         root[strlen(root) - 7] = 0;
1134                 else if (streq(root, "/"))
1135                         root[0] = 0;
1136
1137                 p = strappend(root, "/user");
1138                 free(root);
1139         }
1140
1141         if (!p)
1142                 return -ENOMEM;
1143
1144         *path = p;
1145         return 0;
1146 }
1147
1148 char **cg_shorten_controllers(char **controllers) {
1149         char **f, **t;
1150
1151         controllers = strv_uniq(controllers);
1152
1153         if (!controllers)
1154                 return controllers;
1155
1156         for (f = controllers, t = controllers; *f; f++) {
1157                 int r;
1158                 const char *p;
1159
1160                 if (streq(*f, "systemd") || streq(*f, SYSTEMD_CGROUP_CONTROLLER)) {
1161                         free(*f);
1162                         continue;
1163                 }
1164
1165                 p = normalize_controller(*f);
1166
1167                 r = check(p);
1168                 if (r < 0) {
1169                         log_debug("Controller %s is not available, removing from controllers list.", *f);
1170                         free(*f);
1171                         continue;
1172                 }
1173
1174                 *(t++) = *f;
1175         }
1176
1177         *t = NULL;
1178         return controllers;
1179 }
1180
1181 int cg_pid_get_cgroup(pid_t pid, char **root, char **cgroup) {
1182         char *cg_process, *cg_init, *p;
1183         int r;
1184
1185         assert(pid >= 0);
1186
1187         if (pid == 0)
1188                 pid = getpid();
1189
1190         r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &cg_process);
1191         if (r < 0)
1192                 return r;
1193
1194         r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &cg_init);
1195         if (r < 0) {
1196                 free(cg_process);
1197                 return r;
1198         }
1199
1200         if (endswith(cg_init, "/system"))
1201                 cg_init[strlen(cg_init)-7] = 0;
1202         else if (streq(cg_init, "/"))
1203                 cg_init[0] = 0;
1204
1205         if (startswith(cg_process, cg_init))
1206                 p = cg_process + strlen(cg_init);
1207         else
1208                 p = cg_process;
1209
1210         free(cg_init);
1211
1212         if (cgroup) {
1213                 char* c;
1214
1215                 c = strdup(p);
1216                 if (!c) {
1217                         free(cg_process);
1218                         return -ENOMEM;
1219                 }
1220
1221                 *cgroup = c;
1222         }
1223
1224         if (root) {
1225                 cg_process[p-cg_process] = 0;
1226                 *root = cg_process;
1227         } else
1228                 free(cg_process);
1229
1230         return 0;
1231 }
1232
1233 static int instance_unit_from_cgroup(char *cgroup){
1234         char *at;
1235
1236         assert(cgroup);
1237
1238         at = strstr(cgroup, "@.");
1239         if (at) {
1240                 /* This is a templated service */
1241
1242                 char *i;
1243                 char _cleanup_free_ *i2 = NULL, *s = NULL;
1244
1245                 i = strchr(at, '/');
1246                 if (!i || !i[1]) /* disallow empty instances */
1247                         return -EINVAL;
1248
1249                 s = strndup(at + 1, i - at - 1);
1250                 i2 = strdup(i + 1);
1251                 if (!s || !i2)
1252                         return -ENOMEM;
1253
1254                 strcpy(at + 1, i2);
1255                 strcat(at + 1, s);
1256         }
1257
1258         return 0;
1259 }
1260
1261 /* non-static only for testing purposes */
1262 int cgroup_to_unit(char *cgroup, char **unit){
1263         int r;
1264         char *p;
1265
1266         assert(cgroup);
1267         assert(unit);
1268
1269         r = instance_unit_from_cgroup(cgroup);
1270         if (r < 0)
1271                 return r;
1272
1273         p = strrchr(cgroup, '/');
1274         assert(p);
1275
1276         r = unit_name_is_valid(p + 1, true);
1277         if (!r)
1278                 return -EINVAL;
1279
1280         *unit = strdup(p + 1);
1281         if (!*unit)
1282                 return -ENOMEM;
1283
1284         return 0;
1285 }
1286
1287 static int cg_pid_get(const char *prefix, pid_t pid, char **unit) {
1288         int r;
1289         char _cleanup_free_ *cgroup = NULL;
1290
1291         assert(pid >= 0);
1292         assert(unit);
1293
1294         r = cg_pid_get_cgroup(pid, NULL, &cgroup);
1295         if (r < 0)
1296                 return r;
1297
1298         if (!startswith(cgroup, prefix))
1299                 return -ENOENT;
1300
1301         r = cgroup_to_unit(cgroup, unit);
1302         return r;
1303 }
1304
1305 int cg_pid_get_unit(pid_t pid, char **unit) {
1306         return cg_pid_get("/system/", pid, unit);
1307 }
1308
1309 int cg_pid_get_user_unit(pid_t pid, char **unit) {
1310         return cg_pid_get("/user/", pid, unit);
1311 }
1312
1313 int cg_controller_from_attr(const char *attr, char **controller) {
1314         const char *dot;
1315         char *c;
1316
1317         assert(attr);
1318         assert(controller);
1319
1320         if (!filename_is_safe(attr))
1321                 return -EINVAL;
1322
1323         dot = strchr(attr, '.');
1324         if (!dot) {
1325                 *controller = NULL;
1326                 return 0;
1327         }
1328
1329         c = strndup(attr, dot - attr);
1330         if (!c)
1331                 return -ENOMEM;
1332
1333         if (!filename_is_safe(c)) {
1334                 free(c);
1335                 return -EINVAL;
1336         }
1337
1338         *controller = c;
1339         return 1;
1340 }