[virt-tools-list] [PATCH virt-manager] osdict: lazy load data from libosinfo

Giuseppe Scrivano gscrivan at redhat.com
Fri Mar 28 11:22:06 UTC 2014


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 at redhat.com>
---
 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




More information about the virt-tools-list mailing list