devicedisk: path_in_use_by: Check backing stores as well

Plumb through a fetch_all_vols helper for this, and do all the
caching bits.
This commit is contained in:
Cole Robinson
2013-09-28 21:07:18 -04:00
parent bc34df1dc7
commit 7a5dc7c544
6 changed files with 81 additions and 58 deletions
+10 -3
View File
@@ -136,9 +136,16 @@ class vmmConnection(vmmGObject):
def _init_virtconn(self):
self._backend.cb_fetch_all_guests = (
lambda: [vm.get_guest_for_virtinst_func(refresh_if_nec=False)
for vm in self.vms.values()])
self._backend.cb_fetch_all_pools = lambda: self.pools.values()
lambda: [obj.get_xmlobj(refresh_if_nec=False)
for obj in self.vms.values()])
self._backend.cb_fetch_all_pools = (
lambda: [obj.get_xmlobj(refresh_if_nec=False)
for obj in self.pools.values()])
self._backend.cb_fetch_all_vols = (
lambda: [obj.get_xmlobj(refresh_if_nec=False)
for pool in self.pools.values()
for obj in pool.get_volumes(refresh=False).values()])
def _init_netdev(self):
"""
-3
View File
@@ -405,9 +405,6 @@ class vmmDomain(vmmLibvirtObject):
raise RuntimeError(_("Could not find specified device in the "
"inactive VM configuration: %s") % repr(origdev))
def get_guest_for_virtinst_func(self, *args, **kwargs):
return self.get_xmlobj(*args, **kwargs)
##############################
# Persistent XML change APIs #
+3 -2
View File
@@ -178,8 +178,9 @@ class vmmStoragePool(vmmLibvirtObject):
# Volume handling #
###################
def get_volumes(self):
self.update_volumes()
def get_volumes(self, refresh=True):
if refresh:
self.update_volumes()
return self._volumes
def get_volume(self, uuid):
+49 -32
View File
@@ -23,8 +23,10 @@ import weakref
import libvirt
from virtinst import Guest
from virtinst import CapabilitiesParser
from virtinst import Guest
from virtinst import StoragePool
from virtinst import StorageVolume
from virtinst import pollhelpers
from virtinst import support
from virtinst import util
@@ -58,25 +60,6 @@ def _sanitize_xml(xml):
return xml
class _FetchObjWrapper(object):
"""
Wrapper to make virDomain etc. objects have a similar XML API as
virt-manager objects, so fetch_all* callers get similar results
"""
def __init__(self, backend):
self._backend = backend
self._xml = None
self._xmlobj = None
def get_xml(self, refresh_if_nec=True):
if self._xml is None or refresh_if_nec:
self._xml = self._backend.XMLDesc(0)
return self._xml
def get_backend(self):
return self._backend
class VirtualConnection(object):
"""
Wrapper for libvirt connection that provides various bits like
@@ -122,6 +105,7 @@ class VirtualConnection(object):
# own cached object lists, rather than doing fresh calls
self.cb_fetch_all_guests = None
self.cb_fetch_all_pools = None
self.cb_fetch_all_vols = None
##############
@@ -182,12 +166,7 @@ class VirtualConnection(object):
self._uri = self._libvirtconn.getURI()
self._urisplits = util.uri_split(self._uri)
def fetch_all_guests(self):
# pylint: disable=E1102
if self.cb_fetch_all_guests:
return self.cb_fetch_all_guests()
# pylint: enable=E1102
def _fetch_all_guests_cached(self):
key = "vms"
if key in self._fetch_cache:
return self._fetch_cache[key]
@@ -200,23 +179,61 @@ class VirtualConnection(object):
self._fetch_cache[key] = ret
return ret
def fetch_all_pools(self):
# pylint: disable=E1102
if self.cb_fetch_all_pools:
return self.cb_fetch_all_pools()
# pylint: enable=E1102
def fetch_all_guests(self):
"""
Returns a list of Guest() objects
"""
if self.cb_fetch_all_guests:
return self.cb_fetch_all_guests() # pylint: disable=E1102
return self._fetch_all_guests_cached()
def _fetch_all_pools_cached(self):
key = "pools"
if key in self._fetch_cache:
return self._fetch_cache[key]
ignore, ignore, ret = pollhelpers.fetch_pools(self, {},
lambda obj, ignore: obj)
ret = [_FetchObjWrapper(obj) for obj in ret.values()]
ret = [StoragePool(weakref.ref(self), parsexml=obj.XMLDesc(0))
for obj in ret.values()]
if self.cache_object_fetch:
self._fetch_cache[key] = ret
return ret
def fetch_all_pools(self):
"""
Returns a list of StoragePool objects
"""
if self.cb_fetch_all_pools:
return self.cb_fetch_all_pools() # pylint: disable=E1102
return self._fetch_all_pools_cached()
def _fetch_all_vols_cached(self):
key = "vols"
if key in self._fetch_cache:
return self._fetch_cache[key]
ret = []
for xmlobj in self.fetch_all_pools():
pool = self._libvirtconn.storagePoolLookupByName(xmlobj.name)
# XXX: Should implement pollhelpers support for listAllVolumes
for volname in pool.listVolumes():
vol = pool.storageVolLookupByName(volname)
ret.append(StorageVolume(weakref.ref(self),
parsexml=vol.XMLDesc(0)))
if self.cache_object_fetch:
self._fetch_cache[key] = ret
return ret
def fetch_all_vols(self):
"""
Returns a list of StorageVolume objects
"""
if self.cb_fetch_all_vols:
return self.cb_fetch_all_vols() # pylint: disable=E1102
return self._fetch_all_vols_cached()
def clear_cache(self):
self._fetch_cache = {}
+15 -12
View File
@@ -337,23 +337,26 @@ class VirtualDisk(VirtualDevice):
"""
if not path:
return
ret = []
vols = []
for vol in conn.fetch_all_vols():
if path == vol.backing_store:
vols.append(vol.target_path)
vms = conn.fetch_all_guests()
names = []
for vm in vms:
found = False
for disk in vm.get_devices("disk"):
if disk.path != path:
continue
if check_conflict:
if disk.shareable:
continue
found = True
break
if found:
names.append(vm.name)
if disk.path == path:
if check_conflict:
if disk.shareable:
continue
if vm.name not in ret:
ret.append(vm.name)
return names
if disk.path in vols and vm.name not in ret:
ret.append(vm.name)
return ret
@staticmethod
def stat_local_path(path):
+4 -6
View File
@@ -217,15 +217,13 @@ class StoragePool(_StorageObject):
return None
def check_pool(pool, path):
xml = pool.get_xml(refresh_if_nec=False)
xml_path = StoragePool(conn, parsexml=xml).target_path
xml_path = pool.target_path
if xml_path is not None and os.path.abspath(xml_path) == path:
return pool
return True
for pool in conn.fetch_all_pools():
p = check_pool(pool, path)
if p:
return p.get_backend()
if check_pool(pool, path):
return conn.storagePoolLookupByName(pool.name)
return None