Пример #1
0
    def load(self, vdi_uuid):
        self.lock = self.sr.lock

        self.sr.srcmd.params['o_direct'] = self.sr.o_direct

        if self.sr.srcmd.cmd == "vdi_create":
            self.vdi_type = vhdutil.VDI_TYPE_VHD
            self.key_hash = None
            if "vdi_sm_config" in self.sr.srcmd.params:
                if "key_hash" in self.sr.srcmd.params["vdi_sm_config"]:
                    self.key_hash = self.sr.srcmd.params["vdi_sm_config"][
                        "key_hash"]

                if "type" in self.sr.srcmd.params["vdi_sm_config"]:
                    vdi_type = self.sr.srcmd.params["vdi_sm_config"]["type"]
                    if not self.VDI_TYPE.get(vdi_type):
                        raise xs_errors.XenError('VDIType',
                                                 opterr='Invalid VDI type %s' %
                                                 vdi_type)
                    self.vdi_type = self.VDI_TYPE[vdi_type]
            self.path = os.path.join(self.sr.path, "%s%s" % \
                    (vdi_uuid, vhdutil.FILE_EXTN[self.vdi_type]))
        else:
            found = self._find_path_with_retries(vdi_uuid)
            if not found:
                if self.sr.srcmd.cmd == "vdi_delete":
                    # Could be delete for CBT log file
                    self.path = os.path.join(
                        self.sr.path, "%s.%s" % (vdi_uuid, self.PARAM_VHD))
                    return
                if self.sr.srcmd.cmd == "vdi_attach_from_config":
                    return
                raise xs_errors.XenError('VDIUnavailable',
                                         opterr="VDI %s not found" % vdi_uuid)


        if self.vdi_type == vhdutil.VDI_TYPE_VHD and \
                self.sr.__dict__.get("vhds") and self.sr.vhds.get(vdi_uuid):
            # VHD info already preloaded: use it instead of querying directly
            vhdInfo = self.sr.vhds[vdi_uuid]
            self.utilisation = vhdInfo.sizePhys
            self.size = vhdInfo.sizeVirt
            self.hidden = vhdInfo.hidden
            if self.hidden:
                self.managed = False
            self.parent = vhdInfo.parentUuid
            if self.parent:
                self.sm_config_override = {'vhd-parent': self.parent}
            else:
                self.sm_config_override = {'vhd-parent': None}
            return

        try:
            # Change to the SR directory in case parent
            # locator field path has changed
            os.chdir(self.sr.path)
        except Exception as chdir_exception:
            util.SMlog("Unable to change to SR directory, SR unavailable, %s" %
                       str(chdir_exception))
            raise xs_errors.XenError('SRUnavailable',
                                     opterr=str(chdir_exception))

        if util.ioretry(lambda: util.pathexists(self.path),
                        errlist=[errno.EIO, errno.ENOENT]):
            try:
                st = util.ioretry(lambda: os.stat(self.path),
                                  errlist=[errno.EIO, errno.ENOENT])
                self.utilisation = long(st.st_size)
            except util.CommandException as inst:
                if inst.code == errno.EIO:
                    raise xs_errors.XenError('VDILoad', \
                          opterr='Failed load VDI information %s' % self.path)
                else:
                    util.SMlog("Stat failed for %s, %s" %
                               (self.path, str(inst)))
                    raise xs_errors.XenError('VDIType', \
                          opterr='Invalid VDI type %s' % self.vdi_type)

            if self.vdi_type == vhdutil.VDI_TYPE_RAW:
                self.exists = True
                self.size = self.utilisation
                self.sm_config_override = {'type': self.PARAM_RAW}
                return

            if self.vdi_type == CBTLOG_TAG:
                self.exists = True
                self.size = self.utilisation
                return

            try:
                # The VDI might be activated in R/W mode so the VHD footer
                # won't be valid, use the back-up one instead.
                diskinfo = util.ioretry(
                    lambda: self._query_info(self.path, True),
                    errlist=[errno.EIO, errno.ENOENT])

                if 'parent' in diskinfo:
                    self.parent = diskinfo['parent']
                    self.sm_config_override = {'vhd-parent': self.parent}
                else:
                    self.sm_config_override = {'vhd-parent': None}
                    self.parent = ''
                self.size = long(diskinfo['size']) * 1024 * 1024
                self.hidden = long(diskinfo['hidden'])
                if self.hidden:
                    self.managed = False
                self.exists = True
            except util.CommandException as inst:
                raise xs_errors.XenError('VDILoad', \
                      opterr='Failed load VDI information %s' % self.path)
Пример #2
0
    def _snapshot(self, snap_type, cbtlog=None, cbt_consistency=None):
        util.SMlog("FileVDI._snapshot for %s (type %s)" %
                   (self.uuid, snap_type))

        args = []
        args.append("vdi_clone")
        args.append(self.sr.uuid)
        args.append(self.uuid)

        dest = None
        dst = None
        if snap_type == VDI.SNAPSHOT_DOUBLE:
            dest = util.gen_uuid()
            dst = os.path.join(self.sr.path, "%s.%s" % (dest, self.vdi_type))
            args.append(dest)

        if self.hidden:
            raise xs_errors.XenError('VDIClone', opterr='hidden VDI')

        depth = vhdutil.getDepth(self.path)
        if depth == -1:
            raise xs_errors.XenError('VDIUnavailable', \
                  opterr='failed to get VHD depth')
        elif depth >= vhdutil.MAX_CHAIN_SIZE:
            raise xs_errors.XenError('SnapshotChainTooLong')

        # Test the amount of actual disk space
        if ENFORCE_VIRT_ALLOC:
            self.sr._loadvdis()
            reserved = self.sr.virtual_allocation
            sr_size = self.sr._getsize()
            num_vdis = 2
            if (snap_type == VDI.SNAPSHOT_SINGLE
                    or snap_type == VDI.SNAPSHOT_INTERNAL):
                num_vdis = 1
            if (sr_size - reserved) < ((self.size + VDI.VDIMetadataSize( \
                    vhdutil.VDI_TYPE_VHD, self.size)) * num_vdis):
                raise xs_errors.XenError('SRNoSpace')

        newuuid = util.gen_uuid()
        src = self.path
        newsrc = os.path.join(self.sr.path, "%s.%s" % (newuuid, self.vdi_type))
        newsrcname = "%s.%s" % (newuuid, self.vdi_type)

        if not self._checkpath(src):
            raise xs_errors.XenError('VDIUnavailable', \
                  opterr='VDI %s unavailable %s' % (self.uuid, src))

        # wkcfix: multiphase
        util.start_log_entry(self.sr.path, self.path, args)

        # We assume the filehandle has been released
        try:
            util.ioretry(lambda: os.rename(src, newsrc))

            # Create the snapshot under a temporary name, then rename
            # it afterwards. This avoids a small window where it exists
            # but is invalid. We do not need to do this for
            # snap_type == VDI.SNAPSHOT_DOUBLE because dst never existed
            # before so nobody will try to query it.
            tmpsrc = "%s.%s" % (src, "new")
            util.ioretry(lambda: self._snap(tmpsrc, newsrcname))
            util.ioretry(lambda: os.rename(tmpsrc, src))
            if snap_type == VDI.SNAPSHOT_DOUBLE:
                util.ioretry(lambda: self._snap(dst, newsrcname))
            # mark the original file (in this case, its newsrc)
            # as hidden so that it does not show up in subsequent scans
            util.ioretry(lambda: self._mark_hidden(newsrc))

            #Verify parent locator field of both children and delete newsrc if unused
            introduce_parent = True
            try:
                srcparent = util.ioretry(lambda: self._query_p_uuid(src))
                dstparent = None
                if snap_type == VDI.SNAPSHOT_DOUBLE:
                    dstparent = util.ioretry(lambda: self._query_p_uuid(dst))
                if srcparent != newuuid and \
                        (snap_type == VDI.SNAPSHOT_SINGLE or \
                        snap_type == VDI.SNAPSHOT_INTERNAL or \
                        dstparent != newuuid):
                    util.ioretry(lambda: os.unlink(newsrc))
                    introduce_parent = False
            except:
                pass

            # Introduce the new VDI records
            leaf_vdi = None
            if snap_type == VDI.SNAPSHOT_DOUBLE:
                leaf_vdi = VDI.VDI(self.sr, dest)  # user-visible leaf VDI
                leaf_vdi.read_only = False
                leaf_vdi.location = dest
                leaf_vdi.size = self.size
                leaf_vdi.utilisation = self.utilisation
                leaf_vdi.sm_config = {}
                leaf_vdi.sm_config['vhd-parent'] = dstparent
                # If the parent is encrypted set the key_hash
                # for the new snapshot disk
                vdi_ref = self.sr.srcmd.params['vdi_ref']
                sm_config = self.session.xenapi.VDI.get_sm_config(vdi_ref)
                if "key_hash" in sm_config:
                    leaf_vdi.sm_config['key_hash'] = sm_config['key_hash']
                # If we have CBT enabled on the VDI,
                # set CBT status for the new snapshot disk
                if cbtlog:
                    leaf_vdi.cbt_enabled = True

            base_vdi = None
            if introduce_parent:
                base_vdi = VDI.VDI(self.sr, newuuid)  # readonly parent
                base_vdi.label = "base copy"
                base_vdi.read_only = True
                base_vdi.location = newuuid
                base_vdi.size = self.size
                base_vdi.utilisation = self.utilisation
                base_vdi.sm_config = {}
                grandparent = util.ioretry(lambda: self._query_p_uuid(newsrc))
                if grandparent.find("no parent") == -1:
                    base_vdi.sm_config['vhd-parent'] = grandparent

            try:
                if snap_type == VDI.SNAPSHOT_DOUBLE:
                    leaf_vdi_ref = leaf_vdi._db_introduce()
                    util.SMlog("vdi_clone: introduced VDI: %s (%s)" % \
                            (leaf_vdi_ref,dest))

                if introduce_parent:
                    base_vdi_ref = base_vdi._db_introduce()
                    self.session.xenapi.VDI.set_managed(base_vdi_ref, False)
                    util.SMlog("vdi_clone: introduced VDI: %s (%s)" %
                               (base_vdi_ref, newuuid))
                vdi_ref = self.sr.srcmd.params['vdi_ref']
                sm_config = self.session.xenapi.VDI.get_sm_config(vdi_ref)
                sm_config['vhd-parent'] = srcparent
                self.session.xenapi.VDI.set_sm_config(vdi_ref, sm_config)
            except Exception as e:
                util.SMlog(
                    "vdi_clone: caught error during VDI.db_introduce: %s" %
                    (str(e)))
                # Note it's too late to actually clean stuff up here: the base disk has
                # been marked as deleted already.
                util.end_log_entry(self.sr.path, self.path, ["error"])
                raise
        except util.CommandException as inst:
            # XXX: it might be too late if the base disk has been marked as deleted!
            self._clonecleanup(src, dst, newsrc)
            util.end_log_entry(self.sr.path, self.path, ["error"])
            raise xs_errors.XenError('VDIClone',
                                     opterr='VDI clone failed error %d' %
                                     inst.code)

        # Update cbt files if user created snapshot (SNAPSHOT_DOUBLE)
        if snap_type == VDI.SNAPSHOT_DOUBLE and cbtlog:
            try:
                self._cbt_snapshot(dest, cbt_consistency)
            except:
                # CBT operation failed.
                util.end_log_entry(self.sr.path, self.path, ["error"])
                raise

        util.end_log_entry(self.sr.path, self.path, ["done"])
        if snap_type != VDI.SNAPSHOT_INTERNAL:
            self.sr._update(self.sr.uuid, self.size)
        # Return info on the new user-visible leaf VDI
        ret_vdi = leaf_vdi
        if not ret_vdi:
            ret_vdi = base_vdi
        if not ret_vdi:
            ret_vdi = self
        return ret_vdi.get_params()
Пример #3
0
 def update(self, sr_uuid):
     if not self._checkmount():
         raise xs_errors.XenError('SRUnavailable', \
               opterr='no such directory %s' % self.path)
     self._update(sr_uuid, 0)
Пример #4
0
    def _loadvdis(self):
        if self.vdis:
            return

        pattern = os.path.join(self.path, "*%s" % vhdutil.FILE_EXTN_VHD)
        try:
            self.vhds = vhdutil.getAllVHDs(pattern, FileVDI.extractUuid)
        except util.CommandException as inst:
            raise xs_errors.XenError('SRScan', opterr="error VHD-scanning " \
                    "path %s (%s)" % (self.path, inst))
        try:
            list_vhds = [
                FileVDI.extractUuid(v)
                for v in util.ioretry(lambda: glob.glob(pattern))
            ]
            if len(self.vhds) != len(list_vhds):
                util.SMlog("VHD scan returns %d VHDs: %s" %
                           (len(self.vhds), sorted(list(self.vhds))))
                util.SMlog("VHD list returns %d VHDs: %s" %
                           (len(list_vhds), sorted(list_vhds)))
        except:
            pass
        for uuid in self.vhds.iterkeys():
            if self.vhds[uuid].error:
                raise xs_errors.XenError('SRScan', opterr='uuid=%s' % uuid)
            self.vdis[uuid] = self.vdi(uuid, True)
            # Get the key hash of any encrypted VDIs:
            vhd_path = os.path.join(self.path, self.vhds[uuid].path)
            key_hash = vhdutil.getKeyHash(vhd_path)
            self.vdis[uuid].sm_config_override['key_hash'] = key_hash

        # raw VDIs and CBT log files
        files = util.ioretry(lambda: util.listdir(self.path))
        for fn in files:
            if fn.endswith(vhdutil.FILE_EXTN_RAW):
                uuid = fn[:-(len(vhdutil.FILE_EXTN_RAW))]
                self.vdis[uuid] = self.vdi(uuid, True)
            elif fn.endswith(CBTLOG_TAG):
                cbt_uuid = fn.split(".")[0]
                # If an associated disk exists, update CBT status
                # else create new VDI of type cbt_metadata
                if cbt_uuid in self.vdis:
                    self.vdis[cbt_uuid].cbt_enabled = True
                else:
                    new_vdi = self.vdi(cbt_uuid)
                    new_vdi.ty = "cbt_metadata"
                    new_vdi.cbt_enabled = True
                    self.vdis[cbt_uuid] = new_vdi

        # Mark parent VDIs as Read-only and generate virtual allocation
        self.virtual_allocation = 0
        for uuid, vdi in self.vdis.iteritems():
            if vdi.parent:
                if vdi.parent in self.vdis:
                    self.vdis[vdi.parent].read_only = True
                if vdi.parent in geneology:
                    geneology[vdi.parent].append(uuid)
                else:
                    geneology[vdi.parent] = [uuid]
            if not vdi.hidden:
                self.virtual_allocation += (vdi.size)

        # now remove all hidden leaf nodes from self.vdis so that they are not
        # introduced into the Agent DB when SR is synchronized. With the
        # asynchronous GC, a deleted VDI might stay around until the next
        # SR.scan, so if we don't ignore hidden leaves we would pick up
        # freshly-deleted VDIs as newly-added VDIs
        for uuid in self.vdis.keys():
            if uuid not in geneology and self.vdis[uuid].hidden:
                util.SMlog("Scan found hidden leaf (%s), ignoring" % uuid)
                del self.vdis[uuid]
Пример #5
0
    def _run(self, sr, target):
        dconf_type = sr.dconf.get("type")
        if not dconf_type or not NO_LOGGING.get(dconf_type) or \
                not self.cmd in NO_LOGGING[dconf_type]:
            util.SMlog("%s %s" % (self.cmd, repr(self.params)))
        caching_params = dict((k, self.params.get(k)) for k in \
                [blktap2.VDI.CONF_KEY_ALLOW_CACHING,
                 blktap2.VDI.CONF_KEY_MODE_ON_BOOT,
                 blktap2.VDI.CONF_KEY_CACHE_SR])

        if self.cmd == 'vdi_create':
            # These are the fields owned by the backend, passed on the
            # commandline:
            target.label = self.params['args'][1]
            target.description = self.params['args'][2]
            target.ty = self.params['vdi_type']
            target.metadata_of_pool = self.params['args'][3]
            target.is_a_snapshot = self.params['args'][4] == "true"
            target.snapshot_time = self.params['args'][5]
            target.snapshot_of = self.params['args'][6]
            target.read_only = self.params['args'][7] == "true"

            return target.create(self.params['sr_uuid'], self.vdi_uuid,
                                 long(self.params['args'][0]))

        elif self.cmd == 'vdi_update':
            return target.update(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_introduce':
            target = sr.vdi(self.params['new_uuid'])
            return target.introduce(self.params['sr_uuid'],
                                    self.params['new_uuid'])

        elif self.cmd == 'vdi_delete':
            return target.delete(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_attach':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            writable = self.params['args'][0] == 'true'
            return target.attach(self.params['sr_uuid'], self.vdi_uuid,
                                 writable)

        elif self.cmd == 'vdi_detach':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            return target.detach(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_snapshot':
            return target.snapshot(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_clone':
            return target.clone(self.params['sr_uuid'], self.vdi_uuid)

        elif self.cmd == 'vdi_resize':
            return target.resize(self.params['sr_uuid'], self.vdi_uuid,
                                 long(self.params['args'][0]))

        elif self.cmd == 'vdi_resize_online':
            return target.resize_online(self.params['sr_uuid'], self.vdi_uuid,
                                        long(self.params['args'][0]))

        elif self.cmd == 'vdi_activate':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            writable = self.params['args'][0] == 'true'
            return target.activate(self.params['sr_uuid'], self.vdi_uuid,
                                   writable, caching_params)

        elif self.cmd == 'vdi_deactivate':
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            return target.deactivate(self.params['sr_uuid'], self.vdi_uuid,
                                     caching_params)

        elif self.cmd == 'vdi_generate_config':
            return target.generate_config(self.params['sr_uuid'],
                                          self.vdi_uuid)

        elif self.cmd == 'vdi_attach_from_config':
            ret = target.attach_from_config(self.params['sr_uuid'],
                                            self.vdi_uuid)
            if not target.sr.driver_config.get(
                    "ATTACH_FROM_CONFIG_WITH_TAPDISK"):
                return ret
            target = blktap2.VDI(self.vdi_uuid, target, self.driver_info)
            return target.attach(self.params['sr_uuid'], self.vdi_uuid, True,
                                 True)

        elif self.cmd == 'sr_create':
            return sr.create(self.params['sr_uuid'],
                             long(self.params['args'][0]))

        elif self.cmd == 'sr_delete':
            return sr.delete(self.params['sr_uuid'])

        elif self.cmd == 'sr_update':
            return sr.update(self.params['sr_uuid'])

        elif self.cmd == 'sr_probe':
            txt = sr.probe()
            util.SMlog("sr_probe result: %s" % txt)
            # return the XML document as a string
            return xmlrpclib.dumps((txt, ), "", True)

        elif self.cmd == 'sr_attach':
            is_master = False
            if sr.dconf.get("SRmaster") == "true":
                is_master = True

            resetvdis.reset(sr.session, util.get_this_host(),
                            self.params['sr_uuid'], is_master)

            if is_master:
                # Schedule a scan only when attaching on the SRmaster
                util.set_dirty(sr.session, self.params["sr_ref"])

            return sr.attach(self.params['sr_uuid'])

        elif self.cmd == 'sr_detach':
            return sr.detach(self.params['sr_uuid'])

        elif self.cmd == 'sr_content_type':
            return sr.content_type(self.params['sr_uuid'])

        elif self.cmd == 'sr_scan':
            return sr.scan(self.params['sr_uuid'])

        else:
            util.SMlog("Unknown command: %s" % self.cmd)
            raise xs_errors.XenError('BadRequest')
Пример #6
0
 def mount(self, mountpoint, remotepath):
     try:
         nfs.soft_mount(mountpoint, self.remoteserver, remotepath, self.transport)
     except nfs.NfsException, exc:
         raise xs_errors.XenError('NFSMount', opterr=exc.errstr)
Пример #7
0
    def load(self, sr_uuid):
        if self.force_tapdisk:
            self.sr_vditype = 'aio'
        else:
            self.sr_vditype = 'phy'
        self.discoverentry = 0
        self.default_vdi_visibility = False

        # Required parameters
        if not self.dconf.has_key('target') or not self.dconf['target']:
            raise xs_errors.XenError('ConfigTargetMissing')

        # we are no longer putting hconf in the xml.
        # Instead we pass a session and host ref and let the SM backend query XAPI itself
        try:
            if not self.dconf.has_key('localIQN'):
                self.localIQN = self.session.xenapi.host.get_other_config(
                    self.host_ref)['iscsi_iqn']
            else:
                self.localIQN = self.dconf['localIQN']
        except:
            raise xs_errors.XenError('ConfigISCSIIQNMissing')

        # Check for empty string
        if not self.localIQN:
            raise xs_errors.XenError('ConfigISCSIIQNMissing')

        try:
            self.target = util._convertDNS(self.dconf['target'].split(',')[0])
        except:
            raise xs_errors.XenError('DNSError')

        self.targetlist = self.target
        if self.dconf.has_key('targetlist'):
            self.targetlist = self.dconf['targetlist']

        # Optional parameters
        self.chapuser = ""
        self.chappassword = ""
        if self.dconf.has_key('chapuser') \
                and (self.dconf.has_key('chappassword') or self.dconf.has_key('chappassword_secret')):
            self.chapuser = self.dconf['chapuser'].encode('utf-8')
            if self.dconf.has_key('chappassword_secret'):
                self.chappassword = util.get_secret(
                    self.session, self.dconf['chappassword_secret'])
            else:
                self.chappassword = self.dconf['chappassword']

            self.chappassword = self.chappassword.encode('utf-8')

        self.incoming_chapuser = ""
        self.incoming_chappassword = ""
        if self.dconf.has_key('incoming_chapuser') \
                and (self.dconf.has_key('incoming_chappassword') or self.dconf.has_key('incoming_chappassword_secret')):
            self.incoming_chapuser = self.dconf['incoming_chapuser'].encode(
                'utf-8')
            if self.dconf.has_key('incoming_chappassword_secret'):
                self.incoming_chappassword = util.get_secret(
                    self.session, self.dconf['incoming_chappassword_secret'])
            else:
                self.incoming_chappassword = self.dconf[
                    'incoming_chappassword']

            self.incoming_chappassword = self.incoming_chappassword.encode(
                'utf-8')

        self.port = DEFAULT_PORT
        if self.dconf.has_key('port') and self.dconf['port']:
            try:
                self.port = long(self.dconf['port'])
            except:
                raise xs_errors.XenError('ISCSIPort')
        if self.port > MAXPORT or self.port < 1:
            raise xs_errors.XenError('ISCSIPort')

        # For backwards compatibility
        if self.dconf.has_key('usediscoverynumber'):
            self.discoverentry = self.dconf['usediscoverynumber']

        self.multihomed = False
        if self.dconf.has_key('multihomed'):
            if self.dconf['multihomed'] == "true":
                self.multihomed = True
        elif self.mpath == 'true':
            self.multihomed = True

        if not self.dconf.has_key('targetIQN') or not self.dconf['targetIQN']:
            self._scan_IQNs()
            raise xs_errors.XenError('ConfigTargetIQNMissing')

        self.targetIQN = unicode(self.dconf['targetIQN']).encode('utf-8')

        self._attached = None
        self._pathdict = None
        self._adapter = None
        self._devs = None
        self._tgtidx = None
        self._path = None
        self._address = None
Пример #8
0
        try:
            self.mount()
        except CephFSException, exc:
            # noinspection PyBroadException
            try:
                os.rmdir(self.mountpoint)
            except:
                # we have no recovery strategy
                pass
            raise SR.SROSError(111,
                               "CephFS mount error [opterr=%s]" % exc.errstr)

        if util.ioretry(lambda: util.pathexists(self.linkpath)):
            if len(util.ioretry(lambda: util.listdir(self.linkpath))) != 0:
                self.detach(sr_uuid)
                raise xs_errors.XenError('SRExists')
        else:
            try:
                util.ioretry(lambda: util.makedirs(self.linkpath))
                os.symlink(self.linkpath, self.path)
            except util.CommandException, inst:
                if inst.code != errno.EEXIST:
                    try:
                        self.unmount(self.mountpoint, True)
                    except CephFSException:
                        util.logException('CephFSSR.unmount()')
                    raise SR.SROSError(
                        116,
                        "Failed to create CephFS SR. remote directory creation error: {}"
                        .format(os.strerror(inst.code)))
        self.detach(sr_uuid)
Пример #9
0
                      opterr='Unable to activate LV. Errno is %d' % inst.code)

            try:
                util.pread(["fsck", "-a", self.remotepath])
            except util.CommandException, inst:
                if inst.code == 1:
                    util.SMlog(
                        "FSCK detected and corrected FS errors. Not fatal.")
                else:
                    raise xs_errors.XenError('LVMMount', \
                         opterr='FSCK failed on %s. Errno is %d' % (self.remotepath,inst.code))

            try:
                util.pread(["mount", self.remotepath, self.path])
            except util.CommandException, inst:
                raise xs_errors.XenError('LVMMount', \
                      opterr='Failed to mount FS. Errno is %d' % inst.code)

        self.attached = True

        #Update SCSIid string
        scsiutil.add_serial_record(self.session, self.sr_ref, \
                scsiutil.devlist_to_serialstring(self.root.split(',')))

        # Set the block scheduler
        for dev in self.root.split(','):
            self.block_setscheduler(dev)

    def detach(self, sr_uuid):
        super(EXTSR, self).detach(sr_uuid)
        try:
            # deactivate SR
Пример #10
0
        if self.checkmount():
            raise xs_errors.XenError('SMBAttached')

        try:
            self.mount()
        except SMBException, exc:
            try:
                os.rmdir(self.mountpoint)
            except:
                pass
            raise xs_errors.XenError('SMBMount', opterr=exc.errstr)

        if util.ioretry(lambda: util.pathexists(self.linkpath)):
            if len(util.ioretry(lambda: util.listdir(self.linkpath))) != 0:
                self.detach(sr_uuid)
                raise xs_errors.XenError('SRExists')
        else:
            try:
                util.ioretry(lambda: util.makedirs(self.linkpath))
                os.symlink(self.linkpath, self.path)
            except util.CommandException, inst:
                if inst.code != errno.EEXIST:
                    try:
                        self.unmount(self.mountpoint, True)
                    except SMBException:
                        util.logException('SMBSR.unmount()')
                    raise xs_errors.XenError(
                        'SMBCreate',
                        opterr="remote directory creation error: {}".format(
                            os.strerror(inst.code)))
        self.detach(sr_uuid)
Пример #11
0
    def attach(self, sr_uuid, vdi_uuid):
        util.SMlog("RBDVDI.attach for %s" % self.uuid)

        vdi_ref = self.session.xenapi.VDI.get_by_uuid(vdi_uuid)
        sm_config = self.session.xenapi.VDI.get_sm_config(vdi_ref)

        if sm_config.has_key("snapshot-of"):
            base_uuid = sm_config["snapshot-of"]
            # it's a snapshot VDI
            self.path = self.sr._get_snap_path(base_uuid, vdi_uuid)
        else:
            self.path = self.sr._get_path(vdi_uuid)

        if not hasattr(self, 'xenstore_data'):
            self.xenstore_data = {}

        self.xenstore_data.update(
            scsiutil.update_XS_SCSIdata(
                self.uuid, scsiutil.gen_synthetic_page_data(self.uuid)))

        self.xenstore_data['storage-type'] = 'rbd'
        self.xenstore_data['vdi-type'] = self.vdi_type

        self.attached = True
        self.session.xenapi.VDI.remove_from_sm_config(vdi_ref, 'attached')
        self.session.xenapi.VDI.add_to_sm_config(vdi_ref, 'attached', 'true')

        self.size = int(self.session.xenapi.VDI.get_virtual_size(vdi_ref))

        ##########
        vdis = self.session.xenapi.SR.get_VDIs(self.sr.sr_ref)
        has_a_snapshot = False
        for tmp_vdi in vdis:
            tmp_vdi_uuid = self.session.xenapi.VDI.get_uuid(tmp_vdi)
            tmp_sm_config = self.session.xenapi.VDI.get_sm_config(tmp_vdi)
            if tmp_sm_config.has_key("snapshot-of"):
                if tmp_sm_config["snapshot-of"] == vdi_uuid:
                    has_a_snapshot = True
            if tmp_sm_config.has_key("sxm_mirror"):
                sxm_mirror_vdi = vdi_uuid
        ########## SXM VDIs
        if sm_config.has_key("base_mirror"):
            if has_a_snapshot:
                # it's a mirror vdi of storage migrating VM
                # it's attached first
                self.session.xenapi.VDI.add_to_sm_config(
                    vdi_ref, 'sxm_mirror', 'true')
                # creating dm snapshot dev
                self._setup_mirror(vdi_uuid, self.size)
            else:
                # it's a base vdi of storage migrating VM
                # it's attached after mirror VDI and mirror snapshot VDI has been created
                self._map_VHD(vdi_uuid)
        ########## not SXM VDIs
        elif sm_config.has_key("snapshot-of"):
            base_uuid = sm_config["snapshot-of"]
            # it's a snapshot VDI, attach it as snapshot
            self._map_SNAP(base_uuid, vdi_uuid)
        else:
            # it's not SXM VDI, just attach it
            self._map_VHD(vdi_uuid)

        if not util.pathexists(self.path):
            raise xs_errors.XenError('VDIUnavailable',
                                     opterr='Could not find: %s' % self.path)

        return VDI.VDI.attach(self, self.sr.uuid, self.uuid)
Пример #12
0
    def attach(self, sr_uuid):
        self._mpathHandle()

        npaths = 0
        if not self.attached:
            # Verify iSCSI target and port
            if self.dconf.has_key('multihomelist'
                                  ) and not self.dconf.has_key('multiSession'):
                targetlist = self.dconf['multihomelist'].split(',')
            else:
                targetlist = ['%s:%d' % (self.target, self.port)]
            conn = False
            for val in targetlist:
                (target, port) = val.split(':')
                try:
                    util._testHost(target, long(port), 'ISCSITarget')
                    self.target = target
                    self.port = long(port)
                    conn = True
                    break
                except:
                    pass
            if not conn:
                raise xs_errors.XenError('ISCSITarget')

            # Test and set the initiatorname file
            iscsilib.ensure_daemon_running_ok(self.localIQN)

            # Check to see if auto attach was set
            if not iscsilib._checkTGT(self.targetIQN):
                try:
                    map = iscsilib.discovery(self.target, self.port, self.chapuser, \
                                             self.chappassword, targetIQN=self.targetIQN)
                    iqn = ''
                    if len(map) == 0:
                        self._scan_IQNs()
                        raise xs_errors.XenError(
                            'ISCSIDiscovery', opterr='check target settings')
                    for i in range(0, len(map)):
                        (portal, tpgt, iqn) = map[i]
                        try:
                            (ipaddr, port) = portal.split(',')[0].split(':')
                            if not self.multihomed and ipaddr != self.target:
                                continue
                            util._testHost(ipaddr, long(port), 'ISCSITarget')
                            util.SMlog("Logging in to [%s:%s]" %
                                       (ipaddr, port))
                            iscsilib.login(portal, iqn, self.chapuser,
                                           self.chappassword,
                                           self.incoming_chapuser,
                                           self.incoming_chappassword)
                            npaths = npaths + 1
                        except:
                            pass

                    if not iscsilib._checkTGT(self.targetIQN):
                        raise xs_errors.XenError('ISCSIDevice', \
                                                 opterr='during login')

                    # Allow the devices to settle
                    time.sleep(5)

                except util.CommandException, inst:
                    raise xs_errors.XenError('ISCSILogin', \
                                             opterr='code is %d' % inst.code)
            self.attached = True
Пример #13
0
def scan(srobj):
    systemrootID = util.getrootdevID()
    hbadict = srobj.hbadict
    hbas = srobj.hbas
    dom = xml.dom.minidom.Document()
    e = dom.createElement("Devlist")
    dom.appendChild(e)

    if not os.path.exists(DEVPATH):
        return dom.toprettyxml()

    devs = srobj.devs
    vdis = {}

    for key in hbadict:
        hba = hbadict[key]
        path = os.path.join("/dev", key)
        realpath = path

        obj = srobj.vdi("")
        try:
            obj._query(realpath, devs[realpath][4])
        except:
            continue

        # Test for root dev or existing PBD
        if len(obj.SCSIid) and len(systemrootID) and util.match_scsiID(
                obj.SCSIid, systemrootID):
            util.SMlog("Ignoring root device %s" % realpath)
            continue
        elif util.test_SCSIid(srobj.session, None, obj.SCSIid):
            util.SMlog("SCSIid in use, ignoring (%s)" % obj.SCSIid)
            continue
        elif not devs.has_key(realpath):
            continue

        ids = devs[realpath]
        obj.adapter = ids[1]
        obj.channel = ids[2]
        obj.id = ids[3]
        obj.lun = ids[4]
        obj.hba = hba['procname']
        if hba['eth']:
            obj.eth = hba['eth']
        obj.numpaths = 1
        if vdis.has_key(obj.SCSIid):
            vdis[obj.SCSIid].numpaths += 1
            vdis[obj.SCSIid].path += " [%s]" % key
        elif obj.hba == 'mpp':
            mppdict = _genMPPHBA(obj.adapter)
            if mppdict.has_key(key):
                item = mppdict[key]
                adapters = ''
                for i in item:
                    if len(adapters):
                        adapters += ', '
                        obj.numpaths += 1
                    adapters += i
                if len(adapters):
                    obj.mpp = adapters
            vdis[obj.SCSIid] = obj
        else:
            vdis[obj.SCSIid] = obj

    for key in vdis:
        obj = vdis[key]
        d = dom.createElement("BlockDevice")
        e.appendChild(d)

        for attr in [
                'path', 'numpaths', 'SCSIid', 'vendor', 'serial', 'size',
                'adapter', 'channel', 'id', 'lun', 'hba', 'mpp', 'eth'
        ]:
            try:
                aval = getattr(obj, attr)
            except AttributeError:
                if attr in ['mpp'] or attr in ['eth']:
                    continue
                raise xs_errors.XenError('InvalidArg', \
                      opterr='Missing required field [%s]' % attr)
            entry = dom.createElement(attr)
            d.appendChild(entry)
            textnode = dom.createTextNode(str(aval))
            entry.appendChild(textnode)

    for key in hbas.iterkeys():
        a = dom.createElement("Adapter")
        e.appendChild(a)
        entry = dom.createElement('host')
        a.appendChild(entry)
        textnode = dom.createTextNode(key)
        entry.appendChild(textnode)

        entry = dom.createElement('name')
        a.appendChild(entry)
        textnode = dom.createTextNode(hbas[key])
        entry.appendChild(textnode)

        entry = dom.createElement('manufacturer')
        a.appendChild(entry)
        textnode = dom.createTextNode(getManufacturer(hbas[key]))
        entry.appendChild(textnode)

        id = key.replace("host", "")
        entry = dom.createElement('id')
        a.appendChild(entry)
        textnode = dom.createTextNode(id)
        entry.appendChild(textnode)

        _add_host_parameters_to_adapter(dom, a, 'fc_host', id, [
            'node_name', 'port_name', 'port_state', 'speed', 'supported_speeds'
        ])
        _add_host_parameters_to_adapter(dom, a, 'iscsi_host', id, [
            'hwaddress', 'initiatorname', 'ipaddress', 'port_speed',
            'port_state'
        ])

    return dom.toprettyxml()
Пример #14
0
 def get_params(self):
     if not self._checkpath(self.path):
         raise xs_errors.XenError('VDIUnavailable', \
               opterr='VDI %s unavailable %s' % (self.uuid, self.path))
     return super(FileVDI, self).get_params()
Пример #15
0
    def attach(self, sr_uuid):
        self._mpathHandle()

        multiTargets = False

        npaths = 0
        try:
            pbdref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref)
            if pbdref:
                other_config = self.session.xenapi.PBD.get_other_config(pbdref)
                multiTargets = util.sessions_less_than_targets(
                    other_config, self.dconf)
        except:
            pass

        if not self.attached or multiTargets:
            # Verify iSCSI target and port
            if self.dconf.has_key('multihomelist'
                                  ) and not self.dconf.has_key('multiSession'):
                targetlist = self.dconf['multihomelist'].split(',')
            else:
                targetlist = ['%s:%d' % (self.target, self.port)]
            conn = False
            for val in targetlist:
                (target, port) = iscsilib.parse_IP_port(val)
                try:
                    util._testHost(target, long(port), 'ISCSITarget')
                    self.target = target
                    self.port = long(port)
                    conn = True
                    break
                except:
                    pass
            if not conn:
                raise xs_errors.XenError('ISCSITarget')

            # Test and set the initiatorname file
            iscsilib.ensure_daemon_running_ok(self.localIQN)

            # Check to see if auto attach was set
            if not iscsilib._checkTGT(self.targetIQN) or multiTargets:
                try:
                    map = []
                    if 'any' != self.targetIQN:
                        try:
                            map = iscsilib.get_node_records(self.targetIQN)
                        except:
                            # Pass the exception that is thrown, when there
                            # are no nodes
                            pass
                    if len(map) == 0:
                        map = iscsilib.discovery(
                            self.target, self.port, self.chapuser,
                            self.chappassword, self.targetIQN,
                            iscsilib.get_iscsi_interfaces())
                    if len(map) == 0:
                        self._scan_IQNs()
                        raise xs_errors.XenError(
                            'ISCSIDiscovery', opterr='check target settings')
                    for i in range(0, len(map)):
                        (portal, tpgt, iqn) = map[i]
                        try:
                            (ipaddr, port) = iscsilib.parse_IP_port(portal)
                            if not self.multihomed and ipaddr != self.target:
                                continue
                            util._testHost(ipaddr, long(port), 'ISCSITarget')
                            util.SMlog("Logging in to [%s:%s]" %
                                       (ipaddr, port))
                            iscsilib.login(portal, iqn, self.chapuser,
                                           self.chappassword,
                                           self.incoming_chapuser,
                                           self.incoming_chappassword,
                                           self.mpath == "true")
                            npaths = npaths + 1
                        except Exception, e:
                            # Exceptions thrown in login are acknowledged,
                            # the rest of exceptions are ignored since some of the
                            # paths in multipath may not be reachable
                            if str(e).startswith('ISCSI login'):
                                raise
                            else:
                                pass

                    if not iscsilib._checkTGT(self.targetIQN):
                        raise xs_errors.XenError('ISCSIDevice', \
                                                 opterr='during login')

                    # Allow the devices to settle
                    time.sleep(5)

                except util.CommandException, inst:
                    raise xs_errors.XenError('ISCSILogin', \
                                             opterr='code is %d' % inst.code)
Пример #16
0
    def attach(self, sr_uuid, vdi_uuid):
        if self.deleted:
            raise xs_errors.XenError('VDIUnavailable')

        return super(udevVDI, self).attach(sr_uuid, vdi_uuid)
Пример #17
0
 def check_server(self):
     try:
         nfs.check_server_tcp(self.remoteserver)
     except nfs.NfsException, exc:
         raise xs_errors.XenError('NFSVersion',
                                  opterr=exc.errstr)
Пример #18
0
        self.remotepath = self.dconf['serverpath']
        try:
            self.mount_remotepath(sr_uuid)
        except Exception, exn:
            try:
                os.rmdir(self.path)
            except:
                pass
            raise exn

        if not self.nosubdir:
            newpath = os.path.join(self.path, sr_uuid)
            if util.ioretry(lambda: util.pathexists(newpath)):
                if len(util.ioretry(lambda: util.listdir(newpath))) != 0:
                    self.detach(sr_uuid)
                    raise xs_errors.XenError('SRExists')
            else:
                try:
                    util.ioretry(lambda: util.makedirs(newpath))
                except util.CommandException, inst:
                    if inst.code != errno.EEXIST:
                        self.detach(sr_uuid)
                        raise xs_errors.XenError(
                            'NFSCreate',
                            opterr='remote directory creation error is %d' %
                            inst.code)
        self.detach(sr_uuid)

    def delete(self, sr_uuid):
        # try to remove/delete non VDI contents first
        super(NFSSR, self).delete(sr_uuid)
Пример #19
0
 def attach_from_config(self, sr_uuid, vdi_uuid):
     self.sr.iscsi.attach(sr_uuid)
     if not self.sr.iscsi._attach_LUN_bySCSIid(self.sr.SCSIid):
         raise xs_errors.XenError('InvalidDev')
     return super(LVMoISCSIVDI, self).attach(sr_uuid, vdi_uuid)