1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-01 00:51:24 +03:00

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.
This commit is contained in:
Julia Kartseva 2021-03-01 16:56:04 -08:00
parent 9984f4933b
commit b894ef1b71
2 changed files with 55 additions and 0 deletions

View File

@ -190,6 +190,15 @@ void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockI
free(b); 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) { void cgroup_context_done(CGroupContext *c) {
assert(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_ingress = strv_free(c->ip_filters_ingress);
c->ip_filters_egress = strv_free(c->ip_filters_egress); 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_cpus);
cpu_set_reset(&c->cpuset_mems); cpu_set_reset(&c->cpuset_mems);
} }
@ -360,6 +372,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
CGroupIODeviceLatency *l; CGroupIODeviceLatency *l;
CGroupBlockIODeviceBandwidth *b; CGroupBlockIODeviceBandwidth *b;
CGroupBlockIODeviceWeight *w; CGroupBlockIODeviceWeight *w;
CGroupBPFForeignProgram *p;
CGroupDeviceAllow *a; CGroupDeviceAllow *a;
CGroupContext *c; CGroupContext *c;
IPAddressAccessItem *iaai; IPAddressAccessItem *iaai;
@ -544,6 +557,10 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
STRV_FOREACH(path, c->ip_filters_egress) STRV_FOREACH(path, c->ip_filters_egress)
fprintf(f, "%sIPEgressFilterPath: %s\n", prefix, *path); 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) { 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; 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) \ #define UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(entry) \
uint64_t unit_get_ancestor_##entry(Unit *u) { \ uint64_t unit_get_ancestor_##entry(Unit *u) { \
CGroupContext *c; \ CGroupContext *c; \

View File

@ -31,6 +31,7 @@ typedef struct CGroupIODeviceLimit CGroupIODeviceLimit;
typedef struct CGroupIODeviceLatency CGroupIODeviceLatency; typedef struct CGroupIODeviceLatency CGroupIODeviceLatency;
typedef struct CGroupBlockIODeviceWeight CGroupBlockIODeviceWeight; typedef struct CGroupBlockIODeviceWeight CGroupBlockIODeviceWeight;
typedef struct CGroupBlockIODeviceBandwidth CGroupBlockIODeviceBandwidth; typedef struct CGroupBlockIODeviceBandwidth CGroupBlockIODeviceBandwidth;
typedef struct CGroupBPFForeignProgram CGroupBPFForeignProgram;
typedef enum CGroupDevicePolicy { typedef enum CGroupDevicePolicy {
/* When devices listed, will allow those, plus built-in ones, if none are listed will allow /* When devices listed, will allow those, plus built-in ones, if none are listed will allow
@ -94,6 +95,12 @@ struct CGroupBlockIODeviceBandwidth {
uint64_t wbps; uint64_t wbps;
}; };
struct CGroupBPFForeignProgram {
LIST_FIELDS(CGroupBPFForeignProgram, programs);
uint32_t attach_type;
char *bpffs_path;
};
struct CGroupContext { struct CGroupContext {
bool cpu_accounting; bool cpu_accounting;
bool io_accounting; bool io_accounting;
@ -142,6 +149,7 @@ struct CGroupContext {
char **ip_filters_ingress; char **ip_filters_ingress;
char **ip_filters_egress; char **ip_filters_egress;
LIST_HEAD(CGroupBPFForeignProgram, bpf_foreign_programs);
/* For legacy hierarchies */ /* For legacy hierarchies */
uint64_t cpu_shares; uint64_t cpu_shares;
@ -202,8 +210,10 @@ void cgroup_context_free_io_device_limit(CGroupContext *c, CGroupIODeviceLimit *
void cgroup_context_free_io_device_latency(CGroupContext *c, CGroupIODeviceLatency *l); void cgroup_context_free_io_device_latency(CGroupContext *c, CGroupIODeviceLatency *l);
void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w); void cgroup_context_free_blockio_device_weight(CGroupContext *c, CGroupBlockIODeviceWeight *w);
void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b); void cgroup_context_free_blockio_device_bandwidth(CGroupContext *c, CGroupBlockIODeviceBandwidth *b);
void cgroup_context_remove_bpf_foreign_program(CGroupContext *c, CGroupBPFForeignProgram *p);
int cgroup_add_device_allow(CGroupContext *c, const char *dev, const char *mode); int cgroup_add_device_allow(CGroupContext *c, const char *dev, const char *mode);
int cgroup_add_bpf_foreign_program(CGroupContext *c, uint32_t attach_type, const char *path);
void cgroup_oomd_xattr_apply(Unit *u, const char *cgroup_path); void cgroup_oomd_xattr_apply(Unit *u, const char *cgroup_path);