Improve performance by removing spurious actions

1. Remove a number of time.sleep commands which don't really seem
necessary any longer and which significantly increased the startup
time while parsing the VM list.
2. Handle some variable sets during initialization of the object,
rather than waiting for a management command, enabling...
3. Know when a state change, and the corresponding Libvirt lookup,
is unnecessary due to the target node not matching the current node.
This also removes a number of unremovable errors from Libvirt on the
console which were annoying.

This reduces the total time taken by the VM startup segment (lines
760-762 of Daemon.py) from 17.117s down to 0.976s for 82 VMs.
This commit is contained in:
Joshua Boniface 2019-05-21 22:56:40 -04:00
parent 6fd4710f7f
commit 3893666507
1 changed files with 14 additions and 14 deletions

View File

@ -39,15 +39,17 @@ class DomainInstance(object):
def __init__(self, domuuid, zk_conn, config, logger, this_node): def __init__(self, domuuid, zk_conn, config, logger, this_node):
# Passed-in variables on creation # Passed-in variables on creation
self.domuuid = domuuid self.domuuid = domuuid
self.domname = zkhandler.readdata(zk_conn, '/domains/{}'.format(domuuid))
self.zk_conn = zk_conn self.zk_conn = zk_conn
self.config = config self.config = config
self.logger = logger self.logger = logger
self.this_node = this_node self.this_node = this_node
# Get data from zookeeper
self.domname = zkhandler.readdata(zk_conn, '/domains/{}'.format(domuuid))
self.state = zkhandler.readdata(self.zk_conn, '/domains/{}/state'.format(self.domuuid))
self.node = zkhandler.readdata(self.zk_conn, '/domains/{}/node'.format(self.domuuid))
# These will all be set later # These will all be set later
self.node = None
self.state = None
self.instart = False self.instart = False
self.inrestart = False self.inrestart = False
self.inmigrate = False self.inmigrate = False
@ -185,7 +187,7 @@ class DomainInstance(object):
return return
self.shutdown_vm() self.shutdown_vm()
time.sleep(1) time.sleep(0.2)
self.start_vm() self.start_vm()
self.addDomainToList() self.addDomainToList()
@ -291,10 +293,8 @@ class DomainInstance(object):
if not migrate_ret: if not migrate_ret:
self.logger.out('Could not live migrate VM; shutting down to migrate instead', state='e', prefix='Domain {}:'.format(self.domuuid)) self.logger.out('Could not live migrate VM; shutting down to migrate instead', state='e', prefix='Domain {}:'.format(self.domuuid))
self.shutdown_vm() self.shutdown_vm()
time.sleep(1)
else: else:
self.removeDomainFromList() self.removeDomainFromList()
time.sleep(1)
zkhandler.writedata(self.zk_conn, { '/domains/{}/state'.format(self.domuuid): 'start' }) zkhandler.writedata(self.zk_conn, { '/domains/{}/state'.format(self.domuuid): 'start' })
self.inmigrate = False self.inmigrate = False
@ -310,7 +310,7 @@ class DomainInstance(object):
self.inreceive = True self.inreceive = True
self.logger.out('Receiving migration', state='i', prefix='Domain {}:'.format(self.domuuid)) self.logger.out('Receiving migration', state='i', prefix='Domain {}:'.format(self.domuuid))
while True: while True:
time.sleep(0.5) time.sleep(1)
self.state = zkhandler.readdata(self.zk_conn, '/domains/{}/state'.format(self.domuuid)) self.state = zkhandler.readdata(self.zk_conn, '/domains/{}/state'.format(self.domuuid))
self.dom = self.lookupByUUID(self.domuuid) self.dom = self.lookupByUUID(self.domuuid)
@ -343,10 +343,7 @@ class DomainInstance(object):
# Main function to manage a VM (taking only self) # Main function to manage a VM (taking only self)
# #
def manage_vm_state(self): def manage_vm_state(self):
# Give ourselves a bit of leeway time # Update the current values from zookeeper
time.sleep(0.2)
# Get the current values from zookeeper (don't rely on the watch)
self.state = zkhandler.readdata(self.zk_conn, '/domains/{}/state'.format(self.domuuid)) self.state = zkhandler.readdata(self.zk_conn, '/domains/{}/state'.format(self.domuuid))
self.node = zkhandler.readdata(self.zk_conn, '/domains/{}/node'.format(self.domuuid)) self.node = zkhandler.readdata(self.zk_conn, '/domains/{}/node'.format(self.domuuid))
@ -442,8 +439,11 @@ class DomainInstance(object):
# 1. Takes a text UUID and handles converting it to bytes # 1. Takes a text UUID and handles converting it to bytes
# 2. Try's it and returns a sensible value if not # 2. Try's it and returns a sensible value if not
def lookupByUUID(self, tuuid): def lookupByUUID(self, tuuid):
# Don't do anything if the VM shouldn't live on this node
if self.node != self.this_node.name:
return None
lv_conn = None lv_conn = None
dom = None
libvirt_name = "qemu:///system" libvirt_name = "qemu:///system"
# Convert the text UUID to bytes # Convert the text UUID to bytes
@ -455,14 +455,14 @@ class DomainInstance(object):
lv_conn = libvirt.open(libvirt_name) lv_conn = libvirt.open(libvirt_name)
if lv_conn == None: if lv_conn == None:
self.logger.out('Failed to open local libvirt connection', state='e', prefix='Domain {}:'.format(self.domuuid)) self.logger.out('Failed to open local libvirt connection', state='e', prefix='Domain {}:'.format(self.domuuid))
return dom return None
# Lookup the UUID # Lookup the UUID
dom = lv_conn.lookupByUUID(buuid) dom = lv_conn.lookupByUUID(buuid)
# Fail # Fail
except: except:
pass dom = None
# After everything # After everything
finally: finally: