397dc2
From 9cf56b5a0d1394fef10afdd763dc8005457bbaf5 Mon Sep 17 00:00:00 2001
397dc2
Message-Id: <9cf56b5a0d1394fef10afdd763dc8005457bbaf5@dist-git>
397dc2
From: Pavel Hrdina <phrdina@redhat.com>
397dc2
Date: Fri, 19 Feb 2021 13:33:51 +0100
397dc2
Subject: [PATCH] vircgroupv2: properly detect placement of running VM
397dc2
MIME-Version: 1.0
397dc2
Content-Type: text/plain; charset=UTF-8
397dc2
Content-Transfer-Encoding: 8bit
397dc2
397dc2
When libvirtd starts a VM it internally stores a path to the main
397dc2
cgroup. When we restart libvirtd we should get to the same state.
397dc2
397dc2
When we start a VM on host with systemd the cgroup is created for us and
397dc2
the process is already placed into that cgroup and we detect the path
397dc2
created by systemd using /proc/$PID/cgroup. After that we create
397dc2
sub-cgroups and move all threads there.
397dc2
397dc2
Once libvirtd is restarted we again detect the cgroup path using
397dc2
/proc/$PID/cgroup, but in this case we will get a different path because
397dc2
the main thread was moved to a "emulator" cgroup.
397dc2
397dc2
Instead of ignoring the "emulator" directory when validating cgroups
397dc2
remove it completely when detecting cgroup otherwise cgroups will not
397dc2
work properly when libvirtd is restarted.
397dc2
397dc2
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
397dc2
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
397dc2
(cherry picked from commit 902c6644a8ec292789d561b3188e576c37a86872)
397dc2
397dc2
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
397dc2
397dc2
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
397dc2
Message-Id: <10fb6b61cbb4f9caf8e8ba7706ec01d1da41fc67.1613737828.git.phrdina@redhat.com>
397dc2
Reviewed-by: Ján Tomko <jtomko@redhat.com>
397dc2
---
397dc2
 src/util/vircgroupv2.c | 17 ++++++++++-------
397dc2
 1 file changed, 10 insertions(+), 7 deletions(-)
397dc2
397dc2
diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
397dc2
index 92ae3ec839..4682a6a920 100644
397dc2
--- a/src/util/vircgroupv2.c
397dc2
+++ b/src/util/vircgroupv2.c
397dc2
@@ -121,12 +121,6 @@ virCgroupV2ValidateMachineGroup(virCgroupPtr group,
397dc2
     if (!(tmp = strrchr(group->unified.placement, '/')))
397dc2
         return false;
397dc2
 
397dc2
-    if (STREQ(tmp, "/emulator")) {
397dc2
-        *tmp = '\0';
397dc2
-
397dc2
-        if (!(tmp = strrchr(group->unified.placement, '/')))
397dc2
-            return false;
397dc2
-    }
397dc2
     tmp++;
397dc2
 
397dc2
     if (STRNEQ(tmp, partmachinename) &&
397dc2
@@ -197,6 +191,9 @@ virCgroupV2DetectPlacement(virCgroupPtr group,
397dc2
                            const char *controllers,
397dc2
                            const char *selfpath)
397dc2
 {
397dc2
+    g_autofree char *placement = g_strdup(selfpath);
397dc2
+    char *tmp = NULL;
397dc2
+
397dc2
     if (group->unified.placement)
397dc2
         return 0;
397dc2
 
397dc2
@@ -207,12 +204,18 @@ virCgroupV2DetectPlacement(virCgroupPtr group,
397dc2
     if (STRNEQ(controllers, ""))
397dc2
         return 0;
397dc2
 
397dc2
+    /* Running VM will have the main thread placed in emulator cgroup
397dc2
+     * but we need to get the main cgroup. */
397dc2
+    tmp = g_strrstr(placement, "/emulator");
397dc2
+    if (tmp)
397dc2
+        *tmp = '\0';
397dc2
+
397dc2
     /*
397dc2
      * selfpath == "/" + path="" -> "/"
397dc2
      * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service"
397dc2
      * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo"
397dc2
      */
397dc2
-    group->unified.placement = g_strdup_printf("%s%s%s", selfpath,
397dc2
+    group->unified.placement = g_strdup_printf("%s%s%s", placement,
397dc2
                                                (STREQ(selfpath, "/") || STREQ(path, "") ? "" : "/"), path);
397dc2
 
397dc2
     return 0;
397dc2
-- 
397dc2
2.30.0
397dc2