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.
Pavel