summaryrefslogtreecommitdiffstats
path: root/src/core/cgroup.c
diff options
context:
space:
mode:
authorJulia Kartseva <hex@fb.com>2021-03-02 01:56:04 +0100
committerJulia Kartseva <hex@fb.com>2021-04-10 05:28:47 +0200
commitb894ef1b712433e07cd5f11b8f84dfaa0ce5a4ef (patch)
tree3d5b97e495031cab41c5b5213a74799b7fe71635 /src/core/cgroup.c
parentshared: bpf_attach_type {from,to} string (diff)
downloadsystemd-b894ef1b712433e07cd5f11b8f84dfaa0ce5a4ef.tar.xz
systemd-b894ef1b712433e07cd5f11b8f84dfaa0ce5a4ef.zip
cgroup: add foreign program to cgroup context
- Store foreign bpf programs in cgroup context. A program is considered foreign if it was loaded to a kernel by an entity external to systemd, so systemd is responsible only for attach and detach paths. - Support the case of pinned bpf programs: pinning to bpffs so a program is kept loaded to the kernel even when program fd is closed by a user application is a common way to extend program's lifetime. - Aadd linked list node struct with attach type and bpffs path fields.
Diffstat (limited to 'src/core/cgroup.c')
-rw-r--r--src/core/cgroup.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 96073b108b..85e90260d1 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -190,6 +190,15 @@ void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockI
free(b);
}
+void cgroup_context_remove_bpf_foreign_program(CGroupContext *c, CGroupBPFForeignProgram *p) {
+ assert(c);
+ assert(p);
+
+ LIST_REMOVE(programs, c->bpf_foreign_programs, p);
+ free(p->bpffs_path);
+ free(p);
+}
+
void cgroup_context_done(CGroupContext *c) {
assert(c);
@@ -217,6 +226,9 @@ void cgroup_context_done(CGroupContext *c) {
c->ip_filters_ingress = strv_free(c->ip_filters_ingress);
c->ip_filters_egress = strv_free(c->ip_filters_egress);
+ while (c->bpf_foreign_programs)
+ cgroup_context_remove_bpf_foreign_program(c, c->bpf_foreign_programs);
+
cpu_set_reset(&c->cpuset_cpus);
cpu_set_reset(&c->cpuset_mems);
}
@@ -360,6 +372,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
CGroupIODeviceLatency *l;
CGroupBlockIODeviceBandwidth *b;
CGroupBlockIODeviceWeight *w;
+ CGroupBPFForeignProgram *p;
CGroupDeviceAllow *a;
CGroupContext *c;
IPAddressAccessItem *iaai;
@@ -544,6 +557,10 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
STRV_FOREACH(path, c->ip_filters_egress)
fprintf(f, "%sIPEgressFilterPath: %s\n", prefix, *path);
+
+ LIST_FOREACH(programs, p, c->bpf_foreign_programs)
+ fprintf(f, "%sBPFProgram: %s:%s",
+ prefix, bpf_cgroup_attach_type_to_string(p->attach_type), p->bpffs_path);
}
int cgroup_add_device_allow(CGroupContext *c, const char *dev, const char *mode) {
@@ -575,6 +592,34 @@ int cgroup_add_device_allow(CGroupContext *c, const char *dev, const char *mode)
return 0;
}
+int cgroup_add_bpf_foreign_program(CGroupContext *c, uint32_t attach_type, const char *bpffs_path) {
+ CGroupBPFForeignProgram *p;
+ _cleanup_free_ char *d = NULL;
+
+ assert(c);
+ assert(bpffs_path);
+
+ if (!path_is_normalized(bpffs_path) || !path_is_absolute(bpffs_path))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Path is not normalized: %m");
+
+ d = strdup(bpffs_path);
+ if (!d)
+ return log_oom();
+
+ p = new(CGroupBPFForeignProgram, 1);
+ if (!p)
+ return log_oom();
+
+ *p = (CGroupBPFForeignProgram) {
+ .attach_type = attach_type,
+ .bpffs_path = TAKE_PTR(d),
+ };
+
+ LIST_PREPEND(programs, c->bpf_foreign_programs, TAKE_PTR(p));
+
+ return 0;
+}
+
#define UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(entry) \
uint64_t unit_get_ancestor_##entry(Unit *u) { \
CGroupContext *c; \