I've noticed that virt-manager took more time to startup after we started reading OSes data from libosinfo. Now the libosinfo data is loaded the first time it is accessed, without pre-loading it. This could be further improved by not loading completely an _OsVariant object but only the data that is requested. With the lazy load optimization (best of 10 attempts): $ echo yes | time ./virt-xml --connect __virtinst_test__test:////home/gscrivano/src/virt-manager/tests/testdriver.xml,predictable --confirm test --edit --cpu host-passthrough > /dev/null 0.13user 0.02system 0:00.22elapsed 74%CPU (0avgtext+0avgdata 26756maxresident)k Without (best of 10 attempts): $ echo yes | time ./virt-xml --connect __virtinst_test__test:////home/gscrivano/src/virt-manager/tests/testdriver.xml,predictable --confirm test --edit --cpu host-passthrough > /dev/null 1.26user 0.04system 0:01.36elapsed 95%CPU (0avgtext+0avgdata 57996maxresident)k 0inputs+16outputs (0major+17499minor)pagefaults 0swaps Signed-off-by: Giuseppe Scrivano <gscrivan@xxxxxxxxxx> --- virtinst/osdict.py | 153 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 87 insertions(+), 66 deletions(-) diff --git a/virtinst/osdict.py b/virtinst/osdict.py index e1840d1..6524170 100644 --- a/virtinst/osdict.py +++ b/virtinst/osdict.py @@ -24,9 +24,6 @@ _allvariants = {} from datetime import datetime from gi.repository import Libosinfo as libosinfo # pylint: disable=E0611 -loader = libosinfo.Loader() -loader.process_default_path() - _aliases = { "altlinux" : "altlinux1.0", "debianetch" : "debian4", @@ -67,14 +64,6 @@ _aliases = { } -def lookup_os(key): - key = _aliases.get(key) or key - ret = _allvariants.get(key) - if ret is None: - return ret - return ret - - def _sort(tosort, sortpref=None): sortby_mappings = {} distro_mappings = {} @@ -122,56 +111,6 @@ def _sort(tosort, sortpref=None): return retlist -def list_os(list_types=False, typename=None, - filtervars=None, only_supported=False, - **kwargs): - sortmap = {} - filtervars = filtervars or [] - - for key, osinfo in _allvariants.items(): - if list_types and not osinfo.is_type: - continue - if not list_types and osinfo.is_type: - continue - if typename and typename != osinfo.typename: - continue - if filtervars: - filtervars = [lookup_os(x).name for x in filtervars] - if osinfo.name not in filtervars: - continue - if only_supported and not osinfo.supported: - continue - sortmap[key] = osinfo - return _sort(sortmap, **kwargs) - - -def lookup_osdict_key(variant, key, default): - val = _SENTINEL - if variant is not None: - if not hasattr(lookup_os(variant), key): - raise ValueError("Unknown osdict property '%s'" % key) - val = getattr(lookup_os(variant), key) - if val == _SENTINEL: - val = default - return val - - -def get_recommended_resources(variant, arch): - v = _allvariants.get(variant) - if v is None: - return None - - return v.get_recommended_resources(arch) - - -def lookup_os_by_media(location): - media = libosinfo.Media.create_from_location(location, None) - ret = loader.get_db().guess_os_from_media(media) - if ret and len(ret) > 0: - return ret[0].get_short_id() - return None - - class _OSVariant(object): """ Object tracking guest OS specific configuration bits. @@ -569,9 +508,91 @@ _add_type("unix", "UNIX") _add_type("other", "Other") _add_var("generic", "Generic", supported=True, parent="other") -db = loader.get_db() -oslist = db.get_os_list() -for os in range(oslist.get_length()): - osi = _OsVariantOsInfo(oslist.get_nth(os)) - _allvariants[osi.name] = osi +_os_data_loaded = False +_os_loader = None + + +def _get_os_loader(): + global _os_loader + if _os_loader: + return _os_loader + _os_loader = libosinfo.Loader() + _os_loader.process_default_path() + return _os_loader + + +def _load_os_data(): + global _os_data_loaded + if _os_data_loaded: + return + loader = _get_os_loader() + db = loader.get_db() + oslist = db.get_os_list() + for os in range(oslist.get_length()): + osi = _OsVariantOsInfo(oslist.get_nth(os)) + _allvariants[osi.name] = osi + _os_data_loaded = True + + +def lookup_os(key): + _load_os_data() + key = _aliases.get(key) or key + ret = _allvariants.get(key) + if ret is None: + return ret + return ret + + +def list_os(list_types=False, typename=None, + filtervars=None, only_supported=False, + **kwargs): + _load_os_data() + sortmap = {} + filtervars = filtervars or [] + + for key, osinfo in _allvariants.items(): + if list_types and not osinfo.is_type: + continue + if not list_types and osinfo.is_type: + continue + if typename and typename != osinfo.typename: + continue + if filtervars: + filtervars = [lookup_os(x).name for x in filtervars] + if osinfo.name not in filtervars: + continue + if only_supported and not osinfo.supported: + continue + sortmap[key] = osinfo + return _sort(sortmap, **kwargs) + + +def lookup_osdict_key(variant, key, default): + _load_os_data() + val = _SENTINEL + if variant is not None: + if not hasattr(lookup_os(variant), key): + raise ValueError("Unknown osdict property '%s'" % key) + val = getattr(lookup_os(variant), key) + if val == _SENTINEL: + val = default + return val + + +def get_recommended_resources(variant, arch): + _load_os_data() + v = _allvariants.get(variant) + if v is None: + return None + + return v.get_recommended_resources(arch) + + +def lookup_os_by_media(location): + loader = _get_os_loader() + media = libosinfo.Media.create_from_location(location, None) + ret = loader.get_db().guess_os_from_media(media) + if ret and len(ret) > 0: + return ret[0].get_short_id() + return None -- 1.9.0 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list