3
0
forked from pool/util-linux
util-linux/util-linux-2.14.1-hypervisor_detection.patch

251 lines
6.4 KiB
Diff

Index: util-linux-ng-2.14.1/sys-utils/hypervisor.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ util-linux-ng-2.14.1/sys-utils/hypervisor.c 2008-09-24 12:21:05.000000000 +0200
@@ -0,0 +1,169 @@
+/* Detect the presence of a hypervisor
+ * Copyright (C) 2008 Novell, Inc.
+ * Author: Ky Srinivasan <ksrinivasan@novell.com>
+ *
+ * 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;
+}
+
Index: util-linux-ng-2.14.1/sys-utils/Makefile.am
===================================================================
--- util-linux-ng-2.14.1.orig/sys-utils/Makefile.am 2008-09-10 11:02:43.000000000 +0200
+++ util-linux-ng-2.14.1/sys-utils/Makefile.am 2008-09-24 13:03:21.000000000 +0200
@@ -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
Index: util-linux-ng-2.14.1/configure.ac
===================================================================
--- util-linux-ng-2.14.1.orig/configure.ac 2008-09-10 12:13:27.000000000 +0200
+++ util-linux-ng-2.14.1/configure.ac 2008-09-24 11:43:15.000000000 +0200
@@ -471,6 +471,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]),
Index: util-linux-ng-2.14.1/sys-utils/hypervisor.1
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ util-linux-ng-2.14.1/sys-utils/hypervisor.1 2008-09-24 13:06:24.000000000 +0200
@@ -0,0 +1,38 @@
+.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@novell.com>
+.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.
+