mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-06 22:35:46 +00:00
034ef217d7
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>
114 lines
2.8 KiB
C
114 lines
2.8 KiB
C
/*
|
|
* vircgroupv2.c: methods for cgroups v2 backend
|
|
*
|
|
* Copyright (C) 2018 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include <config.h>
|
|
|
|
#ifdef __linux__
|
|
# include <mntent.h>
|
|
#endif /* __linux__ */
|
|
|
|
#include "internal.h"
|
|
|
|
#define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
|
|
#include "vircgrouppriv.h"
|
|
#undef __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
|
|
|
|
#include "vircgroup.h"
|
|
#include "vircgroupbackend.h"
|
|
#include "vircgroupv2.h"
|
|
#include "virfile.h"
|
|
#include "virlog.h"
|
|
#include "virstring.h"
|
|
|
|
VIR_LOG_INIT("util.cgroup");
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_CGROUP
|
|
|
|
VIR_ENUM_DECL(virCgroupV2Controller);
|
|
VIR_ENUM_IMPL(virCgroupV2Controller, VIR_CGROUP_CONTROLLER_LAST,
|
|
"cpu", "cpuacct", "cpuset", "memory", "devices",
|
|
"freezer", "io", "net_cls", "perf_event", "name=systemd");
|
|
|
|
#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) {
|
|
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;
|
|
}
|
|
|
|
|
|
virCgroupBackend virCgroupV2Backend = {
|
|
.type = VIR_CGROUP_BACKEND_TYPE_V2,
|
|
|
|
.available = virCgroupV2Available,
|
|
};
|
|
|
|
|
|
void
|
|
virCgroupV2Register(void)
|
|
{
|
|
virCgroupBackendRegister(&virCgroupV2Backend);
|
|
}
|
|
|
|
#else /* !__linux__ */
|
|
|
|
void
|
|
virCgroupV2Register(void)
|
|
{
|
|
VIR_INFO("Control groups not supported on this platform");
|
|
}
|
|
|
|
#endif /* !__linux__ */
|