コード例 #1
0
ファイル: cifutils.py プロジェクト: xcp-ng/sm
def getCIFCredentials(dconf, session, prefix=""):
    credentials = None
    domain = None
    if (containsCredentials(dconf, prefix)):

        username, domain = splitDomainAndUsername(dconf['username'])
        credentials = {}
        credentials["USER"] = util.to_plain_string(username)
        util.SMlog("CIFS user = {user}".format(user=credentials["USER"]))

        key_password, key_secret = getDconfPasswordKey(prefix)
        if key_secret in dconf:
            password = util.get_secret(session, dconf[key_secret])
            if password is not None:
                util.SMlog("Obtained CIFS password via secret")
        else:
            password = dconf[key_password]
            if password is not None:
                util.SMlog("Obtained CIFS password")

        credentials["PASSWD"] = util.to_plain_string(password)
        if credentials["PASSWD"] is not None:
            util.SMlog("Obtained CIFS plain text password")

        domain = util.to_plain_string(domain)
    else:
        util.SMlog("NOTE: No CIFS credentials found in dconf")

    return credentials, domain
コード例 #2
0
ファイル: metadata.py プロジェクト: BobBall/sm
def _walkXML(parent):
    Dict = {}
    
    if not parent.hasChildNodes():
        if parent.nodeValue == None:
            return ''

    for node in parent.childNodes:
        if node.nodeType == Node.ELEMENT_NODE:
            # Print the element name
            Dict[util.to_plain_string(node.nodeName)] = ""
            
            # Walk over any text nodes in the current node
            content = []
            for child in node.childNodes:
                if child.nodeType == Node.TEXT_NODE and \
                       child.nodeValue.strip():
                    content.append(child.nodeValue.strip())
            if content:
                strContent = string.join(content)
                Dict[util.to_plain_string(node.nodeName)] = util.to_plain_string(strContent)
            else:
                # Walk the child nodes
                Dict[util.to_plain_string(node.nodeName)] = _walkXML(node)
                
    return Dict
コード例 #3
0
ファイル: ISOSR.py プロジェクト: xcp-ng/sm
    def load(self, sr_uuid):
        """Initialises the SR"""
        # First of all, check we've got the correct keys in dconf
        if 'location' not in self.dconf:
            raise xs_errors.XenError('ConfigLocationMissing')

        # Construct the path we're going to mount under:
        if "legacy_mode" in self.dconf:
            self.mountpoint = util.to_plain_string(self.dconf['location'])
        else:
            # Verify the target address
            self._checkTargetStr(self.dconf['location'])
            self.mountpoint = os.path.join(SR.MOUNT_BASE, sr_uuid)

        # Add on the iso_path value if there is one
        if "iso_path" in self.dconf:
            iso_path = util.to_plain_string(self.dconf['iso_path'])
            if iso_path.startswith("/"):
                iso_path = iso_path[1:]
            self.path = os.path.join(self.mountpoint, iso_path)
        else:
            self.path = self.mountpoint

        # Handle optional dconf attributes
        self.nfsversion = nfs.validate_nfsversion(self.dconf.get('nfsversion'))

        # Fill the required SMB version
        self.smbversion = SMB_VERSION_3

        # Check if smb version is specified from client
        self.is_smbversion_specified = False

        # Some info we need:
        self.sr_vditype = 'phy'
コード例 #4
0
ファイル: metadata.py プロジェクト: xcp-ng/sm
def _walkXML(parent):
    Dict = {}

    if not parent.hasChildNodes():
        if parent.nodeValue is None:
            return ''

    for node in parent.childNodes:
        if node.nodeType == Node.ELEMENT_NODE:
            # Print the element name
            Dict[util.to_plain_string(node.nodeName)] = ""

            # Walk over any text nodes in the current node
            content = []
            for child in node.childNodes:
                if child.nodeType == Node.TEXT_NODE and \
                       child.nodeValue.strip():
                    content.append(child.nodeValue.strip())
            if content:
                strContent = string.join(content)
                Dict[util.to_plain_string(
                    node.nodeName)] = util.to_plain_string(strContent)
            else:
                # Walk the child nodes
                Dict[util.to_plain_string(node.nodeName)] = _walkXML(node)

    return Dict
コード例 #5
0
ファイル: SMBSR.py プロジェクト: letsboogey/sm
    def getMountOptions(self):
        """Creates option string based on parameters provided"""
        options = ['sec=ntlm',
                'cache=loose',
                'vers=3.0',
                'actimeo=0'
        ]

        if self.dconf.has_key('username') and \
                (self.dconf.has_key('password') or
                self.dconf.has_key('password_secret')):

            dom_username = self.dconf['username'].split('\\')

            if len(dom_username) == 1:
                domain = None
                username = dom_username[0]
            elif len(dom_username) == 2:
                domain = dom_username[0]
                username = dom_username[1]
            else:
                raise SMBException("A maximum of 2 tokens are expected "
                                   "(<domain>\<username>). {} were given."
                                   .format(len(dom_username)))

            domain = util.to_plain_string(domain)
            username = util.to_plain_string(username)

            if self.dconf.has_key('password_secret'):
                password = util.get_secret(
                           self.session,
                           self.dconf['password_secret']
            )
            else:
                password = self.dconf['password']

            password = util.to_plain_string(password)

            cred_str = 'username={}\npassword={}\n'.format(username, password)

            if domain:
                cred_str += 'domain={}\n'.format(domain)

            # Open credentials file and truncate
            try:
                with open(self.credentials, 'w') as f:
                    f.write(cred_str)
            except IOError, e:
                raise SMBException("Failed to create credentials file")

	    options.append('credentials=%s' % self.credentials)
コード例 #6
0
    def getMountOptions(self):
        """Creates option string based on parameters provided"""
        options = ['sec=ntlm',
                'cache=loose',
                'vers=3.0',
                'actimeo=0'
        ]

        if self.dconf.has_key('username') and \
                (self.dconf.has_key('password') or
                self.dconf.has_key('password_secret')):

            dom_username = self.dconf['username'].split('\\')

            if len(dom_username) == 1:
                domain = None
                username = dom_username[0]
            elif len(dom_username) == 2:
                domain = dom_username[0]
                username = dom_username[1]
            else:
                raise SMBException("A maximum of 2 tokens are expected "
                                   "(<domain>\<username>). {} were given."
                                   .format(len(dom_username)))

            domain = util.to_plain_string(domain)
            username = util.to_plain_string(username)

            if self.dconf.has_key('password_secret'):
                password = util.get_secret(
                           self.session,
                           self.dconf['password_secret']
            )
            else:
                password = self.dconf['password']

            password = util.to_plain_string(password)

            cred_str = 'username={}\npassword={}\n'.format(username, password)

            if domain:
                cred_str += 'domain={}\n'.format(domain)

            # Open credentials file and truncate
            try:
                with open(self.credentials, 'w') as f:
                    f.write(cred_str)
            except IOError, e:
                raise SMBException("Failed to create credentials file")

	    options.append('credentials=%s' % self.credentials)
コード例 #7
0
    def load(self, sr_uuid):
        """Initialises the SR"""
        if not 'location' in self.dconf:
            raise xs_errors.XenError('ConfigLocationMissing')

        self.path = util.to_plain_string(self.dconf['location'])
        self.sr_vditype = 'file'
コード例 #8
0
ファイル: SR.py プロジェクト: dwhitla-zz/xcp-storage-managers
 def synchronise_gone(self):
     """Delete XenAPI record for old disks"""
     for location in self.gone:
         vdi = self.get_xenapi_vdi(location)
         util.SMlog("Forgetting VDI with location=%s uuid=%s" %
                    (util.to_plain_string(vdi['location']), vdi['uuid']))
         self.sr.forget_vdi(vdi['uuid'])
コード例 #9
0
ファイル: ISOSR.py プロジェクト: xcp-ng/sm
    def vdi(self, uuid):
        """Create a VDI class.  If the VDI does not exist, we determine
        here what its filename should be."""

        filename = util.to_plain_string(self.srcmd.params.get('vdi_location'))
        if filename is None:
            smconfig = self.srcmd.params.get('vdi_sm_config')
            if smconfig is None:
                # uh, oh, a VDI.from_uuid()
                import XenAPI
                _VDI = self.session.xenapi.VDI
                try:
                    vdi_ref = _VDI.get_by_uuid(uuid)
                except XenAPI.Failure as e:
                    if e.details[0] != 'UUID_INVALID':
                        raise
                else:
                    filename = _VDI.get_location(vdi_ref)

        if filename is None:
            # Get the filename from sm-config['path'], or use the UUID
            # if the path param doesn't exist.
            if smconfig and 'path' in smconfig:
                filename = smconfig['path']
                if not self.vdi_path_regex.match(filename):
                    raise xs_errors.XenError('VDICreate', \
                                                 opterr='Invalid path "%s"' % filename)
            else:
                filename = '%s.img' % uuid

        return ISOVDI(self, filename)
コード例 #10
0
ファイル: VDI.py プロジェクト: chandrikas/sm
 def in_sync_with_xenapi_record(self, x):
     """Returns true if this VDI is in sync with the supplied XenAPI record"""
     if self.location <> util.to_plain_string(x['location']):
         util.SMlog("location %s <> %s" % (self.location, x['location']))
         return False
     if self.read_only <> x['read_only']:
         util.SMlog("read_only %s <> %s" % (self.read_only, x['read_only']))
         return False
     if str(self.size) <> x['virtual_size']:
         util.SMlog("virtual_size %s <> %s" % (self.size, x['virtual_size']))
         return False
     if str(self.utilisation) <> x['physical_utilisation']:
         util.SMlog("utilisation %s <> %s" % (self.utilisation, x['physical_utilisation']))
         return False
     sm_config = util.default(self, "sm_config", lambda: {})
     if set(sm_config.keys()) <> set(x['sm_config'].keys()):
         util.SMlog("sm_config %s <> %s" % (repr(sm_config), repr(x['sm_config'])))
         return False
     for k in sm_config.keys():
         if sm_config[k] <> x['sm_config'][k]:
             util.SMlog("sm_config %s <> %s" % (repr(sm_config), repr(x['sm_config'])))
             return False
     if self.cbt_enabled != x['cbt_enabled']:
         util.SMlog("cbt_enabled %s <> %s" % (
             self.cbt_enabled, x['cbt_enabled']))
         return False
     return True
コード例 #11
0
ファイル: VDI.py プロジェクト: voodoochief/sm
 def in_sync_with_xenapi_record(self, x):
     """Returns true if this VDI is in sync with the supplied XenAPI record"""
     if self.location <> util.to_plain_string(x['location']):
         util.SMlog("location %s <> %s" % (self.location, x['location']))
         return False
     if self.read_only <> x['read_only']:
         util.SMlog("read_only %s <> %s" % (self.read_only, x['read_only']))
         return False
     if str(self.size) <> x['virtual_size']:
         util.SMlog("virtual_size %s <> %s" %
                    (self.size, x['virtual_size']))
         return False
     if str(self.utilisation) <> x['physical_utilisation']:
         util.SMlog("utilisation %s <> %s" %
                    (self.utilisation, x['physical_utilisation']))
         return False
     sm_config = util.default(self, "sm_config", lambda: {})
     if set(sm_config.keys()) <> set(x['sm_config'].keys()):
         util.SMlog("sm_config %s <> %s" %
                    (repr(sm_config), repr(x['sm_config'])))
         return False
     for k in sm_config.keys():
         if sm_config[k] <> x['sm_config'][k]:
             util.SMlog("sm_config %s <> %s" %
                        (repr(sm_config), repr(x['sm_config'])))
             return False
     if self.cbt_enabled != x['cbt_enabled']:
         util.SMlog("cbt_enabled %s <> %s" %
                    (self.cbt_enabled, x['cbt_enabled']))
         return False
     return True
コード例 #12
0
ファイル: SR.py プロジェクト: euanh/sm
    def __init__(self, sr):
        self.sr = sr
        self.__xenapi_locations = {}
        self.__xenapi_records = util.list_VDI_records_in_sr(sr)
        for vdi in self.__xenapi_records.keys():
            self.__xenapi_locations[util.to_plain_string(
                self.__xenapi_records[vdi]['location'])] = vdi
        self.__sm_records = {}
        for vdi in sr.vdis.values():
            # We initialise the sm_config field with the values from the database
            # The sm_config_overrides contains any new fields we want to add to
            # sm_config, and also any field to delete (by virtue of having
            # sm_config_overrides[key]=None)
            try:
                if not hasattr(vdi, "sm_config"):
                    vdi.sm_config = self.__xenapi_records[
                        self.__xenapi_locations[
                            vdi.location]]['sm_config'].copy()
            except:
                util.SMlog("missing config for vdi: %s" % vdi.location)
                vdi.sm_config = {}

            vdi._override_sm_config(vdi.sm_config)

            self.__sm_records[vdi.location] = vdi

        xenapi_locations = set(self.__xenapi_locations.keys())
        sm_locations = set(self.__sm_records.keys())

        # These ones are new on disk
        self.new = sm_locations.difference(xenapi_locations)
        # These have disappeared from the disk
        self.gone = xenapi_locations.difference(sm_locations)
        # These are the ones which are still present but might have changed...
        existing = sm_locations.intersection(xenapi_locations)
        # Synchronise the uuid fields using the location as the primary key
        # This ensures we know what the UUIDs are even though they aren't stored
        # in the storage backend.
        for location in existing:
            sm_vdi = self.get_sm_vdi(location)
            xenapi_vdi = self.get_xenapi_vdi(location)
            sm_vdi.uuid = util.default(sm_vdi, "uuid",
                                       lambda: xenapi_vdi['uuid'])

        # Only consider those whose configuration looks different
        self.existing = filter(
            lambda x: not (self.get_sm_vdi(x).in_sync_with_xenapi_record(
                self.get_xenapi_vdi(x))), existing)

        if len(self.new) <> 0:
            util.SMlog("new VDIs on disk: " + repr(self.new))
        if len(self.gone) <> 0:
            util.SMlog("VDIs missing from disk: " + repr(self.gone))
        if len(self.existing) <> 0:
            util.SMlog("VDIs changed on disk: " + repr(self.existing))
コード例 #13
0
ファイル: cifutils.py プロジェクト: cheese/sm
def getCIFCredentials(dconf, session, prefix=""):
    credentials = None
    domain = None
    if (containsCredentials(dconf, prefix)):

        username, domain = splitDomainAndUsername(dconf['username'])
        credentials = {}
        credentials["USER"] = util.to_plain_string(username)

        key_password, key_secret = getDconfPasswordKey(prefix)
        if key_secret in dconf:
            password = util.get_secret(session, dconf[key_secret])
        else:
            password = dconf[key_password]

        credentials["PASSWD"] = util.to_plain_string(password)

        domain = util.to_plain_string(domain)

    return credentials, domain
コード例 #14
0
ファイル: SR.py プロジェクト: rdobson/sm
 def synchronise_gone(self):
     """Delete XenAPI record for old disks"""
     for location in self.gone:
         vdi = self.get_xenapi_vdi(location)
         util.SMlog("Forgetting VDI with location=%s uuid=%s" % (util.to_plain_string(vdi['location']), vdi['uuid']))
         try:
             self.sr.forget_vdi(vdi['uuid'])
         except XenAPI.Failure, e:
             if e.details == "HANDLE_INVALID" or e.details == "UUID_INVALID":
                util.SMlog("VDI %s not found, ignoring exception" % vdi['uuid'])
             else:
                raise
コード例 #15
0
 def synchronise_gone(self):
     """Delete XenAPI record for old disks"""
     for location in self.gone:
         vdi = self.get_xenapi_vdi(location)
         util.SMlog("Forgetting VDI with location=%s uuid=%s" % (util.to_plain_string(vdi['location']), vdi['uuid']))
         try:
             self.sr.forget_vdi(vdi['uuid'])
         except XenAPI.Failure, e:
             if util.isInvalidVDI(e):
                util.SMlog("VDI %s not found, ignoring exception" \
                        % vdi['uuid'])
             else:
                raise
コード例 #16
0
ファイル: SR.py プロジェクト: BobBall/sm
 def synchronise_gone(self):
     """Delete XenAPI record for old disks"""
     for location in self.gone:
         vdi = self.get_xenapi_vdi(location)
         util.SMlog("Forgetting VDI with location=%s uuid=%s" % (util.to_plain_string(vdi['location']), vdi['uuid']))
         try:
             self.sr.forget_vdi(vdi['uuid'])
         except XenAPI.Failure, e:
             if util.isInvalidVDI(e):
                util.SMlog("VDI %s not found, ignoring exception" \
                        % vdi['uuid'])
             else:
                raise
コード例 #17
0
ファイル: SR.py プロジェクト: sugandhaaggarwal/sm
 def synchronise_gone(self):
     """Delete XenAPI record for old disks"""
     for location in self.gone:
         vdi = self.get_xenapi_vdi(location)
         util.SMlog("Forgetting VDI with location=%s uuid=%s" %
                    (util.to_plain_string(vdi['location']), vdi['uuid']))
         try:
             self.sr.forget_vdi(vdi['uuid'])
         except XenAPI.Failure, e:
             if e.details == "HANDLE_INVALID" or e.details == "UUID_INVALID":
                 util.SMlog("VDI %s not found, ignoring exception" % uuid)
             else:
                 raise
コード例 #18
0
    def __init__(self, sr):
        self.sr = sr
        self.__xenapi_locations = {}
        self.__xenapi_records = util.list_VDI_records_in_sr(sr)
        for vdi in self.__xenapi_records.keys():
            self.__xenapi_locations[util.to_plain_string(self.__xenapi_records[vdi]['location'])] = vdi
        self.__sm_records = {}
        for vdi in sr.vdis.values():
            # We initialise the sm_config field with the values from the database
            # The sm_config_overrides contains any new fields we want to add to
            # sm_config, and also any field to delete (by virtue of having 
            # sm_config_overrides[key]=None)
            try:
                if not hasattr(vdi, "sm_config"):
                    vdi.sm_config = self.__xenapi_records[self.__xenapi_locations[vdi.location]]['sm_config'].copy()
            except:
                util.SMlog("missing config for vdi: %s" % vdi.location)
                vdi.sm_config = {}

            vdi._override_sm_config(vdi.sm_config)

            self.__sm_records[vdi.location] = vdi

        xenapi_locations = set(self.__xenapi_locations.keys())
        sm_locations = set(self.__sm_records.keys())

        # These ones are new on disk
        self.new = sm_locations.difference(xenapi_locations)
        # These have disappeared from the disk
        self.gone = xenapi_locations.difference(sm_locations)
        # These are the ones which are still present but might have changed...
        existing = sm_locations.intersection(xenapi_locations)
        # Synchronise the uuid fields using the location as the primary key
        # This ensures we know what the UUIDs are even though they aren't stored
        # in the storage backend.
        for location in existing:
            sm_vdi = self.get_sm_vdi(location)
            xenapi_vdi = self.get_xenapi_vdi(location)
            sm_vdi.uuid = util.default(sm_vdi, "uuid", lambda: xenapi_vdi['uuid']) 
                
        # Only consider those whose configuration looks different
        self.existing = filter(lambda x:not(self.get_sm_vdi(x).in_sync_with_xenapi_record(self.get_xenapi_vdi(x))), existing)

        if len(self.new) <> 0:
            util.SMlog("new VDIs on disk: " + repr(self.new))
        if len(self.gone) <> 0:
            util.SMlog("VDIs missing from disk: " + repr(self.gone))
        if len(self.existing) <> 0:
            util.SMlog("VDIs changed on disk: " + repr(self.existing))
コード例 #19
0
    def vdi(self, uuid):
        """Create a VDI class.  If the VDI does not exist, we determine
        here what its filename should be."""

        filename = util.to_plain_string(self.srcmd.params.get('vdi_location'))
        if filename is None:
            smconfig = self.srcmd.params.get('vdi_sm_config')
            if smconfig is None:
                # uh, oh, a VDI.from_uuid()
                _VDI = self.session.xenapi.VDI
                try:
                    vdi_ref = _VDI.get_by_uuid(uuid)
                except XenAPI.Failure, e:
                    if e.details[0] != 'UUID_INVALID':
                        raise
                else:
                    filename = _VDI.get_location(vdi_ref)
コード例 #20
0
 def synchronise_gone(self):
     """Delete XenAPI record for old disks"""
     for location in self.gone:
         vdi = self.get_xenapi_vdi(location)
         util.SMlog("Forgetting VDI with location=%s uuid=%s" % (util.to_plain_string(vdi['location']), vdi['uuid']))
         self.sr.forget_vdi(vdi['uuid'])
コード例 #21
0
ファイル: ISOSR.py プロジェクト: xcp-ng/sm
    def attach(self, sr_uuid):
        """Std. attach"""
        # Very-Legacy mode means the ISOs are in the local fs - so no need to attach.
        if 'legacy_mode' in self.dconf:
            # Verify path exists
            if not os.path.exists(self.mountpoint):
                raise xs_errors.XenError('ISOLocalPath')
            return

        # Check whether we're already mounted
        if self._checkmount():
            return

        # Create the mountpoint if it's not already there
        if not util.isdir(self.mountpoint):
            util.makedirs(self.mountpoint)

        mountcmd = []
        location = util.to_plain_string(self.dconf['location'])
        # TODO: Have XC standardise iso type string
        protocol = 'nfs_iso'
        options = ''

        if 'type' in self.dconf:
            protocol = self.dconf['type']
        elif ":/" not in location:
            protocol = 'cifs'

        if 'options' in self.dconf:
            options = self.dconf['options'].split(' ')
            if protocol == 'cifs':
                options = filter(lambda x: x != "", options)
            else:
                options = self.getNFSOptions(options)

        # SMB options are passed differently for create via
        # XC/xe sr-create and create via xe-mount-iso-sr
        # In both cases check if SMB version is passed are not.
        # If not use self.smbversion.
        if protocol == 'cifs':
            if 'type' in self.dconf:
                # Create via XC or sr-create
                # Check for username and password
                mountcmd = ["mount.cifs", location, self.mountpoint]
                if 'vers' in self.dconf:
                    self.is_smbversion_specified = True
                    self.smbversion = self.dconf['vers']
                    util.SMlog("self.dconf['vers'] = %s" % self.dconf['vers'])
                self.appendCIFSMountOptions(mountcmd)
            else:
                # Creation via xe-mount-iso-sr
                try:
                    mountcmd = ["mount", location, self.mountpoint]
                    if options and options[0] == '-o':
                        pos = options[1].find('vers=')
                        if pos == -1:
                            options[1] += ',' + self.getSMBVersion()
                        else:
                            self.smbversion = self.getSMBVersionFromOptions(
                                options[1])
                            self.is_smbversion_specified = True
                    else:
                        raise ValueError
                    mountcmd.extend(options)
                except ValueError:
                    raise xs_errors.XenError('ISOInvalidXeMountOptions')
            # Check the validity of 'smbversion'.
            # Raise an exception for any invalid version.
            if self.smbversion not in [SMB_VERSION_1, SMB_VERSION_3]:
                raise xs_errors.XenError('ISOInvalidSMBversion')

        # Attempt mounting
        try:
            if protocol == 'nfs_iso':
                # For NFS, do a soft mount with tcp as protocol. Since ISO SR is
                # going to be r-only, a failure in nfs link can be reported back
                # to the process waiting.
                serv_path = location.split(':')
                util._testHost(serv_path[0], NFSPORT, 'NFSTarget')
                nfs.soft_mount(self.mountpoint,
                               serv_path[0],
                               serv_path[1],
                               'tcp',
                               useroptions=options,
                               nfsversion=self.nfsversion)
            else:
                smb3_fail_reason = None
                if self.smbversion in SMB_VERSION_3:
                    util.SMlog('ISOSR mount over smb 3.0')
                    try:
                        self.mountOverSMB(mountcmd)
                    except util.CommandException as inst:
                        if not self.is_smbversion_specified:
                            util.SMlog('Retrying ISOSR mount over smb 1.0')
                            smb3_fail_reason = inst.reason
                            # mountcmd is constructed such that the last two
                            # items will contain -o argument and its value.
                            del mountcmd[-2:]
                            self.smbversion = SMB_VERSION_1
                            if not options:
                                self.appendCIFSMountOptions(mountcmd)
                            else:
                                if options[0] == '-o':
                                    # regex can be used here since we have
                                    # already validated version entry
                                    options[1] = re.sub(
                                        'vers=3.0', 'vers=1.0', options[1])
                                mountcmd.extend(options)
                            self.mountOverSMB(mountcmd)
                        else:
                            raise xs_errors.XenError('ISOMountFailure',
                                                     opterr=inst.reason)
                else:
                    util.SMlog('ISOSR mount over smb 1.0')
                    self.mountOverSMB(mountcmd)
        except util.CommandException as inst:
            if not self.is_smbversion_specified:
                raise xs_errors.XenError('ISOMountFailure',
                                         opterr=smb3_fail_reason)
            else:
                raise xs_errors.XenError('ISOMountFailure', opterr=inst.reason)

        # Check the iso_path is accessible
        if not self._checkmount():
            self.detach(sr_uuid)
            raise xs_errors.XenError('ISOSharenameFailure')