This function loads the BPF prog with prepared map into kernel and
attaches it into guest cgroup. It can be also used to replace existing
program in the cgroup if we need to resize BPF map to store more rules
for devices. The old program will be closed and removed from kernel.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/util/vircgrouppriv.h | 10 ++++++++
src/util/vircgroupv2.c | 52 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+)
diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h
index a6fb3bb9f8..085fea375c 100644
--- a/src/util/vircgrouppriv.h
+++ b/src/util/vircgrouppriv.h
@@ -42,10 +42,20 @@ struct _virCgroupV1Controller {
typedef struct _virCgroupV1Controller virCgroupV1Controller;
typedef virCgroupV1Controller *virCgroupV1ControllerPtr;
+struct _virCgroupV2Devices {
+ int mapfd;
+ int progfd;
+ ssize_t count;
+ ssize_t max;
+};
+typedef struct _virCgroupV2Devices virCgroupV2Devices;
+typedef virCgroupV2Devices *virCgroupV2DevicesPtr;
+
struct _virCgroupV2Controller {
int controllers;
char *mountPoint;
char *placement;
+ virCgroupV2Devices devices;
};
typedef struct _virCgroupV2Controller virCgroupV2Controller;
typedef virCgroupV2Controller *virCgroupV2ControllerPtr;
diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
index 63e3123cd9..7a8cc040eb 100644
--- a/src/util/vircgroupv2.c
+++ b/src/util/vircgroupv2.c
@@ -1671,6 +1671,58 @@ virCgroupV2DeviceLoadProg(int mapfd)
}
+static int
+virCgroupV2DeviceAttachProg(virCgroupPtr group,
+ int mapfd,
+ size_t max)
+{
+ int ret = -1;
+ int progfd = -1;
+ int cgroupfd = -1;
+ VIR_AUTOFREE(char *) path = NULL;
+
+ if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_DEVICES,
+ NULL, &path) < 0) {
+ goto cleanup;
+ }
+
+ progfd = virCgroupV2DeviceLoadProg(mapfd);
+ if (progfd < 0) {
+ virReportSystemError(errno, "%s", _("failed to load cgroup BPF
prog"));
+ goto cleanup;
+ }
+
+ cgroupfd = open(path, O_RDONLY);
+ if (cgroupfd < 0) {
+ virReportSystemError(errno, _("unable to open '%s'"), path);
+ goto cleanup;
+ }
+
+ if (virBPFAttachProg(progfd, cgroupfd, BPF_CGROUP_DEVICE) < 0) {
+ virReportSystemError(errno, "%s", _("failed to attach cgroup BPF
prog"));
+ goto cleanup;
+ }
+
+ if (group->unified.devices.progfd > 0) {
+ VIR_DEBUG("Closing existing program that was replaced by new one.");
+ VIR_FORCE_CLOSE(group->unified.devices.progfd);
+ }
+
+ group->unified.devices.progfd = progfd;
+ group->unified.devices.mapfd = mapfd;
+ group->unified.devices.max = max;
+ progfd = -1;
+ mapfd = -1;
+
+ ret = 0;
+ cleanup:
+ VIR_FORCE_CLOSE(cgroupfd);
+ VIR_FORCE_CLOSE(progfd);
+ VIR_FORCE_CLOSE(mapfd);
+ return ret;
+}
+
+
virCgroupBackend virCgroupV2Backend = {
.type = VIR_CGROUP_BACKEND_TYPE_V2,
--
2.20.1