summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2015-10-07 17:36:37 +0100
committerDaniel P. Berrange <berrange@redhat.com>2015-10-12 13:15:00 +0100
commit9bf595b1724671332f4e0195ca96a88c1a5dba73 (patch)
tree50e091cf00c7f0cb6b996386651b2b1ebe0881a2
parentfd6d506c50d9c885fd500627bddefe2f93ded0c2 (diff)
downloadlibvirt-9bf595b1724671332f4e0195ca96a88c1a5dba73.tar.gz
virt-host-validate: check for required cgroups
Extend the virt-host-validate checks to see if the required cgroups are compiled into the kernel and that they are mounted on the system. The cgroups are all optional except for 3 that LXC mandates Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-rw-r--r--tools/virt-host-validate-common.c131
-rw-r--r--tools/virt-host-validate-common.h8
-rw-r--r--tools/virt-host-validate-lxc.c30
-rw-r--r--tools/virt-host-validate-qemu.c30
4 files changed, 189 insertions, 10 deletions
diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c
index d646a79ec1..a88fc56963 100644
--- a/tools/virt-host-validate-common.c
+++ b/tools/virt-host-validate-common.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <unistd.h>
#include <sys/utsname.h>
+#include <mntent.h>
#include "virutil.h"
#include "viralloc.h"
@@ -104,14 +105,29 @@ static const char *failEscapeCodes[] = {
verify(ARRAY_CARDINALITY(failEscapeCodes) == VIR_HOST_VALIDATE_LAST);
void virHostMsgFail(virHostValidateLevel level,
- const char *hint)
+ const char *format,
+ ...)
{
+ va_list args;
+ char *msg;
+
+ if (quiet)
+ return;
+
+ va_start(args, format);
+ if (virVasprintf(&msg, format, args) < 0) {
+ perror("malloc");
+ abort();
+ }
+ va_end(args);
+
if (virHostMsgWantEscape())
fprintf(stdout, "%s%s\033[0m (%s)\n",
- failEscapeCodes[level], _(failMessages[level]), hint);
+ failEscapeCodes[level], _(failMessages[level]), msg);
else
fprintf(stdout, "%s (%s)\n",
- _(failMessages[level]), hint);
+ _(failMessages[level]), msg);
+ VIR_FREE(msg);
}
@@ -123,7 +139,7 @@ int virHostValidateDeviceExists(const char *hvname,
virHostMsgCheck(hvname, "if device %s exists", dev_name);
if (access(dev_name, F_OK) < 0) {
- virHostMsgFail(level, hint);
+ virHostMsgFail(level, "%s", hint);
return -1;
}
@@ -140,7 +156,7 @@ int virHostValidateDeviceAccessible(const char *hvname,
virHostMsgCheck(hvname, "if device %s is accessible", dev_name);
if (access(dev_name, R_OK|W_OK) < 0) {
- virHostMsgFail(level, hint);
+ virHostMsgFail(level, "%s", hint);
return -1;
}
@@ -160,7 +176,7 @@ int virHostValidateNamespace(const char *hvname,
snprintf(nspath, sizeof(nspath), "/proc/self/ns/%s", ns_name);
if (access(nspath, F_OK) < 0) {
- virHostMsgFail(level, hint);
+ virHostMsgFail(level, "%s", hint);
return -1;
}
@@ -211,20 +227,117 @@ int virHostValidateLinuxKernel(const char *hvname,
(version & 0xff));
if (STRNEQ(uts.sysname, "Linux")) {
- virHostMsgFail(level, hint);
+ virHostMsgFail(level, "%s", hint);
return -1;
}
if (virParseVersionString(uts.release, &thisversion, true) < 0) {
- virHostMsgFail(level, hint);
+ virHostMsgFail(level, "%s", hint);
return -1;
}
if (thisversion < version) {
- virHostMsgFail(level, hint);
+ virHostMsgFail(level, "%s", hint);
return -1;
} else {
virHostMsgPass();
return 0;
}
}
+
+
+static int virHostValidateCGroupSupport(const char *hvname,
+ const char *cg_name,
+ virHostValidateLevel level,
+ const char *config_name)
+{
+ virHostMsgCheck(hvname, "for cgroup '%s' controller support", cg_name);
+ FILE *fp = fopen("/proc/self/cgroup", "r");
+ size_t len = 0;
+ char *line = NULL;
+ ssize_t ret;
+ bool matched = false;
+
+ if (!fp)
+ goto error;
+
+ while ((ret = getline(&line, &len, fp)) >= 0 && !matched) {
+ char *tmp = strstr(line, cg_name);
+ if (!tmp)
+ continue;
+
+ tmp += strlen(cg_name);
+ if (*tmp != ',' &&
+ *tmp != ':')
+ continue;
+
+ matched = true;
+ }
+ VIR_FREE(line);
+ VIR_FORCE_FCLOSE(fp);
+ if (!matched)
+ goto error;
+
+ virHostMsgPass();
+ return 0;
+
+ error:
+ VIR_FREE(line);
+ virHostMsgFail(level, "Enable CONFIG_%s in kernel Kconfig file", config_name);
+ return -1;
+}
+
+static int virHostValidateCGroupMount(const char *hvname,
+ const char *cg_name,
+ virHostValidateLevel level)
+{
+ virHostMsgCheck(hvname, "for cgroup '%s' controller mount-point", cg_name);
+ FILE *fp = setmntent("/proc/mounts", "r");
+ struct mntent ent;
+ char mntbuf[1024];
+ bool matched = false;
+
+ if (!fp)
+ goto error;
+
+ while (getmntent_r(fp, &ent, mntbuf, sizeof(mntbuf)) && !matched) {
+ char *tmp = strstr(ent.mnt_opts, cg_name);
+ if (!tmp)
+ continue;
+
+ tmp += strlen(cg_name);
+ if (*tmp != ',' &&
+ *tmp != '\0')
+ continue;
+
+ matched = true;
+ }
+ endmntent(fp);
+ if (!matched)
+ goto error;
+
+ virHostMsgPass();
+ return 0;
+
+ error:
+ virHostMsgFail(level, "Mount '%s' cgroup controller (suggested at /sys/fs/cgroup/%s)",
+ cg_name, cg_name);
+ return -1;
+}
+
+int virHostValidateCGroupController(const char *hvname,
+ const char *cg_name,
+ virHostValidateLevel level,
+ const char *config_name)
+{
+ if (virHostValidateCGroupSupport(hvname,
+ cg_name,
+ level,
+ config_name) < 0)
+ return -1;
+ if (virHostValidateCGroupMount(hvname,
+ cg_name,
+ level) < 0)
+ return -1;
+ return 0;
+}
diff --git a/tools/virt-host-validate-common.h b/tools/virt-host-validate-common.h
index c25e69ca60..1547e22897 100644
--- a/tools/virt-host-validate-common.h
+++ b/tools/virt-host-validate-common.h
@@ -40,7 +40,8 @@ extern void virHostMsgCheck(const char *prefix,
extern void virHostMsgPass(void);
extern void virHostMsgFail(virHostValidateLevel level,
- const char *hint);
+ const char *format,
+ ...) ATTRIBUTE_FMT_PRINTF(2, 3);
extern int virHostValidateDeviceExists(const char *hvname,
const char *dev_name,
@@ -64,4 +65,9 @@ extern int virHostValidateNamespace(const char *hvname,
virHostValidateLevel level,
const char *hint);
+extern int virHostValidateCGroupController(const char *hvname,
+ const char *cg_name,
+ virHostValidateLevel level,
+ const char *config_name);
+
#endif /* __VIRT_HOST_VALIDATE_COMMON_H__ */
diff --git a/tools/virt-host-validate-lxc.c b/tools/virt-host-validate-lxc.c
index 43c3f5f08e..48323da3b5 100644
--- a/tools/virt-host-validate-lxc.c
+++ b/tools/virt-host-validate-lxc.c
@@ -63,5 +63,35 @@ int virHostValidateLXC(void)
_("User namespace support is recommended")) < 0)
ret = -1;
+ if (virHostValidateCGroupController("LXC", "memory",
+ VIR_HOST_VALIDATE_FAIL,
+ "MEMCG") < 0)
+ ret = -1;
+
+ if (virHostValidateCGroupController("LXC", "cpu",
+ VIR_HOST_VALIDATE_FAIL,
+ "CGROUP_SCHED") < 0)
+ ret = -1;
+
+ if (virHostValidateCGroupController("LXC", "cpuacct",
+ VIR_HOST_VALIDATE_FAIL,
+ "CGROUP_CPUACCT") < 0)
+ ret = -1;
+
+ if (virHostValidateCGroupController("LXC", "devices",
+ VIR_HOST_VALIDATE_FAIL,
+ "CGROUP_DEVICE") < 0)
+ ret = -1;
+
+ if (virHostValidateCGroupController("LXC", "net_cls",
+ VIR_HOST_VALIDATE_WARN,
+ "NET_CLS_CGROUP") < 0)
+ ret = -1;
+
+ if (virHostValidateCGroupController("LXC", "freezer",
+ VIR_HOST_VALIDATE_WARN,
+ "CGROUP_FREEZER") < 0)
+ ret = -1;
+
return ret;
}
diff --git a/tools/virt-host-validate-qemu.c b/tools/virt-host-validate-qemu.c
index 9486064f8a..b0ae293be5 100644
--- a/tools/virt-host-validate-qemu.c
+++ b/tools/virt-host-validate-qemu.c
@@ -57,5 +57,35 @@ int virHostValidateQEMU(void)
_("Load the 'tun' module to enable networking for QEMU guests")) < 0)
ret = -1;
+ if (virHostValidateCGroupController("QEMU", "memory",
+ VIR_HOST_VALIDATE_WARN,
+ "MEMCG") < 0)
+ ret = -1;
+
+ if (virHostValidateCGroupController("QEMU", "cpu",
+ VIR_HOST_VALIDATE_WARN,
+ "CGROUP_CPU") < 0)
+ ret = -1;
+
+ if (virHostValidateCGroupController("QEMU", "cpuacct",
+ VIR_HOST_VALIDATE_WARN,
+ "CGROUP_CPUACCT") < 0)
+ ret = -1;
+
+ if (virHostValidateCGroupController("QEMU", "devices",
+ VIR_HOST_VALIDATE_WARN,
+ "CGROUP_DEVICES") < 0)
+ ret = -1;
+
+ if (virHostValidateCGroupController("QEMU", "net_cls",
+ VIR_HOST_VALIDATE_WARN,
+ "NET_CLS_CGROUP") < 0)
+ ret = -1;
+
+ if (virHostValidateCGroupController("QEMU", "blkio",
+ VIR_HOST_VALIDATE_WARN,
+ "BLK_CGROUP") < 0)
+ ret = -1;
+
return ret;
}