]> git.proxmox.com Git - mirror_lxcfs.git/blob - src/cgroups/cgroup.c
tree-wide: set _GNU_SOURCE in meson.build
[mirror_lxcfs.git] / src / cgroups / cgroup.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include "config.h"
4
5 #include <dirent.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <inttypes.h>
9 #include <linux/magic.h>
10 #include <linux/sched.h>
11 #include <sched.h>
12 #include <stdarg.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/epoll.h>
19 #include <sys/mount.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <sys/vfs.h>
23 #include <unistd.h>
24
25 #include "../macro.h"
26 #include "../memory_utils.h"
27 #include "cgroup.h"
28 #include "cgroup_utils.h"
29 #include "cgroup2_devices.h"
30
31 extern struct cgroup_ops *cgfsng_ops_init(void);
32
33 struct cgroup_ops *cgroup_init(void)
34 {
35 struct cgroup_ops *ops;
36
37 ops = cgfsng_ops_init();
38 if (!ops)
39 return log_error_errno(NULL, errno, "Failed to initialize cgroup driver");
40
41 return ops;
42 }
43
44 void cgroup_exit(struct cgroup_ops *ops)
45 {
46 if (!ops)
47 return;
48
49 for (struct hierarchy **it = ops->hierarchies; it && *it; it++) {
50 for (char **p = (*it)->controllers; p && *p; p++)
51 free(*p);
52 free((*it)->controllers);
53 free((*it)->__controllers);
54
55 if ((*it)->fd >= 0)
56 close((*it)->fd);
57
58 free((*it)->mountpoint);
59 free((*it)->base_path);
60 free(*it);
61 }
62
63 if (ops->mntns_fd >= 0)
64 close(ops->mntns_fd);
65
66 if (ops->cgroup2_root_fd >= 0)
67 close(ops->cgroup2_root_fd);
68
69 free(ops->hierarchies);
70
71 free(ops);
72
73 return;
74 }
75
76 #define INIT_SCOPE "/init.scope"
77 void prune_init_scope(char *cg)
78 {
79 char *point;
80
81 if (!cg)
82 return;
83
84 point = cg + strlen(cg) - strlen(INIT_SCOPE);
85 if (point < cg)
86 return;
87
88 if (strcmp(point, INIT_SCOPE) == 0) {
89 if (point == cg)
90 *(point + 1) = '\0';
91 else
92 *point = '\0';
93 }
94 }
95
96 char *get_pid_cgroup(pid_t pid, const char *contrl)
97 {
98 int cfd;
99
100 cfd = get_cgroup_fd(contrl);
101 if (cfd < 0)
102 return NULL;
103
104 if (pure_unified_layout(cgroup_ops))
105 return cg_unified_get_current_cgroup(pid);
106
107 return cg_legacy_get_current_cgroup(pid, contrl);
108 }
109
110 /*
111 * Read the cpuset.cpus for cg
112 * Return the answer in a newly allocated string which must be freed
113 */
114 char *get_cpuset(const char *cg)
115 {
116 char *value = NULL;
117 int ret;
118
119 ret = cgroup_ops->get_cpuset_cpus(cgroup_ops, cg, &value);
120 if (ret < 0)
121 return NULL;
122
123 return value;
124 }