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(a)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