[libvirt] [PATCH v2 02/53] vircgroup: introduce virCgroupV2Available

Pavel Hrdina posted 53 patches 6 years, 7 months ago
[libvirt] [PATCH v2 02/53] vircgroup: introduce virCgroupV2Available
Posted by Pavel Hrdina 6 years, 7 months ago
We cannot detect only mount points to figure out whether cgroup v2
is available because systemd uses cgroup v2 for process tracking and
all controllers are mounted as cgroup v1 controllers.

To make sure that this is no the situation we need to check
'cgroup.controllers' file if it's not empty to make sure that cgroup
v2 is not mounted only for process tracking.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
 src/util/vircgroupv2.c | 59 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
index 23bf81dae2..83944602d6 100644
--- a/src/util/vircgroupv2.c
+++ b/src/util/vircgroupv2.c
@@ -19,6 +19,10 @@
  */
 #include <config.h>
 
+#ifdef __linux__
+# include <mntent.h>
+#endif /* __linux__ */
+
 #include "internal.h"
 
 #define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
@@ -28,7 +32,9 @@
 #include "vircgroup.h"
 #include "vircgroupbackend.h"
 #include "vircgroupv2.h"
+#include "virfile.h"
 #include "virlog.h"
+#include "virstring.h"
 
 VIR_LOG_INIT("util.cgroup");
 
@@ -41,8 +47,61 @@ VIR_ENUM_IMPL(virCgroupV2Controller, VIR_CGROUP_CONTROLLER_LAST,
 
 #ifdef __linux__
 
+/* We're looking for one 'cgroup2' fs mount which has some
+ * controllers enabled. */
+static bool
+virCgroupV2Available(void)
+{
+    bool ret = false;
+    FILE *mounts = NULL;
+    struct mntent entry;
+    char buf[CGROUP_MAX_VAL];
+
+    if (!(mounts = fopen("/proc/mounts", "r")))
+        return false;
+
+    while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) {
+        if (STREQ(entry.mnt_type, "cgroup2")) {
+            ret = true;
+            break;
+        }
+    }
+
+    /* Systemd uses cgroup v2 for process tracking but no controller is
+     * available. We should consider this configuration as cgroup v2 is
+     * not available. */
+    if (ret) {
+        int rc;
+        VIR_AUTOFREE(char *) contFile = NULL;
+        VIR_AUTOFREE(char *) contStr = NULL;
+
+        if (virAsprintf(&contFile, "%s/cgroup.controllers", entry.mnt_dir) < 0) {
+            ret = false;
+            goto cleanup;
+        }
+
+        rc = virFileReadAll(contFile, 1024 * 1024, &contStr);
+        if (rc < 0) {
+            ret = false;
+            goto cleanup;
+        }
+
+        if (STREQ(contStr, "")) {
+            ret = false;
+            goto cleanup;
+        }
+    }
+
+ cleanup:
+    VIR_FORCE_FCLOSE(mounts);
+    return ret;
+}
+
+
 virCgroupBackend virCgroupV2Backend = {
     .type = VIR_CGROUP_BACKEND_TYPE_V2,
+
+    .available = virCgroupV2Available,
 };
 
 
-- 
2.17.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 02/53] vircgroup: introduce virCgroupV2Available
Posted by Michal Privoznik 6 years, 7 months ago
On 10/05/2018 02:43 PM, Pavel Hrdina wrote:
> We cannot detect only mount points to figure out whether cgroup v2
> is available because systemd uses cgroup v2 for process tracking and
> all controllers are mounted as cgroup v1 controllers.
> 
> To make sure that this is no the situation we need to check
> 'cgroup.controllers' file if it's not empty to make sure that cgroup
> v2 is not mounted only for process tracking.
> 
> Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
> ---
>  src/util/vircgroupv2.c | 59 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
> index 23bf81dae2..83944602d6 100644
> --- a/src/util/vircgroupv2.c
> +++ b/src/util/vircgroupv2.c
> @@ -19,6 +19,10 @@
>   */
>  #include <config.h>
>  
> +#ifdef __linux__
> +# include <mntent.h>
> +#endif /* __linux__ */
> +
>  #include "internal.h"
>  
>  #define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
> @@ -28,7 +32,9 @@
>  #include "vircgroup.h"
>  #include "vircgroupbackend.h"
>  #include "vircgroupv2.h"
> +#include "virfile.h"
>  #include "virlog.h"
> +#include "virstring.h"
>  
>  VIR_LOG_INIT("util.cgroup");
>  
> @@ -41,8 +47,61 @@ VIR_ENUM_IMPL(virCgroupV2Controller, VIR_CGROUP_CONTROLLER_LAST,
>  
>  #ifdef __linux__


How about:

static bool
virCgroupV2Available(void)
{
    bool ret = false;
    FILE *mounts = NULL;
    struct mntent entry;
    char buf[CGROUP_MAX_VAL];

    if (!(mounts = fopen("/proc/mounts", "r")))
        return false;

    while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) {
        VIR_AUTOFREE(char *) contFile = NULL;
        VIR_AUTOFREE(char *) contStr = NULL;

        if (STRNEQ(entry.mnt_type, "cgroup2"))
            continue;

        /* Systemd uses cgroup v2 for process tracking but no controller is
         * available. We should consider this configuration as cgroup v2 is
         * not available. */
        if (virAsprintf(&contFile, "%s/cgroup.controllers", entry.mnt_dir) < 0)
            goto cleanup;

        if (virFileReadAll(contFile, 1024 * 1024, &contStr) < 0)
            goto cleanup;

        if (STREQ(contStr, ""))
            continue;

        ret = true;
        break;
    }

 cleanup:
    VIR_FORCE_FCLOSE(mounts);
    return ret;
}


Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 02/53] vircgroup: introduce virCgroupV2Available
Posted by Pavel Hrdina 6 years, 7 months ago
On Fri, Oct 05, 2018 at 03:43:50PM +0200, Michal Privoznik wrote:
> On 10/05/2018 02:43 PM, Pavel Hrdina wrote:
> > We cannot detect only mount points to figure out whether cgroup v2
> > is available because systemd uses cgroup v2 for process tracking and
> > all controllers are mounted as cgroup v1 controllers.
> > 
> > To make sure that this is no the situation we need to check
> > 'cgroup.controllers' file if it's not empty to make sure that cgroup
> > v2 is not mounted only for process tracking.
> > 
> > Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
> > ---
> >  src/util/vircgroupv2.c | 59 ++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 59 insertions(+)
> > 
> > diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
> > index 23bf81dae2..83944602d6 100644
> > --- a/src/util/vircgroupv2.c
> > +++ b/src/util/vircgroupv2.c
> > @@ -19,6 +19,10 @@
> >   */
> >  #include <config.h>
> >  
> > +#ifdef __linux__
> > +# include <mntent.h>
> > +#endif /* __linux__ */
> > +
> >  #include "internal.h"
> >  
> >  #define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
> > @@ -28,7 +32,9 @@
> >  #include "vircgroup.h"
> >  #include "vircgroupbackend.h"
> >  #include "vircgroupv2.h"
> > +#include "virfile.h"
> >  #include "virlog.h"
> > +#include "virstring.h"
> >  
> >  VIR_LOG_INIT("util.cgroup");
> >  
> > @@ -41,8 +47,61 @@ VIR_ENUM_IMPL(virCgroupV2Controller, VIR_CGROUP_CONTROLLER_LAST,
> >  
> >  #ifdef __linux__
> 
> 
> How about:
> 
> static bool
> virCgroupV2Available(void)
> {
>     bool ret = false;
>     FILE *mounts = NULL;
>     struct mntent entry;
>     char buf[CGROUP_MAX_VAL];
> 
>     if (!(mounts = fopen("/proc/mounts", "r")))
>         return false;
> 
>     while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) {
>         VIR_AUTOFREE(char *) contFile = NULL;
>         VIR_AUTOFREE(char *) contStr = NULL;
> 
>         if (STRNEQ(entry.mnt_type, "cgroup2"))
>             continue;
> 
>         /* Systemd uses cgroup v2 for process tracking but no controller is
>          * available. We should consider this configuration as cgroup v2 is
>          * not available. */
>         if (virAsprintf(&contFile, "%s/cgroup.controllers", entry.mnt_dir) < 0)
>             goto cleanup;
> 
>         if (virFileReadAll(contFile, 1024 * 1024, &contStr) < 0)
>             goto cleanup;
> 
>         if (STREQ(contStr, ""))
>             continue;
> 
>         ret = true;
>         break;
>     }
> 
>  cleanup:
>     VIR_FORCE_FCLOSE(mounts);
>     return ret;
> }

Works for me :) I was considering moving it inside the while loop but
I was too lazy to do it.

Pavel
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 02/53] vircgroup: introduce virCgroupV2Available
Posted by Michal Privoznik 6 years, 7 months ago
On 10/05/2018 03:48 PM, Pavel Hrdina wrote:
> On Fri, Oct 05, 2018 at 03:43:50PM +0200, Michal Privoznik wrote:
>> On 10/05/2018 02:43 PM, Pavel Hrdina wrote:
>>> We cannot detect only mount points to figure out whether cgroup v2
>>> is available because systemd uses cgroup v2 for process tracking and
>>> all controllers are mounted as cgroup v1 controllers.
>>>
>>> To make sure that this is no the situation we need to check
>>> 'cgroup.controllers' file if it's not empty to make sure that cgroup
>>> v2 is not mounted only for process tracking.
>>>
>>> Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
>>> ---
>>>  src/util/vircgroupv2.c | 59 ++++++++++++++++++++++++++++++++++++++++++
>>>  1 file changed, 59 insertions(+)
>>>
>>> diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
>>> index 23bf81dae2..83944602d6 100644
>>> --- a/src/util/vircgroupv2.c
>>> +++ b/src/util/vircgroupv2.c
>>> @@ -19,6 +19,10 @@
>>>   */
>>>  #include <config.h>
>>>  
>>> +#ifdef __linux__
>>> +# include <mntent.h>
>>> +#endif /* __linux__ */
>>> +
>>>  #include "internal.h"
>>>  
>>>  #define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
>>> @@ -28,7 +32,9 @@
>>>  #include "vircgroup.h"
>>>  #include "vircgroupbackend.h"
>>>  #include "vircgroupv2.h"
>>> +#include "virfile.h"
>>>  #include "virlog.h"
>>> +#include "virstring.h"
>>>  
>>>  VIR_LOG_INIT("util.cgroup");
>>>  
>>> @@ -41,8 +47,61 @@ VIR_ENUM_IMPL(virCgroupV2Controller, VIR_CGROUP_CONTROLLER_LAST,
>>>  
>>>  #ifdef __linux__
>>
>>
>> How about:
>>
>> static bool
>> virCgroupV2Available(void)
>> {
>>     bool ret = false;
>>     FILE *mounts = NULL;
>>     struct mntent entry;
>>     char buf[CGROUP_MAX_VAL];
>>
>>     if (!(mounts = fopen("/proc/mounts", "r")))
>>         return false;
>>
>>     while (getmntent_r(mounts, &entry, buf, sizeof(buf)) != NULL) {
>>         VIR_AUTOFREE(char *) contFile = NULL;
>>         VIR_AUTOFREE(char *) contStr = NULL;
>>
>>         if (STRNEQ(entry.mnt_type, "cgroup2"))
>>             continue;
>>
>>         /* Systemd uses cgroup v2 for process tracking but no controller is
>>          * available. We should consider this configuration as cgroup v2 is
>>          * not available. */
>>         if (virAsprintf(&contFile, "%s/cgroup.controllers", entry.mnt_dir) < 0)
>>             goto cleanup;
>>
>>         if (virFileReadAll(contFile, 1024 * 1024, &contStr) < 0)
>>             goto cleanup;
>>
>>         if (STREQ(contStr, ""))
>>             continue;
>>
>>         ret = true;
>>         break;
>>     }
>>
>>  cleanup:
>>     VIR_FORCE_FCLOSE(mounts);
>>     return ret;
>> }
> 
> Works for me :) I was considering moving it inside the while loop but
> I was too lazy to do it.

ACK then. Although it feels a bit weird to ACK my own code O:-)

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list