How to Programmatically Identify KVM Hypervisor Hostname/IP from Guest VM using Libvirt APIs


5 views

In managed KVM environments with multiple hypervisor hosts, administrators often need to trace VM-to-host relationships. While inventory systems track this mapping, programmatic discovery from within VMs provides valuable redundancy.

The most reliable approach involves configuring the libvirt guest agent:


# On hypervisor (host):
<devices>
  <channel type='unix'>
    <source mode='bind'/>
    <target type='virtio' name='org.qemu.guest_agent.0'/>
  </channel>
</devices>

# Inside guest VM (requires guest agent installation):
virsh domhostname $(hostname)

Hypervisors can inject host information through SMBIOS:


# Hypervisor configuration:
<os>
  <smbios mode='sysinfo'/>
</os>
<sysinfo type='smbios'>
  <system>
    <entry name='manufacturer'>Host01.example.com</entry>
  </system>
</sysinfo>

# Retrieving from guest (Linux):
dmidecode -s system-manufacturer

For environments with consistent networking:


# Using reverse DNS on default gateway:
ip route | awk '/default/ {print $3}' | xargs dig +short -x

# Alternative ARP approach (requires host in same subnet):
arp -an | grep $(ip route | awk '/default/ {print $3}')

Advanced solution using cloud-init or custom virtio channels:


# Hypervisor configuration:
<metadata>
  <hostinfo xmlns="http://example.com/xmlns/hostinfo">
    <hostname>phx-kvm-rack3-12</hostname>
    <management_ip>10.5.12.34</management_ip>
  </hostinfo>
</metadata>

# Parsing with xmllint:
virsh dumpxml $(hostname) | xmllint --xpath '//hostinfo/hostname' -

While these methods provide operational convenience, consider:

  • Restricting guest agent socket permissions
  • Using read-only channels for metadata
  • Implementing network segmentation

When managing large-scale KVM deployments, administrators often need to trace virtual machines back to their physical hosts. While cloud platforms typically provide metadata services, traditional KVM environments require more creative solutions.

Many hypervisors expose host information through the DMI tables. Try:

sudo dmidecode -s system-manufacturer
sudo dmidecode -s system-product-name
sudo dmidecode -s system-serial-number

Some KVM hosts configure custom values in these fields that may contain host identifiers.

If you have libvirt tools installed in the guest:

sudo virsh dumpxml $(hostname) | grep -i 'source host'
# Sample output might show:
# <source host='hypervisor01.example.com' port='16509'/>

Check default gateway or neighboring systems:

ip route show default
arp -an
# The hypervisor often appears as the gateway or nearby neighbor

Configure your hypervisors to pass host information via kernel cmdline:

# On host during VM creation:
virt-install ... --extra-args="hypervisor_host=hv01.example.com"

# Inside guest check with:
cat /proc/cmdline | grep -o 'hypervisor_host=[^ ]*'

With the guest agent running and properly configured:

sudo virsh qemu-agent-command $(hostname) '{"execute":"guest-info"}' 
# May return host connection details in the response

Create a service that collects host information at boot:

# /etc/systemd/system/hypervisor-id.service
[Unit]
Description=Collect Hypervisor Information
After=network.target

[Service]
ExecStart=/usr/bin/bash -c 'echo "Hypervisor: $(dmidecode -s system-manufacturer)" > /var/run/hypervisor.info'
ExecStartPost=/usr/bin/bash -c 'ip route show default | grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" >> /var/run/hypervisor.info'

[Install]
WantedBy=multi-user.target

While these methods work in trusted environments, consider:

  • Restricting DMI information exposure via libvirt XML
  • Using separate management networks
  • Implementing proper authentication for guest agent access

Configure all hypervisors to inject their hostname into VM serial consoles:

<serial type='pty'>
  <source path='/dev/hypervisor/hv01'/>
  <target port='0'/>
</serial>

Then parse from within the guest using terminal emulation tools.