]> git.proxmox.com Git - mirror_lxcfs.git/blob - cgroups/cgroup.h
bindings: add infrastructure for cgroup2 support
[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 #include <stdbool.h>
7 #include <stddef.h>
8 #include <sys/types.h>
9
10 #include "macro.h"
11
12 #define DEFAULT_CGROUP_MOUNTPOINT "/sys/fs/cgroup"
13
14 typedef enum {
15 CGROUP_LAYOUT_UNKNOWN = -1,
16 CGROUP_LAYOUT_LEGACY = 0,
17 CGROUP_LAYOUT_HYBRID = 1,
18 CGROUP_LAYOUT_UNIFIED = 2,
19 } cgroup_layout_t;
20
21 /* A descriptor for a mounted hierarchy
22 *
23 * @controllers
24 * - legacy hierarchy
25 * Either NULL, or a null-terminated list of all the co-mounted controllers.
26 * - unified hierarchy
27 * Either NULL, or a null-terminated list of all enabled controllers.
28 *
29 * @mountpoint
30 * - The mountpoint we will use.
31 * - legacy hierarchy
32 * It will be either /sys/fs/cgroup/controller or
33 * /sys/fs/cgroup/controllerlist.
34 * - unified hierarchy
35 * It will either be /sys/fs/cgroup or /sys/fs/cgroup/<mountpoint-name>
36 * depending on whether this is a hybrid cgroup layout (mix of legacy and
37 * unified hierarchies) or a pure unified cgroup layout.
38 *
39 * @container_base_path
40 * - The cgroup under which the container cgroup path
41 * is created. This will be either the caller's cgroup (if not root), or
42 * init's cgroup (if root).
43 *
44 * @container_full_path
45 * - The full path to the containers cgroup.
46 *
47 * @monitor_full_path
48 * - The full path to the monitor's cgroup.
49 *
50 * @version
51 * - legacy hierarchy
52 * If the hierarchy is a legacy hierarchy this will be set to
53 * CGROUP_SUPER_MAGIC.
54 * - unified hierarchy
55 * If the hierarchy is a unified hierarchy this will be set to
56 * CGROUP2_SUPER_MAGIC.
57 */
58 struct hierarchy {
59 /*
60 * cgroup2 only: what files need to be chowned to delegate a cgroup to
61 * an unprivileged user.
62 */
63 char **controllers;
64 char *__controllers;
65 char *mountpoint;
66 char *container_base_path;
67 char *container_full_path;
68 char *monitor_full_path;
69 int version;
70
71 /* cgroup2 only */
72 unsigned int bpf_device_controller:1;
73 int fd;
74 };
75
76 struct cgroup_ops {
77 /* string constant */
78 const char *driver;
79
80 /* string constant */
81 const char *version;
82
83 /* What controllers is the container supposed to use. */
84 char *container_cgroup;
85 char *monitor_cgroup;
86
87 /* @hierarchies
88 * - A NULL-terminated array of struct hierarchy, one per legacy
89 * hierarchy. No duplicates. First sufficient, writeable mounted
90 * hierarchy wins.
91 */
92 struct hierarchy **hierarchies;
93 /* Pointer to the unified hierarchy. Do not free! */
94 struct hierarchy *unified;
95
96 /*
97 * @cgroup_layout
98 * - What cgroup layout the container is running with.
99 * - CGROUP_LAYOUT_UNKNOWN
100 * The cgroup layout could not be determined. This should be treated
101 * as an error condition.
102 * - CGROUP_LAYOUT_LEGACY
103 * The container is running with all controllers mounted into legacy
104 * cgroup hierarchies.
105 * - CGROUP_LAYOUT_HYBRID
106 * The container is running with at least one controller mounted
107 * into a legacy cgroup hierarchy and a mountpoint for the unified
108 * hierarchy. The unified hierarchy can be empty (no controllers
109 * enabled) or non-empty (controllers enabled).
110 * - CGROUP_LAYOUT_UNIFIED
111 * The container is running on a pure unified cgroup hierarchy. The
112 * unified hierarchy can be empty (no controllers enabled) or
113 * non-empty (controllers enabled).
114 */
115 cgroup_layout_t cgroup_layout;
116
117 int (*num_hierarchies)(struct cgroup_ops *ops);
118 bool (*get_hierarchies)(struct cgroup_ops *ops, int n, char ***out);
119 bool (*mount)(struct cgroup_ops *ops, const char *root);
120 int (*nrtasks)(struct cgroup_ops *ops);
121 struct hierarchy *(*get_hierarchy)(struct cgroup_ops *ops,
122 const char *controller);
123 };
124
125 extern struct cgroup_ops *cgroup_init(void);
126 extern void cgroup_exit(struct cgroup_ops *ops);
127
128 extern void prune_init_scope(char *cg);
129
130 static inline void __auto_cgroup_exit__(struct cgroup_ops **ops)
131 {
132 if (*ops)
133 cgroup_exit(*ops);
134 }
135
136 extern int cgroup_attach(const char *name, const char *lxcpath, int64_t pid);
137
138 #define __do_cgroup_exit __attribute__((__cleanup__(__auto_cgroup_exit__)))
139
140 static inline bool pure_unified_layout(const struct cgroup_ops *ops)
141 {
142 return ops->cgroup_layout == CGROUP_LAYOUT_UNIFIED;
143 }
144
145 static inline bool is_unified_hierarchy(const struct hierarchy *h)
146 {
147 return h->version == CGROUP2_SUPER_MAGIC;
148 }
149
150 #endif