How to determine Linux guest VM virtualization technology

last updated in Categories , , , , , , ,

I have a cloud-based virtual machine running Ubuntu and CentOS Linux server. It may or may not be virtualized. How do I determine what kind of virtualization technology (VMWARE/ KVM/ XEN/ VirtualBox/ Container/lxc/Hyper-V etc.) a Linux guest system running on? How do I find out the virtualization type of a CentOS 7 Linux VPS?

You need to use the virt-what program (a shell script) to detect the type of virtualization being used (or none at all if we are running on bare-metal). It prints out one of more lines each being a ‘fact’ about the virtualization. This page explains how to determine Linux guest VM virtualization technology.

ADVERTISEMENTS


Determine Linux guest VM virtualization

As I said earlier, we need to use virt-what Linux command to find if the program is running in a virtual machine or not. It supports various hypervisors. Let us see how to install virt-what under differnet Linux distros.

Debian or Ubuntu Linux instllation

Run the apt command/apt-get command:
$ sudo apt-get install virt-what
OR
$ sudo apt install virt-what

Fig.01: Debian/Ubuntu Linux install virt-what command
Fig.01: Debian/Ubuntu Linux install virt-what command

Installing virt-what on RHEL/CentOS/Scientific Linux VM

Use the yum command:
$ sudo yum install virt-what

Fig.02: Fedora/RHEL/CentOS Linux install virt-what command
Fig.02: Fedora/RHEL/CentOS Linux install virt-what command

Fedora Linux VM install virt-what to detect if we are running in a virtual machine

Execute the dnf command:
$ sudo dnf install virt-what

Suse/OpenSUSE installation

Run the zypper command:
sudo zypper in virt-what
virt-what on opensuse Linux

Check if your remote server runs in virtual environment

Simply type the following command:
$ $ sudo virt-what
xen
xen-domU

Another output:
$ $ sudo virt-what
kvm

Here is one more output:
$ $ sudo virt-what
lxc

This one is from AWS:
$ sudo virt-what
xen
xen-hvm
aws

virt-what running on a CentOS 8
Easy way to determine virtualization technology

Other possible values

  1. hyperv : This is Microsoft Hyper-V hypervisor.
  2. parallels : The guest is running inside Parallels Virtual Platform (Parallels Desktop, Parallels Server).
  3. powervm_lx86 : The guest is running inside IBM PowerVM Lx86 Linux/x86 emulator.
  4. qemu : This is QEMU hypervisor using software emulation.
  5. virtualpc : The guest appears to be running on Microsoft VirtualPC.
  6. xen-hvm : This is a Xen guest fully virtualized (HVM).
  7. uml : This is a User-Mode Linux (UML) guest.
  8. openvz : The guest appears to be running inside an OpenVZ or Virtuozzo container.
  9. linux_vserver : This process is running in a Linux VServer container.
  10. ibm_systemz : This is an IBM SystemZ (or other S/390) hardware partitioning system.

If nothing is printed, then it can mean *either* that the program is running on bare-metal *or* the program is running inside a type of virtual machine which we don’t know about or cannot detect. Here is the source code of the script:

#!/bin/sh -
# virt-what.  Generated from virt-what.in by configure.
# Copyright (C) 2008-2017 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
# 'virt-what' tries to detect the type of virtualization being
# used (or none at all if we're running on bare-metal).  It prints
# out one or more lines each being a 'fact' about the virtualization.
#
# Please see also the manual page virt-what(1).
# This script should be run as root.
#
# The following resources were useful in writing this script:
# . http://dmo.ca/blog/detecting-virtualization-on-linux/
 
# Do not allow unset variables, and set defaults.
set -u
root=''
skip_qemu_kvm=false
skip_lkvm=false
 
VERSION="1.20"
 
have_cpuinfo () {
    test -e "${root}/proc/cpuinfo"
}
 
use_sysctl() {
    # Lacking /proc, on some systems sysctl can be used instead.
    OS=$(uname) || fail "failed to get operating system name"
 
    [ "$OS" = "OpenBSD" ]
}
 
fail () {
    echo "virt-what: $1" >&2
    exit 1
}
 
usage () {
    echo "virt-what [options]"
    echo "Options:"
    echo "  --help          Display this help"
    echo "  --version       Display version and exit"
    exit 0
}
 
# Handle the command line arguments, if any.
while test $# -gt 0; do
    case "$1" in
        --help) usage ;;
        --test-root=*)
            # Deliberately undocumented: used for 'make check'.
            root=$(echo "$1" | sed 's/.*=//')
            shift 1
            test -z "$root" && fail "--test-root option requires a value"
            ;;
        -v|--version) echo "$VERSION"; exit 0 ;;
        --) shift; break ;;
        *) fail "unrecognized option '$1'";;
    esac
done
test $# -gt 0 && fail "extra operand '$1'"
 
# Add /sbin and /usr/sbin to the path so we can find system
# binaries like dmidecode.
# Add /usr/libexec to the path so we can find the helper binary.
prefix=/usr/local
exec_prefix=${prefix}
PATH="${root}${exec_prefix}/libexec:${root}/sbin:${root}/usr/sbin:${PATH}"
export PATH
 
# Check we're running as root.
EFFUID=$(id -u) || fail "failed to get current user id"
 
if [ "x$root" = "x" ] && [ "$EFFUID" -ne 0 ]; then
    fail "this script must be run as root"
fi
 
# Try to locate the CPU-ID helper program
CPUID_HELPER=$(which virt-what-cpuid-helper 2>/dev/null)
if [ -z "$CPUID_HELPER" ] ; then
    fail "virt-what-cpuid-helper program not found in \$PATH"
fi
 
# Many fullvirt hypervisors give an indication through CPUID.  Use the
# helper program to get this information.
 
cpuid=$(virt-what-cpuid-helper)
 
# Check for various products in the BIOS information.
# Note that dmidecode doesn't exist on all architectures.  On the ones
# it does not, then this will return an error, which is ignored (error
# message redirected into the $dmi variable).
 
dmi=$(LANG=C dmidecode 2>&1)
 
# Architecture.
# Note for the purpose of testing, we only call uname with -m option.
 
arch=$(uname -m | sed -e 's/i.86/i386/' | sed -e 's/arm.*/arm/')
 
# Check for VMware.
# cpuid check added by Chetan Loke.
 
if [ "$cpuid" = "VMwareVMware" ]; then
    echo vmware
elif echo "$dmi" | grep -q 'Manufacturer: VMware'; then
    echo vmware
fi
 
# Check for Hyper-V.
# http://blogs.msdn.com/b/sqlosteam/archive/2010/10/30/is-this-real-the-metaphysics-of-hardware-virtualization.aspx
if [ "$cpuid" = "Microsoft Hv" ]; then
    echo hyperv
fi
 
# Check for VirtualPC.
# The negative check for cpuid is to distinguish this from Hyper-V
# which also has the same manufacturer string in the SM-BIOS data.
if [ "$cpuid" != "Microsoft Hv" ] &&
    echo "$dmi" | grep -q 'Manufacturer: Microsoft Corporation'; then
    echo virtualpc
fi
 
# Check for VirtualBox.
# Added by Laurent Léonard.
if echo "$dmi" | grep -q 'Manufacturer: innotek GmbH'; then
    echo virtualbox
fi
 
# Check for bhyve.
if [ "$cpuid" = "bhyve bhyve " ]; then
  echo bhyve
elif echo "$dmi" | grep -q "Vendor: BHYVE"; then
  echo bhyve
fi
 
# Check for OpenVZ / Virtuozzo.
# Added by Evgeniy Sokolov.
# /proc/vz - always exists if OpenVZ kernel is running (inside and outside
# container)
# /proc/bc - exists on node, but not inside container.
 
if [ -d "${root}/proc/vz" -a ! -d "${root}/proc/bc" ]; then
    echo openvz
fi
 
# Check for LXC containers
# http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface
# Added by Marc Fournier
 
if [ -e "${root}/proc/1/environ" ] &&
    cat "${root}/proc/1/environ" | tr '\000' '\n' | grep -Eiq '^container='; then
    echo lxc
fi
 
# Check for Linux-VServer
if test -e "${root}/proc/self/status" \
   && cat "${root}/proc/self/status" | grep -q "VxID: [0-9]*"; then
    echo linux_vserver
    if grep -q "VxID: 0$" "${root}/proc/self/status"; then
        echo linux_vserver-host
    else
        echo linux_vserver-guest
    fi
fi
 
# Check for UML.
# Added by Laurent Léonard.
if have_cpuinfo && grep -q 'UML' "${root}/proc/cpuinfo"; then
    echo uml
fi
 
# Check for IBM PowerVM Lx86 Linux/x86 emulator.
if have_cpuinfo && grep -q '^vendor_id.*PowerVM Lx86' "${root}/proc/cpuinfo"
then
    echo powervm_lx86
fi
 
# Check for Hitachi Virtualization Manager (HVM) Virtage logical partitioning.
if echo "$dmi" | grep -q 'Manufacturer.*HITACHI' &&
   echo "$dmi" | grep -q 'Product.* LPAR'; then
    echo virtage
fi
 
# Check for IBM SystemZ.
if have_cpuinfo && grep -q '^vendor_id.*IBM/S390' "${root}/proc/cpuinfo"; then
    echo ibm_systemz
    if [ -f "${root}/proc/sysinfo" ]; then
        if grep -q 'VM.*Control Program.*KVM/Linux' "${root}/proc/sysinfo"; then
            echo ibm_systemz-kvm
        elif grep -q 'VM.*Control Program.*z/VM' "${root}/proc/sysinfo"; then
            echo ibm_systemz-zvm
        elif grep -q '^LPAR' "${root}/proc/sysinfo"; then
            echo ibm_systemz-lpar
        else
            # This is unlikely to be correct.
            echo ibm_systemz-direct
        fi
    fi
fi
 
# Check for Parallels.
if echo "$dmi" | grep -q 'Vendor: Parallels'; then
    echo parallels
    skip_qemu_kvm=true
fi
 
# Check for oVirt/RHEV.
if echo "$dmi" | grep -q 'Manufacturer: oVirt'; then
    echo ovirt
fi
if echo "$dmi" | grep -q 'Product Name: RHEV Hypervisor'; then
    echo rhev
fi
 
# Check for Xen.
 
if [ "$cpuid" = "XenVMMXenVMM" ] &&
    ! echo "$dmi" | grep -q 'No SMBIOS nor DMI entry point found, sorry'; then
    echo xen; echo xen-hvm
    skip_qemu_kvm=true
elif [ -d "${root}/proc/xen" ]; then
    echo xen
    if grep -q "control_d" "${root}/proc/xen/capabilities" 2>/dev/null; then
        echo xen-dom0
    else
        echo xen-domU
    fi
    skip_qemu_kvm=true
    skip_lkvm=true
elif [ -f "${root}/sys/hypervisor/type" ] &&
    grep -q "xen" "${root}/sys/hypervisor/type"; then
    # Ordinary kernel with pv_ops.  There does not seem to be
    # enough information at present to tell whether this is dom0
    # or domU.  XXX
    echo xen
elif [ "$arch" = "arm" ] || [ "$arch" = "aarch64" ]; then
    if [ -d "${root}/proc/device-tree/hypervisor" ] &&
        grep -q "xen" "${root}/proc/device-tree/hypervisor/compatible"; then
        echo xen
        skip_qemu_kvm=true
        skip_lkvm=true
    fi
elif [ "$arch" = "ia64" ]; then
    if [ -d "${root}/sys/bus/xen" -a ! -d "${root}/sys/bus/xen-backend" ]; then
        # PV-on-HVM drivers installed in a Xen guest.
        echo xen
        echo xen-hvm
    else
        # There is no virt leaf on IA64 HVM.  This is a last-ditch
        # attempt to detect something is virtualized by using a
        # timing attack.
        virt-what-ia64-xen-rdtsc-test > /dev/null 2>&1
        case "$?" in
            0) ;; # not virtual
            1) # Could be some sort of virt, or could just be a bit slow.
                echo virt
        esac
    fi
fi
 
# Check for QEMU/KVM.
#
# Parallels exports KVMKVMKVM leaf, so skip this test if we've already
# seen that it's Parallels.  Xen uses QEMU as the device model, so
# skip this test if we know it is Xen.
 
if ! "$skip_qemu_kvm"; then
    if [ "$cpuid" = "KVMKVMKVM" ]; then
        echo kvm
    elif [ "$cpuid" = "TCGTCGTCGTCG" ]; then
        echo qemu
        skip_lkvm=true
    elif echo "$dmi" | grep -q 'Product Name: KVM'; then
        echo kvm
        skip_lkvm=true
    elif echo "$dmi" | grep -q 'Manufacturer: QEMU'; then
        # The test for KVM above failed, so now we know we're
        # not using KVM acceleration.
        echo qemu
        skip_lkvm=true
    elif [ "$arch" = "arm" ] || [ "$arch" = "aarch64" ]; then
        if [ -d "${root}/proc/device-tree" ] &&
            ls "${root}/proc/device-tree" | grep -q "fw-cfg"; then
            # We don't have enough information to determine if we're
            # using KVM acceleration or not.
            echo qemu
            skip_lkvm=true
        fi
    elif [ -d ${root}/proc/device-tree/hypervisor ] &&
         grep -q "linux,kvm" /proc/device-tree/hypervisor/compatible; then
        # We are running as a spapr KVM guest on ppc64
        echo kvm
        skip_lkvm=true
    elif use_sysctl; then
        # SmartOS KVM
        product=$(sysctl -n hw.product)
        if echo "$product" | grep -q 'SmartDC HVM'; then
            echo kvm
        fi
    else
        # This is known to fail for qemu with the explicit -cpu
        # option, since /proc/cpuinfo will not contain the QEMU
        # string. QEMU 2.10 added a new CPUID leaf, so this
        # problem only triggered for older QEMU
        if have_cpuinfo && grep -q 'QEMU' "${root}/proc/cpuinfo"; then
            echo qemu
        fi
    fi
fi
 
if ! "$skip_lkvm"; then
    if [ "$cpuid" = "LKVMLKVMLKVM" ]; then
        echo lkvm
    elif [ "$arch" = "arm" ] || [ "$arch" = "aarch64" ]; then
        if [ -d "${root}/proc/device-tree" ] &&
            grep -q "dummy-virt" "${root}/proc/device-tree/compatible"; then
            echo lkvm
        fi
    fi
fi
 
# Check for Docker.
if [ -f "${root}/.dockerinit" ]; then
    echo docker
fi
 
# Check ppc64 lpar, kvm or powerkvm
 
# example /proc/cpuinfo line indicating 'not baremetal'
# platform  : pSeries
#
# example /proc/ppc64/lparcfg systemtype line
# system_type=IBM pSeries (emulated by qemu)
 
if [ "$arch" = "ppc64" ] || [ "$arch" = "ppc64le" ] ; then
    if have_cpuinfo && grep -q 'platform.**pSeries' "${root}/proc/cpuinfo"; then
        if grep -q 'model.*emulated by qemu' "${root}/proc/cpuinfo"; then
                echo ibm_power-kvm
        else
            # Assume LPAR, now detect shared or dedicated
            if grep -q 'shared_processor_mode=1' "${root}/proc/ppc64/lparcfg"; then
                echo ibm_power-lpar_shared
            else
                echo ibm_power-lpar_dedicated
            fi
        # detect powerkvm?
        fi
    fi
fi
 
# Check for OpenBSD/VMM
if [ "$cpuid" = "OpenBSDVMM58" ]; then
        echo vmm
fi
 
# Check for LDoms
if [ "${arch#sparc}" != "$arch" ] && [ -e "${root}/dev/mdesc" ]; then
    echo ldoms
    if [ -d "${root}/sys/class/vlds/ctrl" ] && \
             [ -d "${root}/sys/class/vlds/sp" ]; then
        echo ldoms-control
    else
        echo ldoms-guest
    fi
    MDPROP="${root}/usr/lib/ldoms/mdprop.py"
    if [ -x "${MDPROP}" ]; then
        if [ -n "$($MDPROP -v iodevice device-type=pciex)" ]; then
            echo ldoms-root
            echo ldoms-io
        elif [ -n "$($MDPROP -v iov-device vf-id=0)" ]; then
            echo ldoms-io
        fi
    fi
fi
 
# Check for AWS.
# AWS on Xen.
if echo "$dmi" | grep -q 'Version: [0-9]\.[0-9]\.amazon'; then
    echo aws
# AWS on baremetal or KVM.
elif echo "$dmi" | grep -q 'Vendor: Amazon EC2'; then
    echo aws
fi

How to use dmidecode command to find out same info

Use bash for loop as follows along with the dmidecode command:

for i in system-manufacturer system-product-name
do 
  sudo dmidecode -s $i
done

Sample outputs:

Red Hat
KVM

Other commands to determine virtualization technology

We can use the systemd-detect-virt command to detect execution in a virtualized environment:
systemd-detect-virt

systemd-detect-virt detects execution in a virtualized environment
Known virtualization technologies (both VM, i.e. full hardware virtualization, and container, i.e. shared kernel virtualization)

Conclusion

We learned how to detect if we are running in a virtual machine or not using the virt-what command. See and download source code here.

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.


ADVERTISEMENTS

7 comment

  1. Hi Vivek,

    You have missed to comment one of the main players in the game: “VMware”. I was looking for the detection of VMware but you did not comment on it on the article. I had to read the script to realize it is detected as well.

    By the way, nice post. and absolutely fantastic blog.

  2. It’s appeared on my EL5 and EL6 systems for the past few years as part of default installations. Ubuntu has it, and the source is available as well. In “recent” linux kernels, the kernel detects the hypervisor for you and prints a message that is easily available with

  3. It might be possible for your code to see what sort of virtualisation it could set up. If that fails entirely, you might be in a VM. But you just as might easily be on a box that doesn’t have any VM capable hardware.

Leave a Comment