diff --git a/src/database.py b/src/database.py
index ea0e7bc5d5e158bec51c7c9e93a27f918a264aca..4758c9c7fac8b31a337c4de965c667557aede0fc 100644
--- a/src/database.py
+++ b/src/database.py
@@ -1,6 +1,7 @@
+import collections
 import util
+import vm
 import mount
-import collections
 
 class DataBase:
 
@@ -18,7 +19,8 @@ class DataBase:
             else:
                 vms = util.get_vms(db)
                 pass
-            vm = dict(map(lambda vm: (vm.name, vm), vms))
-            return collections.OrderedDict([ (n,vm[n]) for n in sorted(vm)])
+            vm_dict = dict(map(lambda vm_elem: (vm_elem.name, vm_elem), vms))
+            return collections.OrderedDict([ (n,vm_dict[n]) for n in sorted(vm_dict)])
         self.vms = util.FutureCache(vms, self)
+        self.hypervisors = vm.get_hypervisors(self)
         self.mount = util.FutureCache(mount.get_active_mounts)
diff --git a/src/hostinfo-libvirt.py b/src/hostinfo-libvirt.py
index a927c5a90cfca39cc83c2f71a560fbdbfad5eeb5..968abcb13c65b384f0e49c8d09f4f931c3129699 100644
--- a/src/hostinfo-libvirt.py
+++ b/src/hostinfo-libvirt.py
@@ -148,8 +148,10 @@ if __name__ == '__main__':
             setattr(options, attr, set(o))
         pass
 
-    options.physical_disks = dict([tuple(d.split(':')) for d in set(options.physical_disks)])
-    options.physical_disk_paths = dict([tuple(d.split(':')) for d in set(options.physical_disk_paths)])
+    options.physical_disks = dict([tuple(d.split(':'))
+                                   for d in set(options.physical_disks)])
+    options.physical_disk_paths = dict([tuple(d.split(':'))
+                                        for d in set(options.physical_disk_paths)])
     tree = parser.parse(options.hostinfo)
 
     db = database.DataBase(tree, options)
diff --git a/src/util.py b/src/util.py
index 497bd4b7cc8ceafb518fb4d0dead9228c039be2a..5d19c66cef5be1f684dd7647c698235a19139b60 100644
--- a/src/util.py
+++ b/src/util.py
@@ -1,4 +1,5 @@
 import os
+import calendar
 import ipaddress
 import subprocess
 import re
@@ -7,6 +8,7 @@ import collections
 import uuid
 import time
 from hashlib import sha512
+import parser
 
 NFS_POOL = '/var/lib/libvirt/images-nfs'
 NFS_ROOT = '/var/lib/libvirt/images-nfs-mount'
@@ -83,6 +85,12 @@ class FutureCache:
             pass
         return self._cache[key]
 
+    def __bool__(self):
+        if self._cache == None:
+            self._cache = self._func(*self._args)
+            pass
+        return bool(self._cache)
+
     def __len__(self):
         if self._cache == None:
             self._cache = self._func(*self._args)
@@ -163,18 +171,33 @@ class VirtualMachine:
         self.db = db
         self.qemu = qemu
         self.netgroups = netgroups
+        self.correct = True
         if db.option.virtualize_physical:
             self.name = qemu.name[0]
-            self.memory = db.option.physical_ram
-            self.arch = db.option.physical_arch
-            self.machine_type = db.option.physical_machine_type
-            self.cpu_model = db.option.physical_model
-            self.cpus = db.option.physical_cores
+            self.physical = True
             encoded_name = self.name.encode('utf-8')
             name_hash = sha512(encoded_name).digest()
             hypervisor_index = (int.from_bytes(name_hash) %
                                 len(db.option.check_hypervisor))
             self.host = list(sorted(db.option.check_hypervisor))[hypervisor_index]
+
+            if not db.option.create:
+                if (self.host not in db.hypervisors or
+                    self.name not in db.hypervisors[self.host].domain):
+                    self.correct = False
+                    return
+                dom = db.hypervisors[self.host].domain[self.name].inactive
+                hostinfo = dom._metadata_[0]._child("control.lth.se:hostinfo")[0]
+                qemu._add(hostinfo._host_[0]._qemu_[0])
+                pass
+            pass
+
+        if db.option.virtualize_physical and db.option.create:
+            self.memory = db.option.physical_ram
+            self.arch = db.option.physical_arch
+            self.machine_type = db.option.physical_machine_type
+            self.cpu_model = db.option.physical_model
+            self.cpus = db.option.physical_cores
             uuid_seed=(int.from_bytes(encoded_name)
                        + int.from_bytes(self.memory.encode('utf-8'))
                        + int.from_bytes(self.arch.encode('utf-8'))
@@ -189,24 +212,48 @@ class VirtualMachine:
                 uuid_seed = uuid_seed >> (uuid_seed.bit_length() - 128)
                 pass
             self.uuid = str(uuid.UUID(version=4, int=uuid_seed))
+
+            attr = {
+                'arch': self.arch,
+                'cpus': self.cpus,
+                'cpu_model': self.cpu_model,
+                'memory': self.memory,
+                'uuid': self.uuid,
+                }
+            qemusubtag = parser.Node("qemu", None, attr)
+            qemu._add(qemusubtag)
             pass
         else:
-            self.name = qemu.name[1]
-            self.memory = qemu.memory[0]
-            self.arch = qemu.arch[0]
-            self.machine_type = qemu.machine[0]
-            self.cpu_model = qemu.cpu_model[0]
-            self.cpus = qemu.cpus[0]
-            self.uuid = qemu.uuid[0]
-            pass
-        def disk():
+            qemu_tag = qemu._qemu_[0] if db.option.virtualize_physical else qemu
+            self.name = qemu_tag.name[1]
+            self.memory = qemu_tag.memory[0]
+            self.arch = qemu_tag.arch[0]
+            self.machine_type = qemu_tag.machine[0]
+            self.cpu_model = qemu_tag.cpu_model[0]
+            self.cpus = qemu_tag.cpus[0]
+            self.physical = False
+            self.uuid = qemu_tag.uuid[0]
+            pass
+        def regular_disks(disk_tree):
             def is_raid(d):
                 if d.raid[0] and (d.raid[0].lower() == 'yes' or
                                   d.raid[0] == '1'):
                     return True
                 return False
             disk = []
-            if db.option.virtualize_physical:
+            for d in disk_tree:
+                disk.append(Disk(db=db,
+                                 vm=self,
+                                 host=d.host[0],
+                                 root=d.root[0], id=d.id[0],
+                                 raid=is_raid(d), format=d.format[0],
+                                 size=d.size[0]))
+                pass
+            return disk
+        def physical_disks():
+            disk = []
+            pd = qemu._qemu_[0]
+            if db.option.create:
                 for d_name in db.option.physical_disks:
                     size = db.option.physical_disks[d_name]
                     path = db.option.physical_disk_paths[d_name] or '/tw/general'
@@ -216,17 +263,27 @@ class VirtualMachine:
                                      root=path,
                                      id=d_name, raid=False, format='qcow2',
                                      size=size))
+                    attr = {"root": path,
+                            "host": self.host,
+                            "id": d_name,
+                            "size": size,
+                            "format": 'qcow2'
+                            }
+                    node = parser.Node("disk", None, attr)
+                    pd._add(node)
                     pass
                 pass
+            return disk
+        def disk():
+            disk = []
+            if db.option.virtualize_physical and db.option.create:
+                disk = physical_disks()
+                pass
             else:
-                for d in qemu._disk_:
-                    disk.append(Disk(db=db,
-                                     vm=self,
-                                     host=d.host[0],
-                                     root=d.root[0], id=d.id[0],
-                                     raid=is_raid(d), format=d.format[0],
-                                     size=d.size[0]))
-                    pass
+                disk_tree = qemu._disk_
+                if db.option.virtualize_physical:
+                    disk_tree = disk_tree = qemu._qemu_[0]._disk_
+                disk = regular_disks(disk_tree)
                 pass
             return disk
         self.disk = FutureCache(disk)
@@ -258,9 +315,9 @@ class VirtualMachine:
             def __init__(self, db, mac, i, index):
                 self.mac = mac
                 if not db.option.virtualize_physical:
-                    self.bridge = i.qemu_bridge[0] or 'main'
+                    b = i.qemu_bridge[0] or 'main'
                     pass
-                else:
+                elif db.option.create:
                     bridge_len = len(db.option.physical_interface_bridge)
                     if index < bridge_len:
                         b = db.option.physical_interface_bridge[index]
@@ -268,18 +325,37 @@ class VirtualMachine:
                     else:
                         b = i.bridge[0] or 'tw-int'
                         pass
-                    self.bridge = b
+                    i._set("bridge", b)
+                    pass
+                else:
+                    b = i.bridge[0] or 'tw-int'
+                    i._set("bridge", b)
                     pass
+                self.bridge = b
+                pass
         if not self.db.option.virtualize_physical:
             l = self.qemu._parent._interface_
             pass
-        else:
+        elif self.db.option.create:
             l = self.qemu._interface_
             pass
-        return [ Interface(self.db, mac, i, index)
+        else:
+            if (self.host not in self.db.hypervisors or
+                self.name not in self.db.hypervisors[self.host].domain):
+                self.correct = False
+                return
+            l = self.qemu._interface_
+            dom = self.db.hypervisors[self.host].domain[self.name].inactive
+            hostinfo = dom._metadata_[0]._child("control.lth.se:hostinfo")[0]
+            li = hostinfo._host_[0]._interface_
+            for i in l:
+                meta_interface = next((mi.bridge[0] for mi in li
+                                       if mi.ethernet[0] in i.ethernet[0]), 'tw-int')
+                i._set("bridge", meta_interface)
+            pass
+        return [ Interface(self.db, re.split('[^:0-9a-fA-F]+', i.ethernet[0])[0], i, index)
                  for index, i in enumerate(
-                         [i for i in l if i.ethernet[0] != None])
-                 for mac in i.ethernet[0].split(',')]
+                         [i for i in l if i.ethernet[0] != None])]
 
     def disks(self):
         result = collections.OrderedDict()
@@ -576,7 +652,8 @@ def get_vms(db):
     return get_from_netgroup(db, lambda h: not h._qemu_)
 
 def get_physical(db):
-    return get_from_netgroup(db, lambda h: h._qemu_)
+    filter_hosts = lambda h: h._qemu_ or h.name[0] in db.option.check_hypervisor
+    return get_from_netgroup(db, filter_hosts)
 
 def get_from_netgroup(db, filter_host):
     result = set()
diff --git a/src/vm.py b/src/vm.py
index 0d07026c0ec64cab0f00ffb1bfde0496d29e6590..496621585fbc45d4aeea0906c7ea472a495c19b5 100644
--- a/src/vm.py
+++ b/src/vm.py
@@ -167,7 +167,7 @@ def get_hypervisors(db):
     def safe_hypervisor(hosts):
         for hy in hosts:
             try:
-                yield hy,Hypervisor(hy, db=db)
+                yield hy,util.FutureCache(Hypervisor, hy, db)
                 pass
             except libvirt.libvirtError as e:
                 print('Hypervisor failure: %s' % e, file=sys.stderr)
@@ -329,20 +329,24 @@ def check(db):
             # Restricted by wrong netgroup
             #pring("Restrict netgroup")
             return False
-        print('Check:', vm, hypervisor.host if hypervisor else '')
+        #print('Check:', vm, hypervisor.host if hypervisor else '')
         # Check all VMs
         return True
-    qemu = get_hypervisors(db)
     nfs_checklist = set()
     for vm in db.vms.values():
+        if not vm.correct:
+            print('%s needs to be (re)defined on %s' % (
+                vm.name, vm.host), file=sys.stderr)
+            continue
         if not do_check(vm):
             continue
         #print(vm, len(db.vms.values()))
-        for q in [ q for q in qemu.values() if q.host in vm.disk_by_host ]:
+        for q in [ q for q in db.hypervisors.values() if q.host in vm.disk_by_host ]:
             if not do_check(vm, q):
                 continue
             nfs_checklist.add(q)
-            result = (check_cpu_model(vm, q) and
+            result = (vm.correct and
+                      check_cpu_model(vm, q) and
                       check_disks(vm, q) and
                       check_interfaces(vm, q) and
                       check_RNG(vm, q, (db.option.attach and
@@ -399,11 +403,17 @@ def domain_xml(virtual_machine):
         cpu_model = CPU_MODEL_TEMPLATE % dict(
             cpu_model=virtual_machine.cpu_model)
         pass
+    if virtual_machine.physical:
+        metadata = virtual_machine.qemu._xml()
+        pass
+    else:
+        metadata = virtual_machine.qemu._parent._xml()
+        pass
     return DOMAIN_TEMPLATE % dict(
         name=virtual_machine.name,
         memory=util.eval_size(virtual_machine.memory or '1G'),
         uuid=virtual_machine.uuid,
-        metadata=virtual_machine.qemu._parent._xml(),
+        metadata=metadata,
         cpus=virtual_machine.cpus or '1',
         arch=virtual_machine.arch or 'x86_64',
         cpu_model=cpu_model or '',