diff options
-rw-r--r-- | src/readahead-collect.c | 5 | ||||
-rw-r--r-- | src/readahead-replay.c | 5 | ||||
-rw-r--r-- | src/util.c | 76 | ||||
-rw-r--r-- | src/util.h | 2 |
4 files changed, 88 insertions, 0 deletions
diff --git a/src/readahead-collect.c b/src/readahead-collect.c index ac46c7b3ea..4ca6d74726 100644 --- a/src/readahead-collect.c +++ b/src/readahead-collect.c @@ -649,6 +649,11 @@ int main(int argc, char *argv[]) { return 0; } + if (running_in_vm()) { + log_info("Disabling readahead collector due to execution in virtual machine."); + return 0; + } + if (!(shared = shared_get())) return 1; diff --git a/src/readahead-replay.c b/src/readahead-replay.c index 87f2e598b4..e9c573a593 100644 --- a/src/readahead-replay.c +++ b/src/readahead-replay.c @@ -346,6 +346,11 @@ int main(int argc, char*argv[]) { return 0; } + if (running_in_vm()) { + log_info("Disabling readahead replay due to execution in virtual machine."); + return 0; + } + if (!(shared = shared_get())) return 1; diff --git a/src/util.c b/src/util.c index 7692a2d620..09c13143c6 100644 --- a/src/util.c +++ b/src/util.c @@ -3564,6 +3564,82 @@ const char *default_term_for_tty(const char *tty) { return "TERM=vt100"; } +bool running_in_vm(void) { + +#if defined(__i386__) || defined(__x86_64__) + + /* Both CPUID and DMI are x86 specific interfaces... */ + + const char *const dmi_vendors[] = { + "/sys/class/dmi/id/sys_vendor", + "/sys/class/dmi/id/board_vendor", + "/sys/class/dmi/id/bios_vendor" + }; + + uint32_t eax = 0x40000000; + union { + uint32_t sig32[3]; + char text[13]; + } sig; + + unsigned i; + + for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { + char *s; + bool b; + + if (read_one_line_file(dmi_vendors[i], &s) < 0) + continue; + + b = startswith(s, "QEMU") || + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + startswith(s, "VMware") || + startswith(s, "VMW") || + startswith(s, "Microsoft Corporation") || + startswith(s, "innotek GmbH") || + startswith(s, "Xen"); + + free(s); + + if (b) + return true; + } + + /* http://lwn.net/Articles/301888/ */ + zero(sig); + + +#if defined (__i386__) +#define REG_a "eax" +#define REG_b "ebx" +#elif defined (__amd64__) +#define REG_a "rax" +#define REG_b "rbx" +#endif + + __asm__ __volatile__ ( + /* ebx/rbx is being used for PIC! */ + " push %%"REG_b" \n\t" + " cpuid \n\t" + " mov %%ebx, %1 \n\t" + " pop %%"REG_b" \n\t" + + : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2]) + : "0" (eax) + ); + + if (streq(sig.text, "XenVMMXenVMM") || + streq(sig.text, "KVMKVMKVM") || + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + streq(sig.text, "VMwareVMware") || + /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */ + streq(sig.text, "Microsoft Hv")) + return true; +#endif + + return false; +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime", diff --git a/src/util.h b/src/util.h index c8cae703a2..3f0f48f32d 100644 --- a/src/util.h +++ b/src/util.h @@ -372,6 +372,8 @@ void filter_environ(const char *prefix); const char *default_term_for_tty(const char *tty); +bool running_in_vm(void); + #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) |