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@xxxxxxxxxx> >>> --- >>> 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@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list