X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Fvirt.c;h=54c465520d86dee05cc0af26b496d4fe7f106ff8;hb=7b061de2d0601a33f7246c4b909f30ddc44d7ab6;hp=f10baab40bc0ccbc0620930e467f0ffc6d4908b4;hpb=536bfdab4cca38916ec8b112a6f80b0c068cc806;p=elogind.git diff --git a/src/shared/virt.c b/src/shared/virt.c index f10baab40..54c465520 100644 --- a/src/shared/virt.c +++ b/src/shared/virt.c @@ -101,6 +101,42 @@ static int detect_vm_cpuid(const char **_id) { return 0; } +static int detect_vm_devicetree(const char **_id) { +#if defined(__arm__) || defined(__aarch64__) || defined(__powerpc__) || defined(__powerpc64__) + _cleanup_free_ char *hvtype = NULL; + int r; + + r = read_one_line_file("/proc/device-tree/hypervisor/compatible", &hvtype); + if (r >= 0) { + if (streq(hvtype, "linux,kvm")) { + *_id = "kvm"; + return 1; + } else if (strstr(hvtype, "xen")) { + *_id = "xen"; + return 1; + } + } else if (r == -ENOENT) { + _cleanup_closedir_ DIR *dir = NULL; + struct dirent *dent; + + dir = opendir("/proc/device-tree"); + if (!dir) { + if (errno == ENOENT) + return 0; + return -errno; + } + + FOREACH_DIRENT(dent, dir, return -errno) { + if (strstr(dent->d_name, "fw-cfg")) { + *_id = "qemu"; + return 1; + } + } + } +#endif + return 0; +} + static int detect_vm_dmi(const char **_id) { /* Both CPUID and DMI are x86 specific interfaces... */ @@ -204,6 +240,10 @@ int detect_vm(const char **id) { if (r != 0) goto finish; + r = detect_vm_devicetree(&_id); + if (r != 0) + goto finish; + if (_id) { /* "other" */ r = 1;