diff options
-rw-r--r-- | src/pulsecore/core-util.c | 87 | ||||
-rw-r--r-- | src/pulsecore/core-util.h | 3 |
2 files changed, 90 insertions, 0 deletions
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 8e98e857..11e3d696 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -2867,3 +2867,90 @@ const char *pa_get_temp_dir(void) { return "/tmp"; } + +char *pa_read_line_from_file(const char *fn) { + FILE *f; + char ln[256] = "", *r; + + if (!(f = fopen(fn, "r"))) + return NULL; + + r = fgets(ln, sizeof(ln)-1, f); + fclose(f); + + if (!r) { + errno = EIO; + return NULL; + } + + pa_strip_nl(ln); + return pa_xstrdup(ln); +} + +pa_bool_t pa_running_in_vm(void) { + +#if defined(__i386__) || defined(__x86_64__) + + /* Both CPUID and DMI are x86 specific interfaces... */ + + uint32_t eax = 0x40000000; + union { + uint32_t sig32[3]; + char text[13]; + } sig; + +#ifdef __linux__ + const char *const dmi_vendors[] = { + "/sys/class/dmi/id/sys_vendor", + "/sys/class/dmi/id/board_vendor", + "/sys/class/dmi/id/bios_vendor" + }; + + unsigned i; + + for (i = 0; i < PA_ELEMENTSOF(dmi_vendors); i++) { + char *s; + + if ((s = pa_read_line_from_file(dmi_vendors[i]))) { + + if (pa_startswith(s, "QEMU") || + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + pa_startswith(s, "VMware") || + pa_startswith(s, "VMW") || + pa_startswith(s, "Microsoft Corporation") || + pa_startswith(s, "innotek GmbH") || + pa_startswith(s, "Xen")) { + + pa_xfree(s); + return TRUE; + } + + pa_xfree(s); + } + } + +#endif + + /* http://lwn.net/Articles/301888/ */ + pa_zero(sig); + + __asm__ __volatile__ ( + " xor %%ebx, %%ebx \n\t" + " cpuid \n\t" + + : "=a" (eax), "=b" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2]) + : "0" (eax) + ); + + if (pa_streq(sig.text, "XenVMMXenVMM") || + pa_streq(sig.text, "KVMKVMKVM") || + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + pa_streq(sig.text, "VMwareVMware") || + /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */ + pa_streq(sig.text, "Microsoft Hv")) + return TRUE; + +#endif + + return FALSE; +} diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h index 84752d4d..eba1b404 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -251,4 +251,7 @@ pa_bool_t pa_run_from_build_tree(void); const char *pa_get_temp_dir(void); +char *pa_read_line_from_file(const char *fn); +pa_bool_t pa_running_in_vm(void); + #endif |