]> git.proxmox.com Git - mirror_lxcfs.git/blame - src/cgroups/cgroup.c
tree-wide: set _GNU_SOURCE in meson.build
[mirror_lxcfs.git] / src / cgroups / cgroup.c
CommitLineData
5fbea8a6
CB
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
2c6e12b7 3#include "config.h"
1f5596dd
CB
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>
5fbea8a6
CB
16#include <stdlib.h>
17#include <string.h>
1f5596dd
CB
18#include <sys/epoll.h>
19#include <sys/mount.h>
20#include <sys/stat.h>
5fbea8a6 21#include <sys/types.h>
1f5596dd 22#include <sys/vfs.h>
5fbea8a6
CB
23#include <unistd.h>
24
1f5596dd
CB
25#include "../macro.h"
26#include "../memory_utils.h"
5fbea8a6 27#include "cgroup.h"
1f5596dd 28#include "cgroup_utils.h"
5fbea8a6
CB
29#include "cgroup2_devices.h"
30
31extern struct cgroup_ops *cgfsng_ops_init(void);
32
33struct cgroup_ops *cgroup_init(void)
34{
9ce186dc 35 struct cgroup_ops *ops;
5fbea8a6 36
9ce186dc
CB
37 ops = cgfsng_ops_init();
38 if (!ops)
5fbea8a6
CB
39 return log_error_errno(NULL, errno, "Failed to initialize cgroup driver");
40
9ce186dc 41 return ops;
5fbea8a6
CB
42}
43
44void cgroup_exit(struct cgroup_ops *ops)
45{
5fbea8a6
CB
46 if (!ops)
47 return;
48
0fd1b770
CB
49 for (struct hierarchy **it = ops->hierarchies; it && *it; it++) {
50 for (char **p = (*it)->controllers; p && *p; p++)
5fbea8a6
CB
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);
0fd1b770 59 free((*it)->base_path);
5fbea8a6
CB
60 free(*it);
61 }
0646f250
CB
62
63 if (ops->mntns_fd >= 0)
64 close(ops->mntns_fd);
65
114eb8b8
CB
66 if (ops->cgroup2_root_fd >= 0)
67 close(ops->cgroup2_root_fd);
68
5fbea8a6
CB
69 free(ops->hierarchies);
70
71 free(ops);
72
73 return;
74}
75
76#define INIT_SCOPE "/init.scope"
77void 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}
1f5596dd
CB
95
96char *get_pid_cgroup(pid_t pid, const char *contrl)
97{
98 int cfd;
99
100 cfd = get_cgroup_fd(contrl);
101 if (cfd < 0)
85bd3f8e 102 return NULL;
1f5596dd
CB
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 */
114char *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}