diff --git a/libvirt.spec.in b/libvirt.spec.in index a5bd1738751e637e7eae965305117001654393cb..f279d6dd3a338ce97a33603454f4ed4037d78e93 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1198,9 +1198,11 @@ rm -f $RPM_BUILD_ROOT%{_sysconfdir}/sysctl.d/libvirtd %{_mandir}/man1/virsh.1* %{_mandir}/man1/virt-xml-validate.1* %{_mandir}/man1/virt-pki-validate.1* +%{_mandir}/man1/virt-host-validate.1* %{_bindir}/virsh %{_bindir}/virt-xml-validate %{_bindir}/virt-pki-validate +%{_bindir}/virt-host-validate %{_libdir}/lib*.so.* %dir %{_datadir}/libvirt/ diff --git a/mingw32-libvirt.spec.in b/mingw32-libvirt.spec.in index ef636cd39f0cbde9038ef8740a386484472fd61c..961c3ba054aad5d828f81f23a579ce4b945fc4c4 100644 --- a/mingw32-libvirt.spec.in +++ b/mingw32-libvirt.spec.in @@ -147,6 +147,7 @@ rm -rf $RPM_BUILD_ROOT %{_mingw32_bindir}/virsh.exe %{_mingw32_bindir}/virt-xml-validate %{_mingw32_bindir}/virt-pki-validate +%{_mingw32_bindir}/virt-host-validate.exe %{_mingw32_bindir}/libvirt-qemu-0.dll %{_mingw32_libdir}/libvirt.dll.a diff --git a/po/POTFILES.in b/po/POTFILES.in index 674d6df578808b6867c1f478e020cfd692807638..ba93334e09cfd4e65ddb560a57ff693eb4536979 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -159,3 +159,7 @@ src/xenxs/xen_xm.c tools/console.c tools/libvirt-guests.init.sh tools/virsh.c +tools/virt-host-validate-common.c +tools/virt-host-validate-lxc.c +tools/virt-host-validate-qemu.c +tools/virt-host-validate.c diff --git a/tools/Makefile.am b/tools/Makefile.am index 6705546d285f79f154502dfa54904c9377e44aa1..6596a513366b2aed75846e4e5efba082e983a917 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -30,14 +30,18 @@ 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 DISTCLEANFILES += virt-sanlock-cleanup endif -dist_man1_MANS = virt-xml-validate.1 virt-pki-validate.1 virsh.1 +dist_man1_MANS = \ + virt-host-validate.1 \ + virt-pki-validate.1 \ + virt-xml-validate.1 \ + virsh.1 if HAVE_SANLOCK dist_man8_MANS = virt-sanlock-cleanup.8 endif @@ -56,6 +60,9 @@ virt-pki-validate: virt-pki-validate.in Makefile virt-pki-validate.1: virt-pki-validate.in $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@ +virt-host-validate.1: virt-host-validate.c + $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@ + virt-sanlock-cleanup: virt-sanlock-cleanup.in Makefile $(AM_V_GEN)sed -e 's,[@]SYSCONFDIR@,$(sysconfdir),' \ -e 's,[@]LOCALSTATEDIR@,$(localstatedir),' < $< > $@ \ @@ -64,6 +71,28 @@ 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 = \ + ../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 0000000000000000000000000000000000000000..bd118be0bff398069fc4f7b3587ada5008949a4e --- /dev/null +++ b/tools/virt-host-validate-common.c @@ -0,0 +1,190 @@ +/* + * virt-host-validate-common.c: Sanity check helper APIs + * + * Copyright (C) 2012 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 + +#include +#include +#include +#include +#include + +#include "util.h" +#include "memory.h" +#include "virfile.h" +#include "virt-host-validate-common.h" + +static bool quiet; + +void virHostMsgSetQuiet(bool quietFlag) +{ + quiet = quietFlag; +} + +void virHostMsgCheck(const char *prefix, + 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); + + fprintf(stdout, _("%6s: Checking %-60s: "), prefix, msg); + VIR_FREE(msg); +} + +static bool virHostMsgWantEscape(void) +{ + static bool detectTty = true; + static bool wantEscape = false; + if (detectTty) { + if (isatty(STDOUT_FILENO)) + wantEscape = true; + detectTty = false; + } + return wantEscape; +} + +void virHostMsgPass(void) +{ + if (quiet) + return; + + if (virHostMsgWantEscape()) + fprintf(stdout, "\033[32m%s\033[0m\n", _("PASS")); + else + fprintf(stdout, "%s\n", _("PASS")); +} + + +static const char * failMessages[] = { + N_("FAIL"), + N_("WARN"), + N_("NOTE"), +}; + +verify(ARRAY_CARDINALITY(failMessages) == VIR_HOST_VALIDATE_LAST); + +static const char *failEscapeCodes[] = { + "\033[31m", + "\033[33m", + "\033[34m", +}; + +verify(ARRAY_CARDINALITY(failEscapeCodes) == VIR_HOST_VALIDATE_LAST); + +void virHostMsgFail(virHostValidateLevel level, + const char *hint) +{ + if (virHostMsgWantEscape()) + fprintf(stdout, "%s%s\033[0m (%s)\n", + failEscapeCodes[level], _(failMessages[level]), hint); + else + fprintf(stdout, "%s (%s)\n", + _(failMessages[level]), 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; +} + + +bool virHostValidateHasCPUFlag(const char *name) +{ + FILE *fp = fopen("/proc/cpuinfo", "r"); + bool ret = false; + + if (!fp) + return false; + + do { + char line[1024]; + + if (!fgets(line, sizeof(line), fp)) + break; + + if (strstr(line, name)) { + ret = true; + break; + } + } while (1); + + VIR_FORCE_FCLOSE(fp); + + return ret; +} + + +int virHostValidateLinuxKernel(const char *hvname, + int version, + virHostValidateLevel level, + const char *hint) +{ + struct utsname uts; + unsigned long thisversion; + + 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 (virParseVersionString(uts.release, &thisversion, true) < 0) { + virHostMsgFail(level, hint); + return -1; + } + + if (thisversion < version) { + virHostMsgFail(level, hint); + return -1; + } else { + virHostMsgPass(); + return 0; + } +} diff --git a/tools/virt-host-validate-common.h b/tools/virt-host-validate-common.h new file mode 100644 index 0000000000000000000000000000000000000000..93d8a83a3aa94d7b68fe29919207ddb647007750 --- /dev/null +++ b/tools/virt-host-validate-common.h @@ -0,0 +1,57 @@ +/* + * virt-host-validate-common.h: Sanity check helper APIs + * + * Copyright (C) 2012 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, + + VIR_HOST_VALIDATE_LAST, +} virHostValidateLevel; + +extern void virHostMsgSetQuiet(bool quietFlag); + +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 bool 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 0000000000000000000000000000000000000000..9d69b67e6fb7d7b7adb43c04f285ea85a4052c6d --- /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) 2012 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 + +#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 0000000000000000000000000000000000000000..7efc229009ea931ae4711f79b87c2f620e65c4fa --- /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) 2012 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 0000000000000000000000000000000000000000..b65d44911b26375f7c3e48b5945eba78df78952a --- /dev/null +++ b/tools/virt-host-validate-qemu.c @@ -0,0 +1,57 @@ +/* + * virt-host-validate-qemu.c: Sanity check a QEMU hypervisor host + * + * Copyright (C) 2012 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 + +#include "virt-host-validate-qemu.h" +#include "virt-host-validate-common.h" + +int virHostValidateQEMU(void) +{ + int ret = 0; + + virHostMsgCheck("QEMU", "%s", ("for hardware virtualization")); + if (virHostValidateHasCPUFlag("svm") || + virHostValidateHasCPUFlag("vmx")) { + virHostMsgPass(); + 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; + } else { + virHostMsgFail(VIR_HOST_VALIDATE_WARN, + _("Only emulated CPUs are available, performance will be significantly limited")); + } + + if (virHostValidateDevice("QEMU", "/dev/vhost-net", + 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 0000000000000000000000000000000000000000..ba5f03b2dfb585a7ce77b205ecb4653e9941bd9c --- /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) 2012 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 0000000000000000000000000000000000000000..3893ba3a9dbd4a1242f8863f3f654f1ec7e6f48a --- /dev/null +++ b/tools/virt-host-validate.c @@ -0,0 +1,224 @@ +/* + * virt-host-check.c: Sanity check a hypervisor host + * + * Copyright (C) 2012 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 + +#include +#include +#include +#include + +#include "internal.h" +#include "configmake.h" + +#include "virt-host-validate-common.h" +#if WITH_QEMU +# include "virt-host-validate-qemu.h" +#endif +#if WITH_LXC +# include "virt-host-validate-lxc.h" +#endif + +static void +show_help(FILE *out, const char *argv0) +{ + fprintf(out, + _("\n" + "syntax: %s [OPTIONS] [HVTYPE]\n" + "\n" + " Hypervisor types:\n" + "\n" + " - qemu\n" + " - lxc\n" + "\n" + " Options:\n" + " -h, --help Display command line help\n" + " -v, --version Display command version\n" + " -q, --quiet Don't display progress information\n" + "\n"), + argv0); +} + +static void +show_version(FILE *out, const char *argv0) +{ + fprintf(out, "version: %s %s\n", argv0, VERSION); +} + +static const struct option argOptions[] = { + { "help", 0, NULL, 'h', }, + { "version", 0, NULL, 'v', }, + { "quiet", 0, NULL, 'q', }, + { NULL, 0, NULL, '\0', } +}; + +int +main(int argc, char **argv) +{ + const char *hvname = NULL; + int c; + int ret = EXIT_SUCCESS; + bool quiet = false; + bool usedHvname = false; + + 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; + } + + while ((c = getopt_long(argc, argv, "hvq", argOptions, NULL)) != -1) { + switch (c) { + case 'v': + show_version(stdout, argv[0]); + return EXIT_SUCCESS; + + case 'h': + show_help(stdout, argv[0]); + return EXIT_SUCCESS; + + case 'q': + quiet = true; + break; + + case '?': + default: + show_help(stderr, argv[0]); + return EXIT_FAILURE; + } + } + + if ((argc-optind) > 2) { + fprintf(stderr, _("%s: too many command line arguments\n"), argv[0]); + show_help(stderr, argv[0]); + return EXIT_FAILURE; + } + + if (argc > 1) + hvname = argv[optind]; + + virHostMsgSetQuiet(quiet); + +#if WITH_QEMU + if (!hvname || STREQ(hvname, "qemu")) { + usedHvname = true; + if (virHostValidateQEMU() < 0) + ret = EXIT_FAILURE; + } +#endif + +#if WITH_LXC + if (!hvname || STREQ(hvname, "lxc")) { + usedHvname = true; + if (virHostValidateLXC() < 0) + ret = EXIT_FAILURE; + } +#endif + + if (hvname && !usedHvname) { + fprintf(stderr, _("%s: unsupported hypervisor name %s\n"), + argv[0], hvname); + return EXIT_FAILURE; + } + + return ret; +} + +/* + +=pod + +=head1 NAME + + virt-host-validate - validate host virtualization setup + +=head1 SYNOPSIS + + virt-host-validate [OPTIONS...] [HV-TYPE] + +=head1 DESCRIPTION + +This tool validates that the host is configured in a suitable +way to run libvirt hypervisor drivers. If invoked without any +arguments it will check support for all hypervisor drivers it +is aware of. Optionally it can be given a particular hypervisor +type ('qemu' or 'lxc') to restrict the checks to those relevant +for that virtualization technology + +=head1 OPTIONS + +=over 4 + +=item C<-v>, C<--version> + +Display the command version + +=item C<-h>, C<--help> + +Display the command line help + +=item C<-q>, C<--quiet> + +Don't display details of individual checks being performed. +Only display output if a check does not pass. + +=back + +=head1 EXIT STATUS + +Upon successful validation, an exit status of 0 will be set. Upon +failure a non-zero status will be set. + +=head1 AUTHOR + +Daniel P. Berrange + +=head1 BUGS + +Report any bugs discovered to the libvirt community via the +mailing list C or bug tracker C. +Alternatively report bugs to your software distributor / vendor. + +=head1 COPYRIGHT + +Copyright (C) 2012 by Red Hat, Inc. + +=head1 LICENSE + +virt-host-validate is distributed under the terms of the GNU GPL v2+. +This is free software; see the source for copying conditions. There +is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE + +=head1 SEE ALSO + +C, C, C + +=cut + +*/