change default pool code to be fast
currently it takes 100ms+ to determine the default pool every time, including subprocess spawning (!), which is unacceptable since finding out the default value of properties should be instantaneous instead of checking every thin pool to see if the root device is in it, find and cache the name of the root device thin pool and see if there is a configured pool with that name
This commit is contained in:
parent
d183ab1c18
commit
92c452a655
73
qubes/app.py
73
qubes/app.py
@ -545,6 +545,55 @@ class VMCollection(object):
|
||||
'https://xkcd.com/221/',
|
||||
'http://dilbert.com/strip/2001-10-25')[random.randint(0, 1)])
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
class RootThinPool:
|
||||
'''The thin pool containing the rootfs device'''
|
||||
_inited = False
|
||||
_volume_group = None
|
||||
_thin_pool = None
|
||||
|
||||
@classmethod
|
||||
def _init(cls):
|
||||
'''Find out the thin pool containing the root device'''
|
||||
if not cls._inited:
|
||||
cls._inited = True
|
||||
|
||||
try:
|
||||
rootfs = os.stat('/')
|
||||
root_major = (rootfs.st_dev & 0xff00) >> 8
|
||||
root_minor = rootfs.st_dev & 0xff
|
||||
|
||||
root_table = subprocess.check_output(["dmsetup",
|
||||
"-j", str(root_major), "-m", str(root_minor),
|
||||
"table"])
|
||||
|
||||
_start, _sectors, target_type, target_args = \
|
||||
root_table.decode().split(" ", 3)
|
||||
if target_type == "thin":
|
||||
thin_pool_devnum, _thin_pool_id = target_args.split(" ")
|
||||
with open("/sys/dev/block/{}/dm/name"
|
||||
.format(thin_pool_devnum), "r") as thin_pool_tpool_f:
|
||||
thin_pool_tpool = thin_pool_tpool_f.read().rstrip('\n')
|
||||
if thin_pool_tpool.endswith("-tpool"):
|
||||
volume_group, thin_pool, _tpool = \
|
||||
thin_pool_tpool.rsplit("-", 2)
|
||||
cls._volume_group = volume_group
|
||||
cls._thin_pool = thin_pool
|
||||
except: # pylint: disable=bare-except
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def volume_group(cls):
|
||||
'''Volume group of the thin pool containing the rootfs device'''
|
||||
cls._init()
|
||||
return cls._volume_group
|
||||
|
||||
@classmethod
|
||||
def thin_pool(cls):
|
||||
'''Thin pool name containing the rootfs device'''
|
||||
cls._init()
|
||||
return cls._thin_pool
|
||||
|
||||
def _default_pool(app):
|
||||
''' Default storage pool.
|
||||
|
||||
@ -556,20 +605,16 @@ def _default_pool(app):
|
||||
if 'default' in app.pools:
|
||||
return app.pools['default']
|
||||
else:
|
||||
rootfs = os.stat('/')
|
||||
root_major = (rootfs.st_dev & 0xff00) >> 8
|
||||
root_minor = rootfs.st_dev & 0xff
|
||||
for pool in app.pools.values():
|
||||
if pool.config.get('driver', None) != 'lvm_thin':
|
||||
continue
|
||||
thin_pool = pool.config['thin_pool']
|
||||
thin_volumes = subprocess.check_output(
|
||||
['lvs', '--select', 'pool_lv=' + thin_pool,
|
||||
'-o', 'lv_kernel_major,lv_kernel_minor', '--noheadings'])
|
||||
thin_volumes = thin_volumes.decode()
|
||||
if any([str(root_major), str(root_minor)] == thin_vol.split()
|
||||
for thin_vol in thin_volumes.splitlines()):
|
||||
return pool
|
||||
root_volume_group = RootThinPool.volume_group()
|
||||
root_thin_pool = RootThinPool.thin_pool()
|
||||
if root_thin_pool:
|
||||
for pool in app.pools.values():
|
||||
if pool.config.get('driver', None) != 'lvm_thin':
|
||||
continue
|
||||
if (pool.config['volume_group'] == root_volume_group and
|
||||
pool.config['thin_pool'] == root_thin_pool):
|
||||
return pool
|
||||
|
||||
# not a thin volume? look for file pools
|
||||
for pool in app.pools.values():
|
||||
if pool.config.get('driver', None) != 'file':
|
||||
|
Loading…
Reference in New Issue
Block a user