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