示例#1
0
文件: BaseISCSI.py 项目: stormi/sm
    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 'multihomelist' in self.dconf and 'multiSession' not in self.dconf:
                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 as 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 as inst:
                    raise xs_errors.XenError('ISCSILogin', \
                                             opterr='code is %d' % inst.code)
            self.attached = True
        self._initPaths()
        util._incr_iscsiSR_refcount(self.targetIQN, sr_uuid)
        IQNs = []
        if "multiSession" in self.dconf:
            IQNs = ""
            for iqn in self.dconf['multiSession'].split("|"):
                if len(iqn): IQNs += iqn.split(',')[2]
        else:
            IQNs.append(self.targetIQN)
        sessions = 0
        paths = iscsilib.get_IQN_paths()
        for path in paths:
            try:
                if util.get_single_entry(os.path.join(path,
                                                      'targetname')) in IQNs:
                    sessions += 1
                    util.SMlog("IQN match. Incrementing sessions to %d" %
                               sessions)
            except:
                util.SMlog("Failed to read targetname path," \
                           + "iscsi_sessions value may be incorrect")

        if pbdref:
            # Just to be safe in case of garbage left during crashes
            # we remove the key and add it
            self.session.xenapi.PBD.remove_from_other_config(
                pbdref, "iscsi_sessions")
            self.session.xenapi.PBD.add_to_other_config(
                pbdref, "iscsi_sessions", str(sessions))

        if 'SCSIid' in self.dconf:
            if self.mpath == 'true':
                self.mpathmodule.refresh(self.dconf['SCSIid'], 0)
            devs = os.listdir("/dev/disk/by-scsid/%s" % self.dconf['SCSIid'])
            for dev in devs:
                realdev = os.path.realpath("/dev/disk/by-scsid/%s/%s" %
                                           (self.dconf['SCSIid'], dev))
                util.set_scheduler(realdev.split("/")[-1], "noop")
示例#2
0
                            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)
            self.attached = True
        self._initPaths()
        util._incr_iscsiSR_refcount(self.targetIQN, sr_uuid)
        IQNs = []
        if self.dconf.has_key("multiSession"):
            IQNs = ""
            for iqn in self.dconf['multiSession'].split("|"):
                if len(iqn): IQNs += iqn.split(',')[2]
        else:
            IQNs.append(self.targetIQN)
        sessions = 0
        paths = iscsilib.get_IQN_paths()
        for path in paths:
            try:
                if util.get_single_entry(os.path.join(path,
                                                      'targetname')) in IQNs:
                    sessions += 1
                    util.SMlog("IQN match. Incrementing sessions to %d" %
示例#3
0
文件: ISCSISR.py 项目: fudong1127/sm
                            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)
            self.attached = True
        self._initPaths()
        util._incr_iscsiSR_refcount(self.targetIQN, sr_uuid)
        IQNs = []
        if self.dconf.has_key("multiSession"):
            IQNs = ""
            for iqn in self.dconf['multiSession'].split("|"):
                if len(iqn): IQNs += iqn.split(',')[2]
        else:
            IQNs.append(self.targetIQN)
        sessions = 0
        paths = iscsilib.get_IQN_paths()
        for path in paths:
            try:
                if util.get_single_entry(os.path.join(path, 'targetname')) in IQNs:
                    sessions += 1
                    util.SMlog("IQN match. Incrementing sessions to %d" % sessions)
            except:
class ISCSISR(SR.SR):
    """ISCSI storage repository"""
    def handles(type):
        if type == "iscsi":
            return True
        return False

    handles = staticmethod(handles)

    def _synchroniseAddrList(self, addrlist):
        if not self.multihomed:
            return
        change = False
        if not self.dconf.has_key('multihomelist'):
            change = True
            self.mlist = []
            mstr = ""
        else:
            self.mlist = self.dconf['multihomelist'].split(',')
            mstr = self.dconf['multihomelist']
        for val in addrlist:
            if not val in self.mlist:
                self.mlist.append(val)
                if len(mstr):
                    mstr += ","
                mstr += val
                change = True
        if change:
            pbd = None
            try:
                pbd = util.find_my_pbd(self.session, self.host_ref,
                                       self.sr_ref)
                if pbd <> None:
                    device_config = self.session.xenapi.PBD.get_device_config(
                        pbd)
                    device_config['multihomelist'] = mstr
                    self.session.xenapi.PBD.set_device_config(
                        pbd, device_config)
            except:
                pass

    def load(self, sr_uuid):
        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']
            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.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']
            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.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 = self.dconf['targetIQN']
        self.attached = False
        try:
            self.attached = iscsilib._checkTGT(self.targetIQN)
        except:
            pass
        self._initPaths()

    def _initPaths(self):
        self._init_adapters()
        # Generate a list of all possible paths
        self.pathdict = {}
        addrlist = []
        rec = {}
        key = "%s:%d" % (self.target, self.port)
        rec['ipaddr'] = self.target
        rec['port'] = self.port
        rec['path'] = os.path.join("/dev/iscsi",self.targetIQN,\
                                   key)
        self.pathdict[key] = rec
        util.SMlog("PATHDICT: key %s: %s" % (key, rec))
        self.tgtidx = key
        addrlist.append(key)

        self.path = rec['path']
        self.address = self.tgtidx
        if not self.attached:
            return

        if self.multihomed:
            map = iscsilib.get_node_records(targetIQN=self.targetIQN)
            for i in range(0, len(map)):
                (portal, tpgt, iqn) = map[i]
                (ipaddr, port) = portal.split(',')[0].split(':')
                if self.target != ipaddr:
                    key = "%s:%s" % (ipaddr, port)
                    rec = {}
                    rec['ipaddr'] = ipaddr
                    rec['port'] = long(port)
                    rec['path'] = os.path.join("/dev/iscsi",self.targetIQN,\
                                   key)
                    self.pathdict[key] = rec
                    util.SMlog("PATHDICT: key %s: %s" % (key, rec))
                    addrlist.append(key)

        # Try to detect an active path in order of priority
        for key in self.pathdict:
            if self.adapter.has_key(key):
                self.tgtidx = key
                self.path = self.pathdict[self.tgtidx]['path']
                if os.path.exists(self.path):
                    util.SMlog("Path found: %s" % self.path)
                    break
        self.address = self.tgtidx
        self._synchroniseAddrList(addrlist)

    def _init_adapters(self):
        # Generate a list of active adapters
        ids = scsiutil._genHostList(ISCSI_PROCNAME)
        util.SMlog(ids)
        self.adapter = {}
        for host in ids:
            try:
                targetIQN = util.get_single_entry(glob.glob(\
                    '/sys/class/iscsi_host/host%s/device/session*/iscsi_session*/targetname' % host)[0])
                if targetIQN != self.targetIQN:
                    continue
                addr = util.get_single_entry(glob.glob(\
                    '/sys/class/iscsi_host/host%s/device/session*/connection*/iscsi_connection*/persistent_address' % host)[0])
                port = util.get_single_entry(glob.glob(\
                    '/sys/class/iscsi_host/host%s/device/session*/connection*/iscsi_connection*/persistent_port' % host)[0])
                entry = "%s:%s" % (addr, port)
                self.adapter[entry] = host
            except:
                pass
        self.devs = scsiutil.cacheSCSIidentifiers()

    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
        self._initPaths()
        util._incr_iscsiSR_refcount(self.targetIQN, sr_uuid)
        IQNs = []
        if self.dconf.has_key("multiSession"):
            IQNs = ""
            for iqn in self.dconf['multiSession'].split("|"):
                if len(iqn): IQNs += iqn.split(',')[2]
        else:
            IQNs.append(self.targetIQN)
        sessions = 0
        paths = glob.glob(\
                    '/sys/class/iscsi_host/host*/device/session*/iscsi_session*/targetname')
        for path in paths:
            try:
                if util.get_single_entry(path) in IQNs:
                    sessions += 1
                    util.SMlog("IQN match. Incrementing sessions to %d" %
                               sessions)
            except:
                util.SMlog("Failed to read targetname path," \
                           + "iscsi_sessions value may be incorrect")

        try:
            pbdref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref)
            if pbdref <> None:
                other_conf = self.session.xenapi.PBD.get_other_config(pbdref)
                other_conf['iscsi_sessions'] = str(sessions)
                self.session.xenapi.PBD.set_other_config(pbdref, other_conf)
        except:
            pass

        if self.mpath == 'true' and self.dconf.has_key('SCSIid'):
            self.mpathmodule.refresh(self.dconf['SCSIid'], npaths)