diff --git a/drivers/LinstorSR.py b/drivers/LinstorSR.py index 3bd31e9e..c5ed7c58 100755 --- a/drivers/LinstorSR.py +++ b/drivers/LinstorSR.py @@ -1830,7 +1830,7 @@ def attach(self, sr_uuid, vdi_uuid): return self._attach_using_http_nbd() # Ensure we have a path... - self._create_chain_paths(self.uuid) + self.sr._vhdutil.create_chain_paths(self.uuid) self.attached = True return VDI.VDI.attach(self, self.sr.uuid, self.uuid) @@ -2357,7 +2357,7 @@ def _snapshot(self, snap_type, cbtlog=None, cbt_consistency=None): raise xs_errors.XenError('SnapshotChainTooLong') # Ensure we have a valid path if we don't have a local diskful. - self._create_chain_paths(self.uuid) + self.sr._vhdutil.create_chain_paths(self.uuid) volume_path = self.path if not util.pathexists(volume_path): @@ -2820,37 +2820,6 @@ def _detach_using_http_nbd(self): self._kill_persistent_nbd_server(volume_name) self._kill_persistent_http_server(volume_name) - def _create_chain_paths(self, vdi_uuid): - # OPTIMIZE: Add a limit_to_first_allocated_block param to limit vhdutil calls. - # Useful for the snapshot code algorithm. - - while vdi_uuid: - path = self._linstor.get_device_path(vdi_uuid) - if not util.pathexists(path): - raise xs_errors.XenError( - 'VDIUnavailable', opterr='Could not find: {}'.format(path) - ) - - # Diskless path can be created on the fly, ensure we can open it. - def check_volume_usable(): - while True: - try: - with open(path, 'r+'): - pass - except IOError as e: - if e.errno == errno.ENODATA: - time.sleep(2) - continue - if e.errno == errno.EROFS: - util.SMlog('Volume not attachable because RO. Openers: {}'.format( - self.sr._linstor.get_volume_openers(vdi_uuid) - )) - raise - break - util.retry(check_volume_usable, 15, 2) - - vdi_uuid = self.sr._vhdutil.get_vhd_info(vdi_uuid).parentUuid - # ------------------------------------------------------------------------------ diff --git a/drivers/linstorvhdutil.py b/drivers/linstorvhdutil.py index 23d8b6a0..17b7790e 100644 --- a/drivers/linstorvhdutil.py +++ b/drivers/linstorvhdutil.py @@ -21,6 +21,7 @@ import errno import json import socket +import time import util import vhdutil import xs_errors @@ -141,6 +142,43 @@ def __init__(self, session, linstor): self._session = session self._linstor = linstor + def create_chain_paths(self, vdi_uuid): + # OPTIMIZE: Add a limit_to_first_allocated_block param to limit vhdutil calls. + # Useful for the snapshot code algorithm. + + leaf_vdi_path = self._linstor.get_device_path(vdi_uuid) + path = leaf_vdi_path + while True: + if not util.pathexists(path): + raise xs_errors.XenError( + 'VDIUnavailable', opterr='Could not find: {}'.format(path) + ) + + # Diskless path can be created on the fly, ensure we can open it. + def check_volume_usable(): + while True: + try: + with open(path, 'r+'): + pass + except IOError as e: + if e.errno == errno.ENODATA: + time.sleep(2) + continue + if e.errno == errno.EROFS: + util.SMlog('Volume not attachable because RO. Openers: {}'.format( + self._linstor.get_volume_openers(vdi_uuid) + )) + raise + break + util.retry(check_volume_usable, 15, 2) + + vdi_uuid = self.get_vhd_info(vdi_uuid).parentUuid + if not vdi_uuid: + break + path = self._linstor.get_device_path(vdi_uuid) + + return leaf_vdi_path + # -------------------------------------------------------------------------- # Getters: read locally and try on another host in case of failure. # -------------------------------------------------------------------------- diff --git a/drivers/tapdisk-pause b/drivers/tapdisk-pause index e0bca7be..c316cdfa 100755 --- a/drivers/tapdisk-pause +++ b/drivers/tapdisk-pause @@ -30,6 +30,7 @@ import vhdutil import lvmcache try: + from linstorvhdutil import LinstorVhdUtil from linstorvolumemanager import get_controller_uri, LinstorVolumeManager LINSTOR_AVAILABLE = True except ImportError: @@ -162,11 +163,12 @@ class Tapdisk: dconf = session.xenapi.PBD.get_device_config(pbd) group_name = dconf['group-name'] - device_path = LinstorVolumeManager( + linstor = LinstorVolumeManager( get_controller_uri(), group_name, logger=util.SMlog - ).get_device_path(self.vdi_uuid) + ) + device_path = LinstorVhdUtil(session, linstor).create_chain_paths(self.vdi_uuid) if realpath != device_path: util.SMlog(