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  | 
