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