How I dealt with KVM host identification

Recently I started researching how a KVM guest could tell who it’s host is. I dug into the KVM code and found in r77 there’s new functionality to pass -uuid on the command line on the host and access it from the qemu monitor. KVM-78 should have bios modifications such that ‘dmidecode’ will return this uuid if passed as well. As noted in that last link, libvirt doesn’t support that yet. Although it’s a trivial change I can’t really wait for all this stuff, nor do I want to take the time to package it.

The existing vmport code in qemu, best I can tell, is used mostly for some vmmouse stuff. I can’t find anywhere than anyone actually uses it. I don’t want to write code to start poking around memory holes, so I threw out the idea of prodding around there.

In the end, I used my infrastructure, again. kvm/libvirt hosts report their guests to iclassify based on hostname:

#!/usr/bin/ruby -w
# This is an iclassify script for updating a libvirt (KVM) host with the list of guests
# Until KVM guests can access their UUID, this will rely on hostname being unique
# 2008-10-28 -- Bryan McLellan 

def update_guests
  local_guests = Array.new
  server_guests = Array.new

  # Get the list of current guest hostnames
  %x[virsh list --all 2>/dev/null].each { |line|

    # ignore header lines, match lines that start with a number ID, grab hostname from second column
    if row = line.match(/^\s+\d+\s+(\S+)/)
      local_guests << row[1]
    end
  }

  unless local_guests.empty?
	  # update the array, and try to give it a break if it's the same
	  server_guests = attrib?("guest-hostname")
	  replace_attrib("guest-hostname", local_guests) unless server_guests == local_guests
  end

end 

if tag?("kvm")
  update_guests
end

Then I could modify my ruby script that displays virt server status, originally written when I was using just vmware servers, to also show kvm/libvirt hosts:

client = IClassify::Client.new(config[:server], config[:user], config[:passwd])

vmwarehosts = client.search('(tag:vmware-server OR tag:kvm) AND NOT tag:workstation', [])

vmwarehosts.sort_by { |node| node.description }.each do |node|

  puts node.description
  puts "\tmemory free/total: " + node.attrib?('memoryfree').gsub!(/[^0-9.]/,"") + "/" + node.attrib?('memorysize') \
    + "\tswap free/total: " + node.attrib?('swapfree').gsub!(/[^0-9.]/,"") + "/" + node.attrib?('swapsize')
  print "\tguests: "

  # remember that node.description and friends aren't always clean
  guests = client.search("vmwarehost:#{node.attrib?('hostname')}", [])
  guests.sort_by { |node| node.description }.each do |guest|
    print "#{guest.attrib?('hostname')} "

  end
  if node.attrib?("guest-hostname")
    node.attrib?("guest-hostname").each { |guest| print "#{guest} " }
  end
  puts "\n"
end

And I guess that works for me for now. Later it’ll be nice to use the host and guests’s real UUID as the iclassify uuid. That’s a project for another day.

One thought on “How I dealt with KVM host identification

  1. Pingback: Chef 0.5.2 and Ohai 0.1.4 released at btm.geek

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.