[PATCH] hypervisor: new tool for hypervisor detection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The tool has been written by Ky Srinivasan <ksrinivasan@xxxxxxxxxx>.
It detects the presence or absence of a hypervisor, currently
Xen, KVM and HyperV.

Signed-off-by: Matthias Koenig <mkoenig@xxxxxxx>
---

 sys-utils/Makefile.am  |    5 +
 sys-utils/hypervisor.1 |   41 ++++++++++++
 sys-utils/hypervisor.c |  169 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 215 insertions(+), 0 deletions(-)

diff --git a/configure.ac b/configure.ac
index 770eb45..3714f00 100644
--- a/configure.ac
+++ b/configure.ac
@@ -466,6 +466,12 @@ AC_ARG_ENABLE([elvtune],
 )
 AM_CONDITIONAL(BUILD_ELVTUNE, test "x$enable_elvtune" = xyes)
 
+AC_ARG_ENABLE([hypervisor],
+  AS_HELP_STRING([--enable-hypervisor], [build hypervisor]),
+  [], enable_hypervisor=no
+)
+AM_CONDITIONAL(BUILD_HYPERVISOR, test "x$enable_hypervisor" = xyes)
+
 
 AC_ARG_ENABLE([init],
   AS_HELP_STRING([--enable-init], [build simpleinit, shutdown, initctl]),
diff --git a/sys-utils/Makefile.am b/sys-utils/Makefile.am
index 0dbbb48..e3b7f2d 100644
--- a/sys-utils/Makefile.am
+++ b/sys-utils/Makefile.am
@@ -35,6 +35,11 @@ RDEV_LINKS += ramsize vidmode rootflags
 dist_man_MANS += rdev.8
 endif
 
+if BUILD_HYPERVISOR
+bin_PROGRAMS += hypervisor
+dist_man_MANS += hypervisor.1
+endif
+
 SETARCH_LINKS = linux32 linux64
 
 if ARCH_S390
diff --git a/sys-utils/hypervisor.1 b/sys-utils/hypervisor.1
new file mode 100644
index 0000000..807969b
--- /dev/null
+++ b/sys-utils/hypervisor.1
@@ -0,0 +1,41 @@
+.TH hypervisor 1 "September 2008" "" "User Commands"
+.SH NAME
+hypervisor \- detect presence of a hypervisor
+.SH SYNOPSIS
+.B hypervisor
+[\fIOPTION\fR]
+.SH DESCRIPTION
+Detects the presence/absence of a hypervisor.
+.SH OPTIONS
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Show this message and exit.
+.TP
+\fB\-q\fR, \fB\-\-quiet\fR
+Do not show output message.
+.SH EXIT CODES
+.TP
+0
+No hypervisor detected.
+.TP
+1
+Xen detected.
+.TP
+2
+KVM detected.
+.TP
+3
+HyperV detected.
+.TP
+4
+HyperV emulating Xen detected.
+.SH AUTHOR
+Ky Srinivasan <ksrinivasan@xxxxxxxxxx>
+.SH AVAILABILITY
+The hypervisor command is part of the util-linux-ng package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+.SH COPYRIGHT
+This is free software.  You may redistribute copies of it  under  the  terms
+of  the  GNU General  Public  License <http://www.gnu.org/licenses/gpl.html>.
+There is NO WARRANTY, to the extent permitted by law.
+
diff --git a/sys-utils/hypervisor.c b/sys-utils/hypervisor.c
new file mode 100644
index 0000000..4afd962
--- /dev/null
+++ b/sys-utils/hypervisor.c
@@ -0,0 +1,169 @@
+/* Detect the presence of a hypervisor
+ * Copyright (C) 2008 Novell, Inc.
+ * Author: Ky Srinivasan <ksrinivasan@xxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+
+static int opt_quiet = 0;
+
+struct option options[] = {
+	{ "help",	no_argument,	NULL,	'h' },
+	{ "quiet",	no_argument,	NULL,	'q' },
+	{ NULL,		9,		NULL,	0   }
+};
+
+enum {
+	HYPER_NONE = 0,
+	HYPER_XEN,
+	HYPER_KVM,
+	HYPER_MSHV,
+	HYPER_MSHV_XENPV
+};
+
+static inline void cpuid(unsigned int op,
+		         unsigned int *eax, unsigned int *ebx,
+			 unsigned int *ecx, unsigned int *edx)
+{
+	__asm__("cpuid"
+		: "=a" (*eax),
+		  "=b" (*ebx),
+		  "=c" (*ecx),
+		  "=d" (*edx)
+		: "0" (op), "c"(0));
+}
+
+static int hypervisor(void)
+{
+	unsigned int eax, ebx, ecx, edx;
+	char signature[13];
+	int xen_pv =0;
+
+	/*
+	 * First check if we are running in a para-virtualized guest.
+	 */
+	if ((!access("/sys/hypervisor", F_OK) ||
+            (!access("/proc/xen", F_OK)))) {
+		/*
+		 * For now we are only dealing with para-virtualized
+		 * Linux guests (para-virtualized on Xen). So, this must be
+		 * Xen based.
+		 */
+		xen_pv = 1;
+	}
+	cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
+	*(unsigned int*)(signature + 0) = ebx;
+	*(unsigned int*)(signature + 4) = ecx;
+	*(unsigned int*)(signature + 8) = edx;
+	signature[12] = 0;
+
+	if ((!strncmp("XenVMMXenVMM", signature, 12) || (xen_pv)))
+		return HYPER_XEN;
+	if (!strncmp("KVMKVMKVM", signature, 9))
+		return HYPER_KVM;
+	if (!strncmp("Microsoft Hv", signature, 12)) {
+		if (xen_pv)
+			return HYPER_MSHV_XENPV;
+		else
+			return HYPER_MSHV;
+	}
+
+	return 0;
+}
+
+static void help(void)
+{
+	printf("Usage: hypervisor [OPTION]\n");
+	printf("Detects the presence/absence of a hypervisor.\n\n");
+	printf("Options:\n");
+	printf("  -h, --help\tShow this message and exit.\n");
+	printf("  -q, --quiet\tDo not show output message.\n\n");
+	printf("Exit status:\n");
+	printf("  0\tNo hypervisor detected.\n");
+	printf("  1\tXen detected.\n");
+	printf("  2\tKVM detected.\n");
+	printf("  3\tHyperV detected.\n");
+	printf("  4\tHyperV emulating Xen detected.\n");
+}
+
+
+/*
+ * Program to determine if we are being hosted on the hypervisor.
+ * If the exit status is 0; we are running on bare hardware. The details of
+ * non-zero return values are as follows:
+ *
+ * 0: No hypervisor (running on bare hardware)
+ * 1: Xen is the hypervisor
+ * 2: KVM is the hypervisor
+ * 3: Veridian
+ * 4: Veridian hypervisor emulating Xen.
+ * TODO: VmWare Detection.
+ */
+int main(int argc, char **argv)
+{
+	int option_index, c;
+	int ret;
+
+	while (1) {
+		c = getopt_long(argc, argv, "hq", options, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+			case 'h':
+				help();
+				exit(EXIT_SUCCESS);
+			case 'q':
+				opt_quiet = 1;
+				break;
+			default:
+				break;
+		}
+	}
+
+	ret = hypervisor();
+
+	if (!opt_quiet) {
+		switch (ret) {
+		case HYPER_NONE:
+			printf("No");
+			break;
+		case HYPER_XEN:
+			printf("Xen");
+			break;
+		case HYPER_KVM:
+			printf("KVM");
+			break;
+		case HYPER_MSHV:
+		case HYPER_MSHV_XENPV:
+			printf("Microsoft");
+			break;
+		default:
+			break;
+		}
+		printf(" Hypervisor found\n");
+	}
+
+	return ret;
+}
+

--
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux