]> git.proxmox.com Git - mirror_lxcfs.git/blame - src/cgroups/cgroup.c
Merge pull request #473 from brauner/2021-08-31.fixes
[mirror_lxcfs.git] / src / cgroups / cgroup.c
CommitLineData
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
47extern struct cgroup_ops *cgfsng_ops_init(void);
48
49struct 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
60void 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"
93void 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
112char *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 */
130char *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}