# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1261556533 0
# Node ID 07f98beddc185f950e5421945a074f3fa51d4662
# Parent 52e8af2eba167eb2b0d4aa94048a969ede1ef789
xen-detect: Add command-line arguments.
- Usage info
- Quiesce normal output
- Affect exit status if running in unexpected context
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
tools/misc/xen-detect.c | 79 ++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 70 insertions(+), 9 deletions(-)
diff -r 52e8af2eba16 -r 07f98beddc18 tools/misc/xen-detect.c
--- a/tools/misc/xen-detect.c Wed Dec 23 07:36:33 2009 +0000
+++ b/tools/misc/xen-detect.c Wed Dec 23 08:22:13 2009 +0000
@@ -25,10 +25,13 @@
*/
#include <stdint.h>
+#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include <signal.h>
+#include <unistd.h>
+#include <getopt.h>
static void cpuid(uint32_t idx,
uint32_t *eax,
@@ -66,8 +69,6 @@ static int check_for_xen(int pv_context)
found:
cpuid(base + 1, &eax, &ebx, &ecx, &edx, pv_context);
- printf("Running in %s context on Xen v%d.%d.\n",
- pv_context ? "PV" : "HVM", (uint16_t)(eax >> 16), (uint16_t)eax);
return 1;
}
@@ -77,22 +78,82 @@ void sigill_handler(int sig)
longjmp(sigill_jmp, 1);
}
-int main(void)
+static void usage(void)
{
+ printf("Usage: xen_detect [options]\n");
+ printf("Options:\n");
+ printf(" -h, --help Display this information\n");
+ printf(" -q, --quiet Quiesce normal informational output\n");
+ printf(" -P, --pv Exit status 1 if not running as PV guest\n");
+ printf(" -H, --hvm Exit status 1 if not running as HVM guest.\n");
+ printf(" -N, --none Exit status 1 if running on Xen (PV or HVM)\n");
+}
+
+int main(int argc, char **argv)
+{
+ enum { XEN_PV = 1, XEN_HVM = 2, XEN_NONE = 3 } detected = 0, expected = 0;
+ uint32_t version = 0;
+ int ch, quiet = 0;
+
+ const static char sopts[] = "hqPHN";
+ const static struct option lopts[] = {
+ { "help", 0, NULL, 'h' },
+ { "quiet", 0, NULL, 'q' },
+ { "pv", 0, NULL, 'P' },
+ { "hvm", 0, NULL, 'H' },
+ { "none", 0, NULL, 'N' },
+ { 0, 0, 0, 0}
+ };
+
+ while ( (ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1 )
+ {
+ switch ( ch )
+ {
+ case 'q':
+ quiet = 1;
+ break;
+ case 'P':
+ expected = XEN_PV;
+ break;
+ case 'H':
+ expected = XEN_HVM;
+ break;
+ case 'N':
+ expected = XEN_NONE;
+ break;
+ default:
+ usage();
+ exit(1);
+ }
+ }
+
/* Check for execution in HVM context. */
- if ( check_for_xen(0) )
- return 0;
+ detected = XEN_HVM;
+ if ( (version = check_for_xen(0)) != 0 )
+ goto out;
/*
* Set up a signal handler to test the paravirtualised CPUID instruction.
* If executed outside Xen PV context, the extended opcode will fault, we
* will longjmp via the signal handler, and print "Not running on Xen".
*/
+ detected = XEN_PV;
if ( !setjmp(sigill_jmp)
&& (signal(SIGILL, sigill_handler) != SIG_ERR)
- && check_for_xen(1) )
- return 0;
+ && ((version = check_for_xen(1)) != 0) )
+ goto out;
- printf("Not running on Xen.\n");
- return 0;
+ detected = XEN_NONE;
+
+ out:
+ if ( quiet )
+ /* nothing */;
+ else if ( detected == XEN_NONE )
+ printf("Not running on Xen.\n");
+ else
+ printf("Running in %s context on Xen v%d.%d.\n",
+ (detected == XEN_PV) ? "PV" : "HVM",
+ (uint16_t)(version >> 16), (uint16_t)version);
+
+ return expected && (expected != detected);
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|