diff options
author | Ruediger Meier | 2014-05-20 13:26:48 +0200 |
---|---|---|
committer | Ruediger Meier | 2014-05-29 13:16:32 +0200 |
commit | 5bd31c6d6e1e77c2843505601ee6cbb58ac74e9c (patch) | |
tree | 360186a54d6ab199490e473369f14fa5562496d2 /sys-utils | |
parent | tests: add vbox lscpu dump (diff) | |
download | kernel-qcow2-util-linux-5bd31c6d6e1e77c2843505601ee6cbb58ac74e9c.tar.gz kernel-qcow2-util-linux-5bd31c6d6e1e77c2843505601ee6cbb58ac74e9c.tar.xz kernel-qcow2-util-linux-5bd31c6d6e1e77c2843505601ee6cbb58ac74e9c.zip |
lscpu: detect OS/400 and pHyp hypervisors
This patch comes originally from openSUSE / SLE. Author was probably
Petr Uzel.
Internal SUSE references: fate310255, sr226509
In comparison to the original patch we have slightly corrected iSeries
and pSeries detection according to Alexander Graf's comments on
util-linux@vger.kernel.org. Maybe we would need to add some more code
to detect pSeries emulated by Qemu/KVM.
CC: Stanislav Brabec <sbrabec@suse.cz>
CC: Petr Uzel <petr.uzel@suse.cz>
CC: Alexander Graf <agraf@suse.de>
Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
Diffstat (limited to 'sys-utils')
-rw-r--r-- | sys-utils/lscpu.c | 61 | ||||
-rw-r--r-- | sys-utils/lscpu.h | 2 |
2 files changed, 63 insertions, 0 deletions
diff --git a/sys-utils/lscpu.c b/sys-utils/lscpu.c index 7203d0d7b..11224b0bc 100644 --- a/sys-utils/lscpu.c +++ b/sys-utils/lscpu.c @@ -19,6 +19,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <assert.h> #include <ctype.h> #include <dirent.h> #include <errno.h> @@ -60,6 +61,7 @@ #define _PATH_PROC_STATUS "/proc/self/status" #define _PATH_PROC_VZ "/proc/vz" #define _PATH_PROC_BC "/proc/bc" +#define _PATH_PROC_DEVICETREE "/proc/device-tree" #define _PATH_DEV_MEM "/dev/mem" /* virtualization types */ @@ -89,6 +91,8 @@ const char *hv_vendors[] = { [HYPER_HITACHI] = "Hitachi", [HYPER_PARALLELS] = "Parallels", [HYPER_VBOX] = "Oracle", + [HYPER_OS400] = "OS/400", + [HYPER_PHYP] = "pHyp", }; const int hv_vendor_pci[] = { @@ -577,6 +581,61 @@ read_hypervisor_cpuid(struct lscpu_desc *desc __attribute__((__unused__))) } #endif +static int +read_hypervisor_powerpc(struct lscpu_desc *desc) +{ + assert(!desc->hyper); + + /* powerpc: + * IBM iSeries: legacy, if /proc/iSeries exists, its para-virtualized on top of OS/400 + * IBM pSeries: always has a hypervisor + * if partition-name is "full", its kind of "bare-metal": full-system-partition + * otherwise its some partition created by Hardware Management Console + * in any case, its always some sort of HVM + * Note that pSeries could also be emulated by qemu/KVM. + * KVM: "linux,kvm" in /hypervisor/compatible indicates a KVM guest + * Xen: not in use, not detected + */ + if (path_exist("/proc/iSeries")) { + desc->hyper = HYPER_OS400; + desc->virtype = VIRT_PARA; + } else if (path_exist(_PATH_PROC_DEVICETREE "/ibm,partition-name") + && path_exist(_PATH_PROC_DEVICETREE "/hmc-managed?") + && !path_exist(_PATH_PROC_DEVICETREE "/chosen/qemu,graphic-width")) { + FILE *fd; + desc->hyper = HYPER_PHYP; + desc->virtype = VIRT_PARA; + fd = path_fopen("r", 0, _PATH_PROC_DEVICETREE "/ibm,partition-name"); + if (fd) { + char buf[256]; + if (fscanf(fd, "%s", buf) == 1 && !strcmp(buf, "full")) + desc->virtype = VIRT_NONE; + fclose(fd); + } + } else if (path_exist(_PATH_PROC_DEVICETREE "/hypervisor/compatible")) { + FILE *fd; + fd = path_fopen("r", 0, _PATH_PROC_DEVICETREE "/hypervisor/compatible"); + if (fd) { + char buf[256]; + size_t i, len; + memset(buf, 0, sizeof(buf)); + len = fread(buf, 1, sizeof(buf) - 1, fd); + fclose(fd); + for (i = 0; i < len;) { + if (!strcmp(&buf[i], "linux,kvm")) { + desc->hyper = HYPER_KVM; + desc->virtype = VIRT_FULL; + break; + } + i += strlen(&buf[i]); + i++; + } + } + } + + return desc->hyper; +} + static void read_hypervisor(struct lscpu_desc *desc, struct lscpu_modifier *mod) { @@ -591,6 +650,8 @@ read_hypervisor(struct lscpu_desc *desc, struct lscpu_modifier *mod) if (desc->hyper) desc->virtype = VIRT_FULL; + else if (read_hypervisor_powerpc(desc) > 0) {} + /* Xen para-virt or dom0 */ else if (path_exist(_PATH_PROC_XEN)) { int dom0 = 0; diff --git a/sys-utils/lscpu.h b/sys-utils/lscpu.h index 5dc965001..e34029194 100644 --- a/sys-utils/lscpu.h +++ b/sys-utils/lscpu.h @@ -15,6 +15,8 @@ enum { HYPER_HITACHI, HYPER_PARALLELS, /* OpenVZ/VIrtuozzo */ HYPER_VBOX, + HYPER_OS400, + HYPER_PHYP, }; extern int read_hypervisor_dmi(void); |