[libvirt] [PATCH 04/19] vircgroup: introduce virCgroupV2DeviceAttachProg

Pavel Hrdina phrdina at redhat.com
Wed Jan 2 14:08:36 UTC 2019


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 at 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




More information about the libvir-list mailing list