]> git.proxmox.com Git - mirror_lxcfs.git/blob - cgroups/cgroup.h
proc: split proc virtualization into separate files
[mirror_lxcfs.git] / cgroups / cgroup.h
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #ifndef __LXC_CGROUP_H
4 #define __LXC_CGROUP_H
5
6 #ifndef _GNU_SOURCE
7 #define _GNU_SOURCE
8 #endif
9
10 #ifndef FUSE_USE_VERSION
11 #define FUSE_USE_VERSION 26
12 #endif
13
14 #define _FILE_OFFSET_BITS 64
15
16 #include <errno.h>
17 #include <stdbool.h>
18 #include <stddef.h>
19 #include <sys/types.h>
20
21 #include "../config.h"
22 #include "../macro.h"
23 #include "../memory_utils.h"
24
25 #define DEFAULT_CGROUP_MOUNTPOINT "/sys/fs/cgroup"
26
27 typedef enum {
28 CGROUP_LAYOUT_UNKNOWN = -1,
29 CGROUP_LAYOUT_LEGACY = 0,
30 CGROUP_LAYOUT_HYBRID = 1,
31 CGROUP_LAYOUT_UNIFIED = 2,
32 } cgroup_layout_t;
33
34 /* A descriptor for a mounted hierarchy
35 *
36 * @controllers
37 * - legacy hierarchy
38 * Either NULL, or a null-terminated list of all the co-mounted controllers.
39 * - unified hierarchy
40 * Either NULL, or a null-terminated list of all enabled controllers.
41 *
42 * @mountpoint
43 * - The mountpoint we will use.
44 * - legacy hierarchy
45 * It will be either /sys/fs/cgroup/controller or
46 * /sys/fs/cgroup/controllerlist.
47 * - unified hierarchy
48 * It will either be /sys/fs/cgroup or /sys/fs/cgroup/<mountpoint-name>
49 * depending on whether this is a hybrid cgroup layout (mix of legacy and
50 * unified hierarchies) or a pure unified cgroup layout.
51 *
52 * @container_base_path
53 * - The cgroup under which the container cgroup path
54 * is created. This will be either the caller's cgroup (if not root), or
55 * init's cgroup (if root).
56 *
57 * @container_full_path
58 * - The full path to the containers cgroup.
59 *
60 * @monitor_full_path
61 * - The full path to the monitor's cgroup.
62 *
63 * @version
64 * - legacy hierarchy
65 * If the hierarchy is a legacy hierarchy this will be set to
66 * CGROUP_SUPER_MAGIC.
67 * - unified hierarchy
68 * If the hierarchy is a unified hierarchy this will be set to
69 * CGROUP2_SUPER_MAGIC.
70 */
71 struct hierarchy {
72 /*
73 * cgroup2 only: what files need to be chowned to delegate a cgroup to
74 * an unprivileged user.
75 */
76 char **controllers;
77 char *__controllers;
78 char *mountpoint;
79 char *base_path;
80 int version;
81
82 /* cgroup2 only */
83 unsigned int bpf_device_controller:1;
84 int fd;
85 };
86
87 struct cgroup_ops {
88 /*
89 * File descriptor of the mount namespace the cgroup hierarchies are
90 * mounted in.
91 */
92 int mntns_fd;
93
94 /* string constant */
95 const char *driver;
96
97 /* string constant */
98 const char *version;
99
100 /* @hierarchies
101 * - A NULL-terminated array of struct hierarchy, one per legacy
102 * hierarchy. No duplicates. First sufficient, writeable mounted
103 * hierarchy wins.
104 */
105 struct hierarchy **hierarchies;
106 /* Pointer to the unified hierarchy. Do not free! */
107 struct hierarchy *unified;
108
109 /*
110 * @cgroup_layout
111 * - What cgroup layout the container is running with.
112 * - CGROUP_LAYOUT_UNKNOWN
113 * The cgroup layout could not be determined. This should be treated
114 * as an error condition.
115 * - CGROUP_LAYOUT_LEGACY
116 * The container is running with all controllers mounted into legacy
117 * cgroup hierarchies.
118 * - CGROUP_LAYOUT_HYBRID
119 * The container is running with at least one controller mounted
120 * into a legacy cgroup hierarchy and a mountpoint for the unified
121 * hierarchy. The unified hierarchy can be empty (no controllers
122 * enabled) or non-empty (controllers enabled).
123 * - CGROUP_LAYOUT_UNIFIED
124 * The container is running on a pure unified cgroup hierarchy. The
125 * unified hierarchy can be empty (no controllers enabled) or
126 * non-empty (controllers enabled).
127 */
128 cgroup_layout_t cgroup_layout;
129
130 int (*num_hierarchies)(struct cgroup_ops *ops);
131 bool (*get_hierarchies)(struct cgroup_ops *ops, int n, char ***out);
132 bool (*mount)(struct cgroup_ops *ops, const char *root);
133 struct hierarchy *(*get_hierarchy)(struct cgroup_ops *ops,
134 const char *controller);
135 bool (*get)(struct cgroup_ops *ops, const char *controller,
136 const char *cgroup, const char *file, char **value);
137
138 /* memory */
139 int (*get_memory_stats)(struct cgroup_ops *ops, const char *cgroup,
140 char **value);
141 int (*get_memory_current)(struct cgroup_ops *ops, const char *cgroup,
142 char **value);
143 int (*get_memory_swap_current)(struct cgroup_ops *ops,
144 const char *cgroup, char **value);
145 int (*get_memory_max)(struct cgroup_ops *ops, const char *cgroup,
146 char **value);
147 int (*get_memory_swap_max)(struct cgroup_ops *ops, const char *cgroup,
148 char **value);
149
150 /* cpuset */
151 int (*get_cpuset_cpus)(struct cgroup_ops *ops, const char *cgroup,
152 char **value);
153 bool (*can_use_cpuview)(struct cgroup_ops *ops);
154
155 /* io */
156 int (*get_io_service_bytes)(struct cgroup_ops *ops, const char *cgroup,
157 char **value);
158 int (*get_io_service_time)(struct cgroup_ops *ops, const char *cgroup,
159 char **value);
160 int (*get_io_serviced)(struct cgroup_ops *ops, const char *cgroup,
161 char **value);
162 int (*get_io_merged)(struct cgroup_ops *ops, const char *cgroup,
163 char **value);
164 int (*get_io_wait_time)(struct cgroup_ops *ops, const char *cgroup,
165 char **value);
166 };
167
168 extern struct cgroup_ops *cgroup_ops;
169
170 extern struct cgroup_ops *cgroup_init(void);
171 extern void cgroup_exit(struct cgroup_ops *ops);
172
173 extern void prune_init_scope(char *cg);
174
175 static inline void __auto_cgroup_exit__(struct cgroup_ops **ops)
176 {
177 if (*ops)
178 cgroup_exit(*ops);
179 }
180
181 extern int cgroup_attach(const char *name, const char *lxcpath, int64_t pid);
182
183 #define __do_cgroup_exit __attribute__((__cleanup__(__auto_cgroup_exit__)))
184
185 static inline bool pure_unified_layout(const struct cgroup_ops *ops)
186 {
187 return ops->cgroup_layout == CGROUP_LAYOUT_UNIFIED;
188 }
189
190 static inline bool is_unified_hierarchy(const struct hierarchy *h)
191 {
192 return h->version == CGROUP2_SUPER_MAGIC;
193 }
194
195 static inline bool is_unified_controller(int version)
196 {
197 return version == CGROUP2_SUPER_MAGIC;
198 }
199
200 static inline int get_cgroup_fd(const char *controller)
201 {
202 struct hierarchy *h;
203
204 h = cgroup_ops->get_hierarchy(cgroup_ops, controller);
205 return h ? h->fd : -EBADF;
206 }
207
208 extern char *get_pid_cgroup(pid_t pid, const char *contrl);
209
210 extern char *get_cpuset(const char *cg);
211
212 #endif