[libvirt] [PATCH RFC] Add a virt-host-validate command to sanity check HV config

Daniel P. Berrange berrange at redhat.com
Tue Jan 10 17:33:33 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

To assist people in verifying that their host is operating in an
optimal manner, provide a 'virt-host-validate' command. For each
type of hypervisor, it will check any pre-requisites, or other
good recommendations and report what's working & what is not.

eg

  # virt-host-validate
  QEMU: Checking for device /dev/kvm                                         : FAIL (Check that the 'kvm-intel' or 'kvm-amd' modules are loaded & the BIOS has enabled virtualization)
  QEMU: Checking for device /dev/vhost                                       : WARN (Load the 'vhost_net' module to improve performance of virtio networking)
  QEMU: Checking for device /dev/net/tun                                     : PASS
   LXC: Checking for Linux >= 2.6.26                                         : PASS

This warns people if they have vmx/svm, but don't have /dev/kvm. It
also warns about missing /dev/vhost net.
---
 tools/Makefile.am                 |   25 ++++++-
 tools/virt-host-validate-common.c |  166 +++++++++++++++++++++++++++++++++++++
 tools/virt-host-validate-common.h |   53 ++++++++++++
 tools/virt-host-validate-lxc.c    |   37 ++++++++
 tools/virt-host-validate-lxc.h    |   27 ++++++
 tools/virt-host-validate-qemu.c   |   50 +++++++++++
 tools/virt-host-validate-qemu.h   |   27 ++++++
 tools/virt-host-validate.c        |   77 +++++++++++++++++
 8 files changed, 461 insertions(+), 1 deletions(-)
 create mode 100644 tools/virt-host-validate-common.c
 create mode 100644 tools/virt-host-validate-common.h
 create mode 100644 tools/virt-host-validate-lxc.c
 create mode 100644 tools/virt-host-validate-lxc.h
 create mode 100644 tools/virt-host-validate-qemu.c
 create mode 100644 tools/virt-host-validate-qemu.h
 create mode 100644 tools/virt-host-validate.c

diff --git a/tools/Makefile.am b/tools/Makefile.am
index 6705546..2b14319 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -30,7 +30,7 @@ EXTRA_DIST = \
 DISTCLEANFILES =
 
 bin_SCRIPTS = virt-xml-validate virt-pki-validate
-bin_PROGRAMS = virsh
+bin_PROGRAMS = virsh virt-host-validate
 
 if HAVE_SANLOCK
 sbin_SCRIPTS = virt-sanlock-cleanup
@@ -64,6 +64,29 @@ virt-sanlock-cleanup: virt-sanlock-cleanup.in Makefile
 virt-sanlock-cleanup.8: virt-sanlock-cleanup.in
 	$(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@
 
+virt_host_validate_SOURCES = \
+		virt-host-validate.c \
+		virt-host-validate-common.c virt-host-validate-common.h \
+		virt-host-validate-qemu.c virt-host-validate-qemu.h \
+		virt-host-validate-lxc.c virt-host-validate-lxc.h \
+		$(NULL)
+
+virt_host_validate_LDFLAGS = \
+		$(WARN_LDFLAGS) \
+		$(COVERAGE_LDFLAGS) \
+		$(NULL)
+
+virt_host_validate_LDADD = \
+		$(WARN_CFLAGS)					\
+		../src/libvirt.la				\
+		../gnulib/lib/libgnu.la				\
+		$(NULL)
+
+virt_host_validate_CFLAGS = \
+		$(WARN_CFLAGS)					\
+		$(COVERAGE_CFLAGS)				\
+		$(NULL)
+
 virsh_SOURCES =							\
 		console.c console.h				\
 		virsh.c
diff --git a/tools/virt-host-validate-common.c b/tools/virt-host-validate-common.c
new file mode 100644
index 0000000..7ada218
--- /dev/null
+++ b/tools/virt-host-validate-common.c
@@ -0,0 +1,166 @@
+/*
+ * virt-host-validate-common.c: Sanity check helper APis
+ *
+ * Copyright (C) 2011 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <config.h>
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+
+#include "util.h"
+#include "memory.h"
+#include "virt-host-validate-common.h"
+
+void virHostMsgCheck(const char *prefix,
+                     const char *format,
+                     ...)
+{
+    va_list args;
+    char *msg;
+
+    va_start(args, format);
+    if (virVasprintf(&msg, format, args) < 0) {
+        perror("malloc");
+        abort();
+    }
+    va_end(args);
+
+    fprintf(stdout, "%6s: Checking %-60s: ", prefix, msg);
+    VIR_FREE(msg);
+}
+
+void virHostMsgPass(void)
+{
+    fprintf(stdout, "\033[32mPASS\033[0m\n");
+}
+
+void virHostMsgFail(virHostValidateLevel level,
+                    const char *hint)
+{
+    if (level == VIR_HOST_VALIDATE_FAIL)
+        fprintf(stdout, "\033[31mFAIL\033[0m (%s)\n", hint);
+    else if (level == VIR_HOST_VALIDATE_WARN)
+        fprintf(stdout, "\033[33mWARN\033[0m (%s)\n", hint);
+    else if (level == VIR_HOST_VALIDATE_NOTE)
+        fprintf(stdout, "\033[34mNOTE\033[0m (%s)\n", hint);
+}
+
+
+int virHostValidateDevice(const char *hvname,
+                          const char *devname,
+                          virHostValidateLevel level,
+                          const char *hint)
+{
+    virHostMsgCheck(hvname, "for device %s", devname);
+
+    if (access(devname, R_OK|W_OK) < 0) {
+        virHostMsgFail(level, hint);
+        return -1;
+    }
+
+    virHostMsgPass();
+    return 0;
+}
+
+
+int virHostValidateHasCPUFlag(const char *name)
+{
+    FILE *fp = fopen("/proc/cpuinfo", "r");
+    int ret = 0;
+
+    if (!fp)
+        return 0;
+
+    do {
+        char line[1024];
+
+        if (!fgets(line, sizeof(line), fp))
+            break;
+
+        if (strstr(line, name)) {
+            ret = 1;
+            break;
+        }
+    } while (1);
+
+    fclose(fp);
+
+    return ret;
+}
+
+
+int virHostValidateLinuxKernel(const char *hvname,
+                               int version,
+                               virHostValidateLevel level,
+                               const char *hint)
+{
+    struct utsname uts;
+    int major, minor, micro;
+
+    uname(&uts);
+
+    virHostMsgCheck(hvname, "for Linux >= %d.%d.%d",
+                    ((version >> 16) & 0xff),
+                    ((version >> 8) & 0xff),
+                    (version & 0xff));
+
+    if (STRNEQ(uts.sysname, "Linux")) {
+        virHostMsgFail(level, hint);
+        return -1;
+    }
+
+    if (sscanf(uts.release, "%d.%d.%d", &major, &minor, &micro) != 3) {
+        micro = 0;
+        if (sscanf(uts.release, "%d.%d", &major, &minor) != 2) {
+            virHostMsgFail(level, hint);
+            return -1;
+        }
+    }
+
+    if (major > ((version >> 16) & 0xff)) {
+        virHostMsgPass();
+        return 0;
+    } else if (major < ((version >> 16) & 0xff)) {
+        virHostMsgFail(level, hint);
+        return -1;
+    }
+
+    if (minor > ((version >> 8) & 0xff)) {
+        virHostMsgPass();
+        return 0;
+    } else if (minor < ((version >> 8) & 0xff)) {
+        virHostMsgFail(level, hint);
+        return -1;
+    }
+
+    if (micro > (version & 0xff)) {
+        virHostMsgPass();
+        return 0;
+    } else if (micro < (version & 0xff)) {
+        virHostMsgFail(level, hint);
+        return -1;
+    }
+
+    virHostMsgPass();
+    return 0;
+}
diff --git a/tools/virt-host-validate-common.h b/tools/virt-host-validate-common.h
new file mode 100644
index 0000000..6a4d1ac
--- /dev/null
+++ b/tools/virt-host-validate-common.h
@@ -0,0 +1,53 @@
+/*
+ * virt-host-validate-common.h: Sanity check helper APis
+ *
+ * Copyright (C) 2011 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#ifndef __VIRT_HOST_VALIDATE_COMMON_H__
+#define __VIRT_HOST_VALIDATE_COMMON_H__
+
+#include "internal.h"
+
+typedef enum {
+    VIR_HOST_VALIDATE_FAIL,
+    VIR_HOST_VALIDATE_WARN,
+    VIR_HOST_VALIDATE_NOTE,
+} virHostValidateLevel;
+
+extern void virHostMsgCheck(const char *prefix,
+                            const char *format,
+                            ...) ATTRIBUTE_FMT_PRINTF(2, 3);
+
+extern void virHostMsgPass(void);
+extern void virHostMsgFail(virHostValidateLevel level,
+                           const char *hint);
+
+extern int virHostValidateDevice(const char *hvname,
+                                 const char *devname,
+                                 virHostValidateLevel level,
+                                 const char *hint);
+
+extern int virHostValidateHasCPUFlag(const char *name);
+
+extern int virHostValidateLinuxKernel(const char *hvname,
+                                      int version,
+                                      virHostValidateLevel level,
+                                      const char *hint);
+
+#endif /* __VIRT_HOST_VALIDATE_COMMON_H__ */
diff --git a/tools/virt-host-validate-lxc.c b/tools/virt-host-validate-lxc.c
new file mode 100644
index 0000000..f41cf78
--- /dev/null
+++ b/tools/virt-host-validate-lxc.c
@@ -0,0 +1,37 @@
+/*
+ * virt-host-validate-lxc.c: Sanity check a LXC hypervisor host
+ *
+ * Copyright (C) 2011 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <config.h>
+
+#include "virt-host-validate-lxc.h"
+#include "virt-host-validate-common.h"
+
+int virHostValidateLXC(void)
+{
+    int ret = 0;
+
+    if (virHostValidateLinuxKernel("LXC", (2 << 16) | (6 << 8) | 26,
+                                   VIR_HOST_VALIDATE_FAIL,
+                                   "Upgrade to a kernel supporting namespaces") < 0)
+        ret = -1;
+
+    return ret;
+}
diff --git a/tools/virt-host-validate-lxc.h b/tools/virt-host-validate-lxc.h
new file mode 100644
index 0000000..3cae39f
--- /dev/null
+++ b/tools/virt-host-validate-lxc.h
@@ -0,0 +1,27 @@
+/*
+ * virt-host-validate-lxc.h: Sanity check a LXC hypervisor host
+ *
+ * Copyright (C) 2011 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#ifndef __VIRT_HOST_VALIDATE_LXC_H__
+#define __VIRT_HOST_VALIDATE_LXC_H__
+
+extern int virHostValidateLXC(void);
+
+#endif /* __VIRT_HOST_VALIDATE_LXC_H__ */
diff --git a/tools/virt-host-validate-qemu.c b/tools/virt-host-validate-qemu.c
new file mode 100644
index 0000000..b0e4fe5
--- /dev/null
+++ b/tools/virt-host-validate-qemu.c
@@ -0,0 +1,50 @@
+/*
+ * virt-host-validate-qemu.c: Sanity check a QEMU hypervisor host
+ *
+ * Copyright (C) 2011 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <config.h>
+
+#include "virt-host-validate-qemu.h"
+#include "virt-host-validate-common.h"
+
+int virHostValidateQEMU(void)
+{
+    int ret = 0;
+
+    if (virHostValidateHasCPUFlag("svm") ||
+        virHostValidateHasCPUFlag("vmx")) {
+        if (virHostValidateDevice("QEMU", "/dev/kvm",
+                                  VIR_HOST_VALIDATE_FAIL,
+                                  "Check that the 'kvm-intel' or 'kvm-amd' modules are loaded & the BIOS has enabled virtualization") < 0)
+            ret = -1;
+    }
+
+    if (virHostValidateDevice("QEMU", "/dev/vhost",
+                              VIR_HOST_VALIDATE_WARN,
+                              "Load the 'vhost_net' module to improve performance of virtio networking") < 0)
+        ret = -1;
+
+    if (virHostValidateDevice("QEMU", "/dev/net/tun",
+                              VIR_HOST_VALIDATE_FAIL,
+                              "Load the 'tun' module to enable networking for QEMU guests") < 0)
+        ret = -1;
+
+    return ret;
+}
diff --git a/tools/virt-host-validate-qemu.h b/tools/virt-host-validate-qemu.h
new file mode 100644
index 0000000..e1dbcbe
--- /dev/null
+++ b/tools/virt-host-validate-qemu.h
@@ -0,0 +1,27 @@
+/*
+ * virt-host-validate-qemu.h: Sanity check a QEMU hypervisor host
+ *
+ * Copyright (C) 2011 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#ifndef __VIRT_HOST_VALIDATE_QEMU_H__
+#define __VIRT_HOST_VALIDATE_QEMU_H__
+
+extern int virHostValidateQEMU(void);
+
+#endif /* __VIRT_HOST_VALIDATE_QEMU_H__ */
diff --git a/tools/virt-host-validate.c b/tools/virt-host-validate.c
new file mode 100644
index 0000000..b94aa8f
--- /dev/null
+++ b/tools/virt-host-validate.c
@@ -0,0 +1,77 @@
+/*
+ * virt-host-check.c: Sanity check a hypervisor host
+ *
+ * Copyright (C) 2011 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <gettext.h>
+
+#include "internal.h"
+#include "configmake.h"
+
+#include "virt-host-validate-qemu.h"
+#include "virt-host-validate-lxc.h"
+
+static void
+show_help(FILE *out, const char *argv0)
+{
+    fprintf(out, "syntax: %s [OPTIONS] [HVTYPE]\n", argv0);
+}
+
+int
+main(int argc, char **argv)
+{
+    const char *hvname = NULL;
+    int ret = EXIT_SUCCESS;
+
+    if (!setlocale(LC_ALL, "")) {
+        perror("setlocale");
+        /* failure to setup locale is not fatal */
+    }
+    if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
+        perror("bindtextdomain");
+        return EXIT_FAILURE;
+    }
+    if (!textdomain(PACKAGE)) {
+        perror("textdomain");
+        return EXIT_FAILURE;
+    }
+
+    if (argc > 2) {
+        fprintf(stderr, "too many command line arguments\n");
+        show_help(stderr, argv[0]);
+        return EXIT_FAILURE;
+    }
+
+    if (argc > 1)
+        hvname = argv[1];
+
+    if ((!hvname || STREQ(hvname, "qemu")) &&
+        virHostValidateQEMU() < 0)
+        ret = EXIT_FAILURE;
+
+    if ((!hvname || STREQ(hvname, "lxc")) &&
+        virHostValidateLXC() < 0)
+        ret = EXIT_FAILURE;
+
+    return ret;
+}
-- 
1.7.7.5




More information about the libvir-list mailing list