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