vircgroupv2devices: refactor virCgroupV2DevicesRemoveProg

When running on systemd host the cgroup itself is removed by machined
so when we reach this code the directory no longer exist. If libvirtd
was running the whole time between starting and destroying VM the
detection is skipped because we still have both FD in memory. But if
libvirtd was restarted and no operation requiring cgroup devices
executed the FDs would be 0 and libvirt would try to detect them using
the cgroup directory. This results in reporting following errors:

    libvirtd[955]: unable to open '/sys/fs/cgroup/machine.slice/machine-qemu\x2d1\x2dguest.scope/': No such file or directory
    libvirtd[955]: Failed to remove cgroup for guest

When running on non-systemd host where we handle cgroups manually this
would not happen.

When destroying VM it is not necessary to detect the BPF prog and map
because the following code only closes the FDs without doing anything
else. We could run code that would try to detach the BPF prog from the
cgroup but that is not necessary as well. If the cgroup is removed and
there is no other FD open to the prog kernel will cleanup the prog and
map eventually.

Reported-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Tested-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Pavel Hrdina 2021-04-14 12:01:23 +02:00
parent 6960a895ab
commit 07497fc6da
4 changed files with 7 additions and 13 deletions

View File

@ -1963,12 +1963,12 @@ virCgroupV2Register;
# util/vircgroupv2devices.h # util/vircgroupv2devices.h
virCgroupV2DevicesAvailable; virCgroupV2DevicesAvailable;
virCgroupV2DevicesCloseProg;
virCgroupV2DevicesCreateProg; virCgroupV2DevicesCreateProg;
virCgroupV2DevicesDetectProg; virCgroupV2DevicesDetectProg;
virCgroupV2DevicesGetKey; virCgroupV2DevicesGetKey;
virCgroupV2DevicesGetPerms; virCgroupV2DevicesGetPerms;
virCgroupV2DevicesPrepareProg; virCgroupV2DevicesPrepareProg;
virCgroupV2DevicesRemoveProg;
# util/vircommand.h # util/vircommand.h
virCommandAbort; virCommandAbort;

View File

@ -535,7 +535,7 @@ virCgroupV2Remove(virCgroup *group)
if (virCgroupV2PathOfController(group, controller, "", &grppath) < 0) if (virCgroupV2PathOfController(group, controller, "", &grppath) < 0)
return 0; return 0;
if (virCgroupV2DevicesRemoveProg(parent) < 0) if (virCgroupV2DevicesCloseProg(parent) < 0)
return -1; return -1;
return virCgroupRemoveRecursively(grppath); return virCgroupRemoveRecursively(grppath);

View File

@ -548,18 +548,12 @@ virCgroupV2DevicesPrepareProg(virCgroup *group)
int int
virCgroupV2DevicesRemoveProg(virCgroup *group) virCgroupV2DevicesCloseProg(virCgroup *group)
{ {
if (virCgroupV2DevicesDetectProg(group) < 0) if (group->unified.devices.mapfd > 0)
return -1;
if (group->unified.devices.progfd <= 0 && group->unified.devices.mapfd <= 0)
return 0;
if (group->unified.devices.mapfd >= 0)
VIR_FORCE_CLOSE(group->unified.devices.mapfd); VIR_FORCE_CLOSE(group->unified.devices.mapfd);
if (group->unified.devices.progfd >= 0) if (group->unified.devices.progfd > 0)
VIR_FORCE_CLOSE(group->unified.devices.progfd); VIR_FORCE_CLOSE(group->unified.devices.progfd);
return 0; return 0;
@ -629,7 +623,7 @@ virCgroupV2DevicesPrepareProg(virCgroup *group G_GNUC_UNUSED)
int int
virCgroupV2DevicesRemoveProg(virCgroup *group G_GNUC_UNUSED) virCgroupV2DevicesCloseProg(virCgroup *group G_GNUC_UNUSED)
{ {
return 0; return 0;
} }

View File

@ -38,7 +38,7 @@ int
virCgroupV2DevicesPrepareProg(virCgroup *group); virCgroupV2DevicesPrepareProg(virCgroup *group);
int int
virCgroupV2DevicesRemoveProg(virCgroup *group); virCgroupV2DevicesCloseProg(virCgroup *group);
uint32_t uint32_t
virCgroupV2DevicesGetPerms(int perms, virCgroupV2DevicesGetPerms(int perms,