diff options
| author | Lennart Poettering <lennart@poettering.net> | 2009-11-05 03:22:15 +0100 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2009-11-05 03:22:15 +0100 | 
| commit | 642c69bed85ce7c0be57bd08af0cf7243228f08b (patch) | |
| tree | db56d77e019816da0f1718eaf759d0c349343989 | |
| parent | 19516d4e7f4b6db205681931ad1c4bc1b6bef363 (diff) | |
core-util: add call to detect if we are called from within a VM
| -rw-r--r-- | src/pulsecore/core-util.c | 89 | ||||
| -rw-r--r-- | src/pulsecore/core-util.h | 3 | 
2 files changed, 92 insertions, 0 deletions
| diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 2b0a60a8..93ddf301 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -2944,6 +2944,7 @@ int pa_pipe_cloexec(int pipefd[2]) {      if (errno != EINVAL && errno != ENOSYS)          return r; +  #endif      if ((r = pipe(pipefd)) < 0) @@ -2965,6 +2966,7 @@ int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {      if (errno != EINVAL && errno != ENOSYS)          return fd; +  #endif      if ((fd = accept(sockfd, addr, addrlen)) < 0) @@ -3015,3 +3017,90 @@ void pa_nullify_stdfds(void) {  #endif  } + +char *pa_read_line_from_file(const char *fn) { +    FILE *f; +    char ln[256] = "", *r; + +    if (!(f = pa_fopen_cloexec(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 9c9cf78a..31a83bcc 100644 --- a/src/pulsecore/core-util.h +++ b/src/pulsecore/core-util.h @@ -267,4 +267,7 @@ FILE* pa_fopen_cloexec(const char *path, const char *mode);  void pa_nullify_stdfds(void); +char *pa_read_line_from_file(const char *fn); +pa_bool_t pa_running_in_vm(void); +  #endif | 
