提交 ce11a5c5 编写于 作者: P Pavel Hrdina

vircgroup: introduce virCgroupV2DevicesDetectProg

This function will be called if libvirtd was restarted while some
domains were running.  It will try to detect existing programs attached
to the guest cgroup.
Signed-off-by: NPavel Hrdina <phrdina@redhat.com>
Reviewed-by: NJán Tomko <jtomko@redhat.com>
上级 48423a0b
...@@ -1719,6 +1719,7 @@ virCgroupV2Register; ...@@ -1719,6 +1719,7 @@ virCgroupV2Register;
# util/vircgroupv2devices.h # util/vircgroupv2devices.h
virCgroupV2DevicesAttachProg; virCgroupV2DevicesAttachProg;
virCgroupV2DevicesAvailable; virCgroupV2DevicesAvailable;
virCgroupV2DevicesDetectProg;
# util/virclosecallbacks.h # util/virclosecallbacks.h
virCloseCallbacksGet; virCloseCallbacksGet;
......
...@@ -322,6 +322,110 @@ virCgroupV2DevicesAttachProg(virCgroupPtr group, ...@@ -322,6 +322,110 @@ virCgroupV2DevicesAttachProg(virCgroupPtr group,
VIR_FORCE_CLOSE(mapfd); VIR_FORCE_CLOSE(mapfd);
return ret; return ret;
} }
static int
virCgroupV2DevicesCountMapEntries(int mapfd)
{
int ret = 0;
int rc;
uint64_t key = 0;
uint64_t prevKey = 0;
while ((rc = virBPFGetNextElem(mapfd, &prevKey, &key)) == 0) {
ret++;
prevKey = key;
}
if (rc < 0)
return -1;
return ret;
}
# define MAX_PROG_IDS 10
int
virCgroupV2DevicesDetectProg(virCgroupPtr group)
{
g_autofree char *path = NULL;
VIR_AUTOCLOSE cgroupfd = -1;
unsigned int progcnt = 0;
unsigned int progids[MAX_PROG_IDS] = { 0 };
int progfd = -1;
int mapfd = -1;
int nitems = -1;
struct bpf_prog_info progInfo = { 0 };
struct bpf_map_info mapInfo = { 0 };
g_autofree unsigned int *mapIDs = NULL;
if (group->unified.devices.progfd > 0 && group->unified.devices.mapfd > 0)
return 0;
if (virCgroupPathOfController(group, VIR_CGROUP_CONTROLLER_DEVICES,
NULL, &path) < 0) {
return -1;
}
cgroupfd = open(path, O_RDONLY);
if (cgroupfd < 0) {
virReportSystemError(errno, _("unable to open '%s'"), path);
return -1;
}
if (virBPFQueryProg(cgroupfd, MAX_PROG_IDS, BPF_CGROUP_DEVICE,
&progcnt, progids) < 0) {
virReportSystemError(errno, "%s", _("unable to query cgroup BPF progs"));
return -1;
}
if (progcnt == 0)
return 0;
/* No need to have alternate code, this function will not be called
* if compiled with old kernel. */
progfd = virBPFGetProg(progids[0]);
if (progfd < 0) {
virReportSystemError(errno, "%s", _("failed to get cgroup BPF prog FD"));
return -1;
}
if (virBPFGetProgInfo(progfd, &progInfo, &mapIDs) < 0) {
virReportSystemError(errno, "%s", _("failed to get cgroup BPF prog info"));
return -1;
}
if (progInfo.nr_map_ids == 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("no map for cgroup BPF prog"));
return -1;
}
mapfd = virBPFGetMap(mapIDs[0]);
if (mapfd < 0) {
virReportSystemError(errno, "%s", _("failed to get cgroup BPF map FD"));
return -1;
}
if (virBPFGetMapInfo(mapfd, &mapInfo) < 0) {
virReportSystemError(errno, "%s", _("failed to get cgroup BPF map info"));
return -1;
}
nitems = virCgroupV2DevicesCountMapEntries(mapfd);
if (nitems < 0) {
virReportSystemError(errno, "%s", _("failed to count cgroup BPF map items"));
return -1;
}
group->unified.devices.progfd = progfd;
group->unified.devices.mapfd = mapfd;
group->unified.devices.max = mapInfo.max_entries;
group->unified.devices.count = nitems;
return 0;
}
#else /* !HAVE_DECL_BPF_CGROUP_DEVICE */ #else /* !HAVE_DECL_BPF_CGROUP_DEVICE */
bool bool
virCgroupV2DevicesAvailable(virCgroupPtr group G_GNUC_UNUSED) virCgroupV2DevicesAvailable(virCgroupPtr group G_GNUC_UNUSED)
...@@ -340,4 +444,14 @@ virCgroupV2DevicesAttachProg(virCgroupPtr group G_GNUC_UNUSED, ...@@ -340,4 +444,14 @@ virCgroupV2DevicesAttachProg(virCgroupPtr group G_GNUC_UNUSED,
"with this kernel")); "with this kernel"));
return -1; return -1;
} }
int
virCgroupV2DevicesDetectProg(virCgroupPtr group G_GNUC_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
_("cgroups v2 BPF devices not supported "
"with this kernel"));
return -1;
}
#endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */ #endif /* !HAVE_DECL_BPF_CGROUP_DEVICE */
...@@ -27,3 +27,6 @@ int ...@@ -27,3 +27,6 @@ int
virCgroupV2DevicesAttachProg(virCgroupPtr group, virCgroupV2DevicesAttachProg(virCgroupPtr group,
int mapfd, int mapfd,
size_t max); size_t max);
int
virCgroupV2DevicesDetectProg(virCgroupPtr group);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册