[Pkg-libvirt-commits] [libvirt] 01/02: Cherry-pick cgroup related fixes from upstream trunk

Guido Guenther agx at alioth.debian.org
Thu Sep 12 14:43:16 UTC 2013


This is an automated email from the git hooks/post-receive script.

agx pushed a commit to annotated tag debian/1.1.2-3
in repository libvirt.

commit d7b6d7a5aedb372e9c3fbf24acf3e1d1db4a15ee
Author: Guido Günther <agx at sigxcpu.org>
Date:   Thu Sep 12 16:12:17 2013 +0200

    Cherry-pick cgroup related fixes from upstream trunk
    
    Namely a48838ad2e36c124229b6faaf6e24284810e3802 and
    f0b6d8d472de3c1bf3ade24e07df7c6d02075b77.
    
    Thanks: Laurent Biognville for chasing this and Daniel P. Berrange for the acutual fixes.
    Closes: #721979
---
 ...ups-when-all-are-mounted-on-sys-fs-cgroup.patch |  207 ++++++++++++++++++
 ...ng-of-VMs-on-when-only-logind-part-of-sys.patch |  230 ++++++++++++++++++++
 debian/patches/series                              |    2 +
 3 files changed, 439 insertions(+)

diff --git a/debian/patches/Fix-cgroups-when-all-are-mounted-on-sys-fs-cgroup.patch b/debian/patches/Fix-cgroups-when-all-are-mounted-on-sys-fs-cgroup.patch
new file mode 100644
index 0000000..4e21155
--- /dev/null
+++ b/debian/patches/Fix-cgroups-when-all-are-mounted-on-sys-fs-cgroup.patch
@@ -0,0 +1,207 @@
+From: "Daniel P. Berrange" <berrange at redhat.com>
+Date: Tue, 10 Sep 2013 14:31:53 +0100
+Subject: Fix cgroups when all are mounted on /sys/fs/cgroup
+
+Some users in Ubuntu/Debian seem to have a setup where all the
+cgroup controllers are mounted on /sys/fs/cgroup rather than
+any /sys/fs/cgroup/<controller> name. In the loop which detects
+which controllers are present for a mount point we were modifying
+'mnt_dir' field in the 'struct mntent' var, but not always restoring
+the original value. This caused detection to break in the all-in-one
+mount setup.
+
+Fix that logic bug and add test case coverage for this mount
+setup.
+
+Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
+---
+ src/util/vircgroup.c  |  3 ++-
+ tests/vircgroupmock.c | 45 ++++++++++++++++++++++++++++++++++++++---
+ tests/vircgrouptest.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 99 insertions(+), 4 deletions(-)
+
+diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
+index 16458a3..a260356 100644
+--- a/src/util/vircgroup.c
++++ b/src/util/vircgroup.c
+@@ -342,10 +342,11 @@ virCgroupDetectMounts(virCgroupPtr group)
+                                        entry.mnt_dir);
+                         goto error;
+                     }
+-                    *tmp2 = '\0';
++
+                     /* If it is a co-mount it has a filename like "cpu,cpuacct"
+                      * and we must identify the symlink path */
+                     if (strchr(tmp2 + 1, ',')) {
++                        *tmp2 = '\0';
+                         if (virAsprintf(&linksrc, "%s/%s",
+                                         entry.mnt_dir, typestr) < 0)
+                             goto error;
+diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c
+index f1a5700..d83496c 100644
+--- a/tests/vircgroupmock.c
++++ b/tests/vircgroupmock.c
+@@ -103,6 +103,27 @@ const char *proccgroups =
+     "blkio   8       4       1\n";
+ 
+ 
++const char *procmountsallinone =
++    "rootfs / rootfs rw 0 0\n"
++    "sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0\n"
++    "proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0\n"
++    "udev /dev devtmpfs rw,relatime,size=16458560k,nr_inodes=4114640,mode=755 0 0\n"
++    "devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0\n"
++    "nfsd /proc/fs/nfsd nfsd rw,relatime 0 0\n"
++    "cgroup /not/really/sys/fs/cgroup cgroup rw,relatime,blkio,devices,memory,cpuacct,cpu,cpuset 0 0\n";
++
++const char *procselfcgroupsallinone =
++    "6:blkio,devices,memory,cpuacct,cpu,cpuset:/";
++
++const char *proccgroupsallinone =
++    "#subsys_name    hierarchy       num_cgroups     enabled\n"
++    "cpuset   6   1  1\n"
++    "cpu      6   1  1\n"
++    "cpuacct  6   1  1\n"
++    "memory   6   1  1\n"
++    "devices  6   1  1\n"
++    "blkio    6   1  1\n";
++
+ static int make_file(const char *path,
+                      const char *name,
+                      const char *value)
+@@ -378,11 +399,21 @@ static void init_sysfs(void)
+ 
+ FILE *fopen(const char *path, const char *mode)
+ {
++    const char *mock;
++    bool allinone = false;
+     init_syms();
+ 
++    mock = getenv("VIR_CGROUP_MOCK_MODE");
++    if (mock && STREQ(mock, "allinone"))
++        allinone = true;
++
+     if (STREQ(path, "/proc/mounts")) {
+         if (STREQ(mode, "r")) {
+-            return fmemopen((void *)procmounts, strlen(procmounts), mode);
++            if (allinone)
++                return fmemopen((void *)procmountsallinone,
++                                strlen(procmountsallinone), mode);
++            else
++                return fmemopen((void *)procmounts, strlen(procmounts), mode);
+         } else {
+             errno = EACCES;
+             return NULL;
+@@ -390,7 +421,11 @@ FILE *fopen(const char *path, const char *mode)
+     }
+     if (STREQ(path, "/proc/cgroups")) {
+         if (STREQ(mode, "r")) {
+-            return fmemopen((void *)proccgroups, strlen(proccgroups), mode);
++            if (allinone)
++                return fmemopen((void *)proccgroupsallinone,
++                                strlen(proccgroupsallinone), mode);
++            else
++                return fmemopen((void *)proccgroups, strlen(proccgroups), mode);
+         } else {
+             errno = EACCES;
+             return NULL;
+@@ -398,7 +433,11 @@ FILE *fopen(const char *path, const char *mode)
+     }
+     if (STREQ(path, "/proc/self/cgroup")) {
+         if (STREQ(mode, "r")) {
+-            return fmemopen((void *)procselfcgroups, strlen(procselfcgroups), mode);
++            if (allinone)
++                return fmemopen((void *)procselfcgroupsallinone,
++                                strlen(procselfcgroupsallinone), mode);
++            else
++                return fmemopen((void *)procselfcgroups, strlen(procselfcgroups), mode);
+         } else {
+             errno = EACCES;
+             return NULL;
+diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
+index 4bdd4c9..f12587c 100644
+--- a/tests/vircgrouptest.c
++++ b/tests/vircgrouptest.c
+@@ -99,6 +99,16 @@ const char *mountsFull[VIR_CGROUP_CONTROLLER_LAST] = {
+     [VIR_CGROUP_CONTROLLER_BLKIO] = "/not/really/sys/fs/cgroup/blkio",
+     [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/not/really/sys/fs/cgroup/systemd",
+ };
++const char *mountsAllInOne[VIR_CGROUP_CONTROLLER_LAST] = {
++    [VIR_CGROUP_CONTROLLER_CPU] = "/not/really/sys/fs/cgroup",
++    [VIR_CGROUP_CONTROLLER_CPUACCT] = "/not/really/sys/fs/cgroup",
++    [VIR_CGROUP_CONTROLLER_CPUSET] = "/not/really/sys/fs/cgroup",
++    [VIR_CGROUP_CONTROLLER_MEMORY] = "/not/really/sys/fs/cgroup",
++    [VIR_CGROUP_CONTROLLER_DEVICES] = "/not/really/sys/fs/cgroup",
++    [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
++    [VIR_CGROUP_CONTROLLER_BLKIO] = "/not/really/sys/fs/cgroup",
++    [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
++};
+ 
+ const char *links[VIR_CGROUP_CONTROLLER_LAST] = {
+     [VIR_CGROUP_CONTROLLER_CPU] = "/not/really/sys/fs/cgroup/cpu",
+@@ -108,6 +118,18 @@ const char *links[VIR_CGROUP_CONTROLLER_LAST] = {
+     [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
+     [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
+     [VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
++    [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
++};
++
++const char *linksAllInOne[VIR_CGROUP_CONTROLLER_LAST] = {
++    [VIR_CGROUP_CONTROLLER_CPU] = NULL,
++    [VIR_CGROUP_CONTROLLER_CPUACCT] = NULL,
++    [VIR_CGROUP_CONTROLLER_CPUSET] = NULL,
++    [VIR_CGROUP_CONTROLLER_MEMORY] = NULL,
++    [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
++    [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
++    [VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
++    [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
+ };
+ 
+ 
+@@ -417,6 +439,34 @@ cleanup:
+     return ret;
+ }
+ 
++static int testCgroupNewForSelfAllInOne(const void *args ATTRIBUTE_UNUSED)
++{
++    virCgroupPtr cgroup = NULL;
++    int ret = -1;
++    const char *placement[VIR_CGROUP_CONTROLLER_LAST] = {
++        [VIR_CGROUP_CONTROLLER_CPU] = "/",
++        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/",
++        [VIR_CGROUP_CONTROLLER_CPUSET] = "/",
++        [VIR_CGROUP_CONTROLLER_MEMORY] = "/",
++        [VIR_CGROUP_CONTROLLER_DEVICES] = "/",
++        [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
++        [VIR_CGROUP_CONTROLLER_BLKIO] = "/",
++    };
++
++    if (virCgroupNewSelf(&cgroup) < 0) {
++        fprintf(stderr, "Cannot create cgroup for self\n");
++        goto cleanup;
++    }
++
++    ret = validateCgroup(cgroup, "", mountsAllInOne, linksAllInOne, placement);
++
++cleanup:
++    virCgroupFree(&cgroup);
++    return ret;
++}
++
++
++
+ # define FAKESYSFSDIRTEMPLATE abs_builddir "/fakesysfsdir-XXXXXX"
+ 
+ static int
+@@ -455,6 +505,11 @@ mymain(void)
+     if (virtTestRun("New cgroup for domain partition escaped", 1, testCgroupNewForPartitionDomainEscaped, NULL) < 0)
+         ret = -1;
+ 
++    setenv("VIR_CGROUP_MOCK_MODE", "allinone", 1);
++    if (virtTestRun("New cgroup for self (allinone)", 1, testCgroupNewForSelfAllInOne, NULL) < 0)
++        ret = -1;
++    unsetenv("VIR_CGROUP_MOCK_MODE");
++
+     if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
+         virFileDeleteTree(fakesysfsdir);
+ 
diff --git a/debian/patches/Fix-launching-of-VMs-on-when-only-logind-part-of-sys.patch b/debian/patches/Fix-launching-of-VMs-on-when-only-logind-part-of-sys.patch
new file mode 100644
index 0000000..b575255
--- /dev/null
+++ b/debian/patches/Fix-launching-of-VMs-on-when-only-logind-part-of-sys.patch
@@ -0,0 +1,230 @@
+From: "Daniel P. Berrange" <berrange at redhat.com>
+Date: Wed, 11 Sep 2013 19:15:52 +0100
+Subject: Fix launching of VMs on when only logind part of systemd is present
+
+Debian systems may run the 'systemd-logind' daemon, which causes the
+/sys/fs/cgroup/systemd  mount to be setup, but no other cgroup
+controllers are created. While the LXC driver considers cgroups to
+be mandatory, the QEMU driver is supposed to accept them as optional.
+
+We detect whether they are present by looking in /proc/mounts for
+any mounts of type 'cgroups', but this is not sufficient. We need to
+skip any named mounts (as seen by a name=XXX string in the mount
+options), so that we only detect actual resource controllers.
+
+http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=721979
+
+Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
+---
+ src/util/vircgroup.c  |  5 +++-
+ tests/vircgroupmock.c | 40 ++++++++++++++++++++++++---
+ tests/vircgrouptest.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 116 insertions(+), 4 deletions(-)
+
+diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
+index a260356..626bbc6 100644
+--- a/src/util/vircgroup.c
++++ b/src/util/vircgroup.c
+@@ -91,7 +91,10 @@ virCgroupAvailable(void)
+         return false;
+ 
+     while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) {
+-        if (STREQ(entry.mnt_type, "cgroup")) {
++        /* We're looking for at least one 'cgroup' fs mount,
++         * which is *not* a named mount. */
++        if (STREQ(entry.mnt_type, "cgroup") &&
++            !strstr(entry.mnt_opts, "name=")) {
+             ret = true;
+             break;
+         }
+diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c
+index d83496c..adc1718 100644
+--- a/tests/vircgroupmock.c
++++ b/tests/vircgroupmock.c
+@@ -124,6 +124,27 @@ const char *proccgroupsallinone =
+     "devices  6   1  1\n"
+     "blkio    6   1  1\n";
+ 
++const char *procmountslogind =
++    "none /not/really/sys/fs/cgroup tmpfs rw,rootcontext=system_u:object_r:sysfs_t:s0,seclabel,relatime,size=4k,mode=755 0 0\n"
++    "systemd /not/really/sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,name=systemd 0 0\n";
++
++const char *procselfcgroupslogind =
++    "1:name=systemd:/\n";
++
++const char *proccgroupslogind =
++    "#subsys_name    hierarchy       num_cgroups     enabled\n"
++    "cpuset    0  1  1\n"
++    "cpu       0  1  1\n"
++    "cpuacct   0  1  1\n"
++    "memory    0  1  0\n"
++    "devices   0  1  1\n"
++    "freezer   0  1  1\n"
++    "net_cls   0  1  1\n"
++    "blkio     0  1  1\n"
++    "perf_event  0  1  1\n";
++
++
++
+ static int make_file(const char *path,
+                      const char *name,
+                      const char *value)
+@@ -400,18 +421,25 @@ static void init_sysfs(void)
+ FILE *fopen(const char *path, const char *mode)
+ {
+     const char *mock;
+-    bool allinone = false;
++    bool allinone = false, logind = false;
+     init_syms();
+ 
+     mock = getenv("VIR_CGROUP_MOCK_MODE");
+-    if (mock && STREQ(mock, "allinone"))
+-        allinone = true;
++    if (mock) {
++        if (STREQ(mock, "allinone"))
++            allinone = true;
++        else if (STREQ(mock, "logind"))
++            logind = true;
++    }
+ 
+     if (STREQ(path, "/proc/mounts")) {
+         if (STREQ(mode, "r")) {
+             if (allinone)
+                 return fmemopen((void *)procmountsallinone,
+                                 strlen(procmountsallinone), mode);
++            else if (logind)
++                return fmemopen((void *)procmountslogind,
++                                strlen(procmountslogind), mode);
+             else
+                 return fmemopen((void *)procmounts, strlen(procmounts), mode);
+         } else {
+@@ -424,6 +452,9 @@ FILE *fopen(const char *path, const char *mode)
+             if (allinone)
+                 return fmemopen((void *)proccgroupsallinone,
+                                 strlen(proccgroupsallinone), mode);
++            else if (logind)
++                return fmemopen((void *)proccgroupslogind,
++                                strlen(proccgroupslogind), mode);
+             else
+                 return fmemopen((void *)proccgroups, strlen(proccgroups), mode);
+         } else {
+@@ -436,6 +467,9 @@ FILE *fopen(const char *path, const char *mode)
+             if (allinone)
+                 return fmemopen((void *)procselfcgroupsallinone,
+                                 strlen(procselfcgroupsallinone), mode);
++            else if (logind)
++                return fmemopen((void *)procselfcgroupslogind,
++                                strlen(procselfcgroupslogind), mode);
+             else
+                 return fmemopen((void *)procselfcgroups, strlen(procselfcgroups), mode);
+         } else {
+diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
+index f12587c..570e061 100644
+--- a/tests/vircgrouptest.c
++++ b/tests/vircgrouptest.c
+@@ -109,6 +109,16 @@ const char *mountsAllInOne[VIR_CGROUP_CONTROLLER_LAST] = {
+     [VIR_CGROUP_CONTROLLER_BLKIO] = "/not/really/sys/fs/cgroup",
+     [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
+ };
++const char *mountsLogind[VIR_CGROUP_CONTROLLER_LAST] = {
++    [VIR_CGROUP_CONTROLLER_CPU] = NULL,
++    [VIR_CGROUP_CONTROLLER_CPUACCT] = NULL,
++    [VIR_CGROUP_CONTROLLER_CPUSET] = NULL,
++    [VIR_CGROUP_CONTROLLER_MEMORY] = NULL,
++    [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
++    [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
++    [VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
++    [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/not/really/sys/fs/cgroup/systemd",
++};
+ 
+ const char *links[VIR_CGROUP_CONTROLLER_LAST] = {
+     [VIR_CGROUP_CONTROLLER_CPU] = "/not/really/sys/fs/cgroup/cpu",
+@@ -132,6 +142,17 @@ const char *linksAllInOne[VIR_CGROUP_CONTROLLER_LAST] = {
+     [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
+ };
+ 
++const char *linksLogind[VIR_CGROUP_CONTROLLER_LAST] = {
++    [VIR_CGROUP_CONTROLLER_CPU] = NULL,
++    [VIR_CGROUP_CONTROLLER_CPUACCT] = NULL,
++    [VIR_CGROUP_CONTROLLER_CPUSET] = NULL,
++    [VIR_CGROUP_CONTROLLER_MEMORY] = NULL,
++    [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
++    [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
++    [VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
++    [VIR_CGROUP_CONTROLLER_SYSTEMD] = NULL,
++};
++
+ 
+ static int testCgroupNewForSelf(const void *args ATTRIBUTE_UNUSED)
+ {
+@@ -466,6 +487,48 @@ cleanup:
+ }
+ 
+ 
++static int testCgroupNewForSelfLogind(const void *args ATTRIBUTE_UNUSED)
++{
++    virCgroupPtr cgroup = NULL;
++    int ret = -1;
++    const char *placement[VIR_CGROUP_CONTROLLER_LAST] = {
++        [VIR_CGROUP_CONTROLLER_CPU] = NULL,
++        [VIR_CGROUP_CONTROLLER_CPUACCT] = NULL,
++        [VIR_CGROUP_CONTROLLER_CPUSET] = NULL,
++        [VIR_CGROUP_CONTROLLER_MEMORY] = NULL,
++        [VIR_CGROUP_CONTROLLER_DEVICES] = NULL,
++        [VIR_CGROUP_CONTROLLER_FREEZER] = NULL,
++        [VIR_CGROUP_CONTROLLER_BLKIO] = NULL,
++        [VIR_CGROUP_CONTROLLER_SYSTEMD] = "/",
++    };
++
++    if (virCgroupNewSelf(&cgroup) < 0) {
++        fprintf(stderr, "Cannot create cgroup for self\n");
++        goto cleanup;
++    }
++
++    ret = validateCgroup(cgroup, "", mountsLogind, linksLogind, placement);
++
++cleanup:
++    virCgroupFree(&cgroup);
++    return ret;
++}
++
++
++static int testCgroupAvailable(const void *args)
++{
++    bool got = virCgroupAvailable();
++    bool want = args == (void*)0x1;
++
++    if (got != want) {
++        fprintf(stderr, "Expected cgroup %savailable, but state was wrong\n",
++                want ? "" : "not ");
++        return -1;
++    }
++
++    return 0;
++}
++
+ 
+ # define FAKESYSFSDIRTEMPLATE abs_builddir "/fakesysfsdir-XXXXXX"
+ 
+@@ -505,9 +568,21 @@ mymain(void)
+     if (virtTestRun("New cgroup for domain partition escaped", 1, testCgroupNewForPartitionDomainEscaped, NULL) < 0)
+         ret = -1;
+ 
++    if (virtTestRun("Cgroup available", 1, testCgroupAvailable, (void*)0x1) < 0)
++        ret = -1;
++
+     setenv("VIR_CGROUP_MOCK_MODE", "allinone", 1);
+     if (virtTestRun("New cgroup for self (allinone)", 1, testCgroupNewForSelfAllInOne, NULL) < 0)
+         ret = -1;
++    if (virtTestRun("Cgroup available", 1, testCgroupAvailable, (void*)0x1) < 0)
++        ret = -1;
++    unsetenv("VIR_CGROUP_MOCK_MODE");
++
++    setenv("VIR_CGROUP_MOCK_MODE", "logind", 1);
++    if (virtTestRun("New cgroup for self (logind)", 1, testCgroupNewForSelfLogind, NULL) < 0)
++        ret = -1;
++    if (virtTestRun("Cgroup available", 1, testCgroupAvailable, (void*)0x0) < 0)
++        ret = -1;
+     unsetenv("VIR_CGROUP_MOCK_MODE");
+ 
+     if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
diff --git a/debian/patches/series b/debian/patches/series
index 328e080..56bb5c8 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -13,3 +13,5 @@ Allow-xen-toolstack-to-find-it-s-binaries.patch
 Fix-make-check-not-finding-finding-the-libvirtd-lens.patch
 Parse-AM_LDFLAGS-to-driver-modules-too.patch
 virFileNBDDeviceAssociate-Avoid-use-of-uninitialized.patch
+Fix-cgroups-when-all-are-mounted-on-sys-fs-cgroup.patch
+Fix-launching-of-VMs-on-when-only-logind-part-of-sys.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-libvirt/libvirt.git



More information about the Pkg-libvirt-commits mailing list