vircgroup: workaround devices in hybrid mode

So the issue here is that you can end up with configuration where
you have cgroup v1 and v2 enabled at the same time and the devices
controllers is enabled for cgroup v1.

In cgroup v2 there is no devices controller, the device access is
controlled using BPF and since it is not a cgroup controller both
of them can exists at the same time and both of them are applied while
resolving access to devices.

In order to avoid configuring both BPF and cgroup v1 devices we will
use BPF if possible and otherwise fallback to cgroup v1 devices.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Pavel Hrdina 2019-11-14 11:44:42 +01:00
parent 884479b42b
commit c359cb9aee
4 changed files with 20 additions and 4 deletions

View File

@ -403,7 +403,8 @@ virCgroupDetect(virCgroupPtr group,
for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
if (group->backends[i]) {
int rc = group->backends[i]->detectControllers(group, controllers, parent);
int rc = group->backends[i]->detectControllers(group, controllers, parent,
controllersAvailable);
if (rc < 0)
return -1;
controllersAvailable |= rc;

View File

@ -99,7 +99,8 @@ typedef char *
typedef int
(*virCgroupDetectControllersCB)(virCgroupPtr group,
int controllers,
virCgroupPtr parent);
virCgroupPtr parent,
int detected);
typedef bool
(*virCgroupHasControllerCB)(virCgroupPtr cgroup,

View File

@ -403,7 +403,8 @@ virCgroupV1StealPlacement(virCgroupPtr group)
static int
virCgroupV1DetectControllers(virCgroupPtr group,
int controllers,
virCgroupPtr parent G_GNUC_UNUSED)
virCgroupPtr parent G_GNUC_UNUSED,
int detected)
{
size_t i;
size_t j;
@ -413,6 +414,11 @@ virCgroupV1DetectControllers(virCgroupPtr group,
/* First mark requested but non-existing controllers to be ignored */
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
if (((1 << i) & controllers)) {
int type = 1 << i;
if (type & detected) {
VIR_FREE(group->legacy[i].mountPoint);
VIR_FREE(group->legacy[i].placement);
}
/* Remove non-existent controllers */
if (!group->legacy[i].mountPoint) {
VIR_DEBUG("Requested controller '%s' not mounted, ignoring",
@ -453,6 +459,11 @@ virCgroupV1DetectControllers(virCgroupPtr group,
VIR_DEBUG("Auto-detecting controllers");
controllers = 0;
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
int type = 1 << i;
if (type & detected) {
VIR_FREE(group->legacy[i].mountPoint);
VIR_FREE(group->legacy[i].placement);
}
VIR_DEBUG("Controller '%s' present=%s",
virCgroupV1ControllerTypeToString(i),
group->legacy[i].mountPoint ? "yes" : "no");

View File

@ -292,7 +292,8 @@ virCgroupV2ParseControllersFile(virCgroupPtr group,
static int
virCgroupV2DetectControllers(virCgroupPtr group,
int controllers,
virCgroupPtr parent)
virCgroupPtr parent,
int detected)
{
size_t i;
@ -309,6 +310,8 @@ virCgroupV2DetectControllers(virCgroupPtr group,
if (controllers >= 0)
group->unified.controllers &= controllers;
group->unified.controllers &= ~detected;
for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++)
VIR_DEBUG("Controller '%s' present=%s",
virCgroupV2ControllerTypeToString(i),