mirror of
https://github.com/virt-manager/virt-manager.git
synced 2026-08-04 02:13:21 -05:00
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:
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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 #
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user