def detach(self, sr_uuid): keys = [] pbdref = None try: pbdref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if self.dconf.has_key("SCSIid"): self.mpathmodule.reset(self.dconf["SCSIid"], True) # explicitly unmap keys.append("mpath-" + self.dconf["SCSIid"]) # Remove iscsi_sessions and multipathed keys if pbdref <> None: if self.cmd == "sr_detach": keys += ["multipathed", "iscsi_sessions", "MPPEnabled"] for key in keys: try: self.session.xenapi.PBD.remove_from_other_config(pbdref, key) except: pass if util._decr_iscsiSR_refcount(self.targetIQN, sr_uuid) != 0: return if self.direct and util._containsVDIinuse(self): return if iscsilib._checkTGT(self.targetIQN): try: iscsilib.logout(self.target, self.targetIQN, all=True) except util.CommandException, inst: raise xs_errors.XenError("ISCSIQueryDaemon", opterr="error is %d" % inst.code) if iscsilib._checkTGT(self.targetIQN): raise xs_errors.XenError("ISCSIQueryDaemon", opterr="Failed to logout from target")
def create(self, sr_uuid, size): # Check SCSIid not already in use by other PBDs if util.test_SCSIid(self.session, sr_uuid, self.SCSIid): raise xs_errors.XenError('SRInUse') self.iscsi.attach(sr_uuid) try: if not self.iscsi._attach_LUN_bySCSIid(self.SCSIid): # UPGRADE FROM GEORGE: take care of ill-formed SCSIid upgraded = False matchSCSIid = False for file in filter(self.iscsi.match_lun, util.listdir(self.iscsi.path)): path = os.path.join(self.iscsi.path, file) if not util.wait_for_path(path, ISCSISR.MAX_TIMEOUT): util.SMlog( "Unable to detect LUN attached to host [%s]" % path) continue try: SCSIid = scsiutil.getSCSIid(path) except: continue try: matchSCSIid = scsiutil.compareSCSIid_2_6_18( self.SCSIid, path) except: continue if (matchSCSIid): util.SMlog("Performing upgrade from George") try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) device_config = self.session.xenapi.PBD.get_device_config( pbd) device_config['SCSIid'] = SCSIid self.session.xenapi.PBD.set_device_config( pbd, device_config) self.dconf['SCSIid'] = SCSIid self.SCSIid = self.dconf['SCSIid'] except: continue if not self.iscsi._attach_LUN_bySCSIid(self.SCSIid): raise xs_errors.XenError('InvalidDev') else: upgraded = True break else: util.SMlog( "Not a matching LUN, skip ... scsi_id is: %s" % SCSIid) continue if not upgraded: raise xs_errors.XenError('InvalidDev') self._pathrefresh(OCFSoISCSISR) OCFSSR.OCFSSR.create(self, sr_uuid, size) except Exception, inst: self.iscsi.detach(sr_uuid) raise xs_errors.XenError("SRUnavailable", opterr=inst)
def _synchroniseAddrList(self, addrlist): if not self.multihomed: return change = False if 'multihomelist' not in self.dconf: 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 _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 _add_pbd_other_config(self, key, value): try: pbd_ref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: util.SMlog("No pbd for sr_ref %s on host_ref %s" % (sr_ref, host_ref)) return try: self.session.xenapi.PBD.add_to_other_config(pbd_ref, key, value) except: util.SMlog("add_to_other_config failed")
def _reset_pbd_other_config(self): try: pbd_ref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: util.SMlog("No pbd for sr_ref %s on host_ref %s" % (sr_ref, host_ref)) for key in ["multipathed"]: try: self.session.xenapi.PBD.remove_from_other_config(pbd_ref, key) except: util.SMlog("remove_from_other_config failed")
def updateSMBVersInPBDConfig(self): """Store smb version in PBD config""" pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) if pbd is not None: util.SMlog('Updating SMB version in PBD device config') dconf = self.session.xenapi.PBD.get_device_config(pbd) dconf['vers'] = self.smbversion self.session.xenapi.PBD.set_device_config(pbd, dconf) else: raise Exception('Could not find PBD for corresponding SR')
def _reset_pbd_other_config(self): try: pbd_ref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: util.SMlog("No pbd for sr_ref %s on host_ref %s" %(self.sr_ref, self.host_ref)) for key in ["multipathed"]: try: self.session.xenapi.PBD.remove_from_other_config(pbd_ref, key) except: util.SMlog("remove_from_other_config failed")
def _add_pbd_other_config(self, key, value): try: pbd_ref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: util.SMlog("No pbd for sr_ref %s on host_ref %s" %(self.sr_ref, self.host_ref)) return try: self.session.xenapi.PBD.add_to_other_config(pbd_ref, key, value) except: util.SMlog("add_to_other_config failed")
def detach(self, sr_uuid): LVHDSR.LVHDSR.detach(self, sr_uuid) self.mpathmodule.reset(self.SCSIid,True,True) # explicit_unmap try: pbdref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass for key in ["mpath-" + self.SCSIid, "multipathed", "MPPEnabled"]: try: self.session.xenapi.PBD.remove_from_other_config(pbdref, key) except: pass
def detach(self, sr_uuid): super(OCFSoHBASR, self).detach(sr_uuid) self.mpathmodule.reset(self.SCSIid,True,True) # explicit_unmap try: pbdref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass for key in ["mpath-" + self.SCSIid, "multipathed", "MPPEnabled"]: try: self.session.xenapi.PBD.remove_from_other_config(pbdref, key) except: pass
def create(self, sr_uuid, size): # Check SCSIid not already in use by other PBDs if util.test_SCSIid(self.session, sr_uuid, self.SCSIid): raise xs_errors.XenError('SRInUse') self.iscsi.attach(sr_uuid) try: if not self.iscsi._attach_LUN_bySCSIid(self.SCSIid): # UPGRADE FROM GEORGE: take care of ill-formed SCSIid upgraded = False matchSCSIid = False for file in filter(self.iscsi.match_lun, util.listdir(self.iscsi.path)): path = os.path.join(self.iscsi.path,file) if not util.wait_for_path(path, ISCSISR.MAX_TIMEOUT): util.SMlog("Unable to detect LUN attached to host [%s]" % path) continue try: SCSIid = scsiutil.getSCSIid(path) except: continue try: matchSCSIid = scsiutil.compareSCSIid_2_6_18(self.SCSIid, path) except: continue if (matchSCSIid): util.SMlog("Performing upgrade from George") try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) device_config = self.session.xenapi.PBD.get_device_config(pbd) device_config['SCSIid'] = SCSIid self.session.xenapi.PBD.set_device_config(pbd, device_config) self.dconf['SCSIid'] = SCSIid self.SCSIid = self.dconf['SCSIid'] except: continue if not self.iscsi._attach_LUN_bySCSIid(self.SCSIid): raise xs_errors.XenError('InvalidDev') else: upgraded = True break else: util.SMlog("Not a matching LUN, skip ... scsi_id is: %s" % SCSIid) continue if not upgraded: raise xs_errors.XenError('InvalidDev') self._pathrefresh(LVHDoISCSISR) LVHDSR.LVHDSR.create(self, sr_uuid, size) except Exception, inst: self.iscsi.detach(sr_uuid) raise xs_errors.XenError("SRUnavailable", opterr=inst)
def load(self, sr_uuid): driver = SR.driver('hba') self.hbasr = driver(self.original_srcmd, sr_uuid) pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if not self.dconf.has_key('SCSIid') or not self.dconf['SCSIid']: print >>sys.stderr,self.hbasr.print_devs() raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(OCFSoHBASR) super(OCFSoHBASR, self).load(sr_uuid)
def load(self, sr_uuid): driver = SR.driver('hba') self.hbasr = driver(self.original_srcmd, sr_uuid) pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if 'SCSIid' not in self.dconf or not self.dconf['SCSIid']: print(self.hbasr.print_devs(), file=sys.stderr) raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(OCFSoHBASR, load = False) super(OCFSoHBASR, self).load(sr_uuid)
def load(self, sr_uuid): driver = SR.driver('hba') if 'type' not in self.original_srcmd.params['device_config'] or \ 'type' in self.original_srcmd.params['device_config'] and \ self.original_srcmd.dconf['type'] == "any": self.original_srcmd.dconf['type'] = "fcoe" self.hbasr = driver(self.original_srcmd, sr_uuid) pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if 'SCSIid' not in self.dconf or not self.dconf['SCSIid']: print(self.hbasr.print_devs(), file=sys.stderr) raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] LVHDSR.LVHDSR.load(self, sr_uuid)
def load(self, sr_uuid): driver = SR.driver('hba') self.hbasr = driver(self.original_srcmd, sr_uuid) # If this is a vdi command, don't initialise SR if not (util.isVDICommand(self.original_srcmd.cmd)): pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass try: if not self.dconf.has_key('SCSIid') and self.dconf.has_key( 'device'): # UPGRADE FROM MIAMI: add SCSIid key to device_config util.SMlog("Performing upgrade from Miami") if not os.path.exists(self.dconf['device']): raise xs_errors.XenError('InvalidDev') SCSIid = scsiutil.getSCSIid(self.dconf['device']) self.dconf['SCSIid'] = SCSIid del self.dconf['device'] if pbd <> None: device_config = self.session.xenapi.PBD.get_device_config( pbd) device_config['SCSIid'] = SCSIid device_config['upgraded_from_miami'] = 'true' del device_config['device'] self.session.xenapi.PBD.set_device_config( pbd, device_config) except: pass if not self.dconf.has_key('SCSIid') or not self.dconf['SCSIid']: print >> sys.stderr, self.hbasr.print_devs() raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(LVHDoHBASR, load=False) LVHDSR.LVHDSR.load(self, sr_uuid)
def load(self, sr_uuid): driver = SR.driver('hba') if 'type' not in self.original_srcmd.params['device_config'] or \ 'type' in self.original_srcmd.params['device_config'] and \ self.original_srcmd.dconf['type'] == "any": self.original_srcmd.dconf['type'] = "fcoe" self.hbasr = driver(self.original_srcmd, sr_uuid) pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if not self.dconf.has_key('SCSIid') or not self.dconf['SCSIid']: print >>sys.stderr, self.hbasr.print_devs() raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(LVHDoFCoESR) LVHDSR.LVHDSR.load(self, sr_uuid)
def load(self, sr_uuid): driver = SR.driver('hba') if 'type' not in self.original_srcmd.params['device_config'] or \ 'type' in self.original_srcmd.params['device_config'] and \ self.original_srcmd.dconf['type'] == "any": self.original_srcmd.dconf['type'] = "fcoe" self.hbasr = driver(self.original_srcmd, sr_uuid) pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if not self.dconf.has_key('SCSIid') or not self.dconf['SCSIid']: print >> sys.stderr, self.hbasr.print_devs() raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(LVHDoFCoESR, load=False) LVHDSR.LVHDSR.load(self, sr_uuid)
def detach(self, sr_uuid, delete=False): keys = [] pbdref = None try: pbdref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if 'SCSIid' in self.dconf: self.mpathmodule.reset(self.dconf['SCSIid'], explicit_unmap=True) keys.append("mpath-" + self.dconf['SCSIid']) # Remove iscsi_sessions and multipathed keys if pbdref != None: if self.cmd == 'sr_detach': keys += ["multipathed", "iscsi_sessions", "MPPEnabled"] for key in keys: try: self.session.xenapi.PBD.remove_from_other_config( pbdref, key) except: pass if util._decr_iscsiSR_refcount(self.targetIQN, sr_uuid) != 0: return if self.direct and util._containsVDIinuse(self): return if iscsilib._checkTGT(self.targetIQN): try: iscsilib.logout(self.target, self.targetIQN, all=True) if delete: iscsilib.delete(self.targetIQN) except util.CommandException as inst: raise xs_errors.XenError('ISCSIQueryDaemon', \ opterr='error is %d' % inst.code) if iscsilib._checkTGT(self.targetIQN): raise xs_errors.XenError('ISCSIQueryDaemon', \ opterr='Failed to logout from target') self.attached = False
def load(self, sr_uuid): driver = SR.driver('hba') self.hbasr = driver(self.original_srcmd, sr_uuid) # If this is a vdi command, don't initialise SR if not (util.isVDICommand(self.original_srcmd.cmd)): pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass try: if not self.dconf.has_key('SCSIid') and self.dconf.has_key('device'): # UPGRADE FROM MIAMI: add SCSIid key to device_config util.SMlog("Performing upgrade from Miami") if not os.path.exists(self.dconf['device']): raise xs_errors.XenError('InvalidDev') SCSIid = scsiutil.getSCSIid(self.dconf['device']) self.dconf['SCSIid'] = SCSIid del self.dconf['device'] if pbd <> None: device_config = self.session.xenapi.PBD.get_device_config(pbd) device_config['SCSIid'] = SCSIid device_config['upgraded_from_miami'] = 'true' del device_config['device'] self.session.xenapi.PBD.set_device_config(pbd, device_config) except: pass if not self.dconf.has_key('SCSIid') or not self.dconf['SCSIid']: print >>sys.stderr,self.hbasr.print_devs() raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(LVHDoHBASR, load = False) LVHDSR.LVHDSR.load(self, sr_uuid)
def load(self, sr_uuid): if not sr_uuid: # This is a probe call, generate a temp sr_uuid sr_uuid = util.gen_uuid() driver = SR.driver('iscsi') self.iscsi = driver(self.original_srcmd, sr_uuid) # Be extremely careful not to throw exceptions here since this function # is the main one used by all operations including probing and creating pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if not self.dconf.has_key('SCSIid') and self.dconf.has_key( 'LUNid') and pbd <> None: # UPGRADE FROM RIO: add SCSIid key to device_config util.SMlog("Performing upgrade from Rio") scsiid = self._getSCSIid_from_LUN(sr_uuid) device_config = self.session.xenapi.PBD.get_device_config(pbd) device_config['SCSIid'] = scsiid device_config['upgraded_from_rio'] = 'true' self.session.xenapi.PBD.set_device_config(pbd, device_config) self.dconf['SCSIid'] = scsiid # Apart from the upgrade case, user must specify a SCSIid if not self.dconf.has_key('SCSIid'): self._LUNprint(sr_uuid) raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(LVMoISCSISR) super(LVMoISCSISR, self).load(sr_uuid)
def load(self, sr_uuid): if not sr_uuid: # This is a probe call, generate a temp sr_uuid sr_uuid = util.gen_uuid() driver = SR.driver('iscsi') self.iscsi = driver(self.original_srcmd, sr_uuid) # Be extremely careful not to throw exceptions here since this function # is the main one used by all operations including probing and creating pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if not self.dconf.has_key('SCSIid') and self.dconf.has_key('LUNid') and pbd <> None: # UPGRADE FROM RIO: add SCSIid key to device_config util.SMlog("Performing upgrade from Rio") scsiid = self._getSCSIid_from_LUN(sr_uuid) device_config = self.session.xenapi.PBD.get_device_config(pbd) device_config['SCSIid'] = scsiid device_config['upgraded_from_rio'] = 'true' self.session.xenapi.PBD.set_device_config(pbd, device_config) self.dconf['SCSIid'] = scsiid # Apart from the upgrade case, user must specify a SCSIid if not self.dconf.has_key('SCSIid'): self._LUNprint(sr_uuid) raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(LVMoISCSISR) super(LVMoISCSISR, self).load(sr_uuid)
def load(self, sr_uuid): driver = SR.driver("hba") self.hbasr = driver(self.original_srcmd, sr_uuid) pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass try: if not self.dconf.has_key("SCSIid") and self.dconf.has_key("device"): # UPGRADE FROM MIAMI: add SCSIid key to device_config util.SMlog("Performing upgrade from Miami") if not os.path.exists(self.dconf["device"]): raise SCSIid = scsiutil.getSCSIid(self.dconf["device"]) self.dconf["SCSIid"] = SCSIid del self.dconf["device"] if pbd <> None: device_config = self.session.xenapi.PBD.get_device_config(pbd) device_config["SCSIid"] = SCSIid device_config["upgraded_from_miami"] = "true" del device_config["device"] self.session.xenapi.PBD.set_device_config(pbd, device_config) except: pass if not self.dconf.has_key("SCSIid") or not self.dconf["SCSIid"]: print >>sys.stderr, self.hbasr.print_devs() raise xs_errors.XenError("ConfigSCSIid") self.SCSIid = self.dconf["SCSIid"] self._pathrefresh(LVMoHBASR) super(LVMoHBASR, self).load(sr_uuid)
def load(self, sr_uuid): if not sr_uuid: # This is a probe call, generate a temp sr_uuid sr_uuid = util.gen_uuid() driver = SR.driver('iscsi') if self.original_srcmd.dconf.has_key('target'): self.original_srcmd.dconf['targetlist'] = self.original_srcmd.dconf['target'] iscsi = driver(self.original_srcmd, sr_uuid) self.iscsiSRs = [] self.iscsiSRs.append(iscsi) if self.dconf['target'].find(',') == 0 or self.dconf['targetIQN'] == "*": # Instantiate multiple sessions self.iscsiSRs = [] if self.dconf['targetIQN'] == "*": IQN = "any" else: IQN = self.dconf['targetIQN'] dict = {} IQNstring = "" IQNs = [] try: if self.dconf.has_key('multiSession'): IQNs = self.dconf['multiSession'].split("|") for IQN in IQNs: if IQN: dict[IQN] = "" else: try: IQNs.remove(IQN) except: # Exceptions are not expected but just in case pass # Order in multiSession must be preserved. It is important for dual-controllers. # IQNstring cannot be built with a dictionary iteration because of this IQNstring = self.dconf['multiSession'] else: for tgt in self.dconf['target'].split(','): try: tgt_ip = util._convertDNS(tgt) except: raise xs_errors.XenError('DNSError') iscsilib.ensure_daemon_running_ok(iscsi.localIQN) map = iscsilib.discovery(tgt_ip,iscsi.port,iscsi.chapuser,iscsi.chappassword,targetIQN=IQN) util.SMlog("Discovery for IP %s returned %s" % (tgt,map)) for i in range(0,len(map)): (portal,tpgt,iqn) = map[i] (ipaddr, port) = iscsilib.parse_IP_port(portal) try: util._testHost(ipaddr, long(port), 'ISCSITarget') except: util.SMlog("Target Not reachable: (%s:%s)" % (ipaddr, port)) continue key = "%s,%s,%s" % (ipaddr,port,iqn) dict[key] = "" # Again, do not mess up with IQNs order. Dual controllers will benefit from that if IQNstring == "": # Compose the IQNstring first for key in dict.iterkeys(): IQNstring += "%s|" % key # Reinitialize and store iterator key_iterator = dict.iterkeys() else: key_iterator = IQNs # Now load the individual iSCSI base classes for key in key_iterator: (ipaddr,port,iqn) = key.split(',') srcmd_copy = copy.deepcopy(self.original_srcmd) srcmd_copy.dconf['target'] = ipaddr srcmd_copy.dconf['targetIQN'] = iqn srcmd_copy.dconf['multiSession'] = IQNstring util.SMlog("Setting targetlist: %s" % srcmd_copy.dconf['targetlist']) self.iscsiSRs.append(driver(srcmd_copy, sr_uuid)) pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) if pbd <> None and not self.dconf.has_key('multiSession'): dconf = self.session.xenapi.PBD.get_device_config(pbd) dconf['multiSession'] = IQNstring self.session.xenapi.PBD.set_device_config(pbd, dconf) except: util.logException("LVHDoISCSISR.load") self.iscsi = self.iscsiSRs[0] # Be extremely careful not to throw exceptions here since this function # is the main one used by all operations including probing and creating pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass # Apart from the upgrade case, user must specify a SCSIid if not self.dconf.has_key('SCSIid'): # Dual controller issue self.LUNs = {} # Dict for LUNs from all the iscsi objects for ii in range(0, len(self.iscsiSRs)): self.iscsi = self.iscsiSRs[ii] self._LUNprint(sr_uuid) for key in self.iscsi.LUNs: self.LUNs[key] = self.iscsi.LUNs[key] self.print_LUNs_XML() self.iscsi = self.iscsiSRs[0] # back to original value raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] # This block checks if the first iscsi target contains the right SCSIid. # If not it scans the other iscsi targets because chances are that more # than one controller is present dev_match = False forced_login = False # No need to check if only one iscsi target is present if len(self.iscsiSRs) == 1: pass else: target_success = False attempt_discovery = False for iii in range(0, len(self.iscsiSRs)): # Check we didn't leave any iscsi session open # If exceptions happened before, the cleanup function has worked on the right target. if forced_login == True: try: iscsilib.ensure_daemon_running_ok(self.iscsi.localIQN) iscsilib.logout(self.iscsi.target, self.iscsi.targetIQN) forced_login = False except: raise xs_errors.XenError('ISCSILogout') self.iscsi = self.iscsiSRs[iii] util.SMlog("path %s" %self.iscsi.path) util.SMlog("iscsci data: targetIQN %s, portal %s" % (self.iscsi.targetIQN, self.iscsi.target)) iscsilib.ensure_daemon_running_ok(self.iscsi.localIQN) if not iscsilib._checkTGT(self.iscsi.targetIQN): attempt_discovery = True try: # Ensure iscsi db has been populated map = iscsilib.discovery( self.iscsi.target, self.iscsi.port, self.iscsi.chapuser, self.iscsi.chappassword, targetIQN=self.iscsi.targetIQN) if len(map) == 0: util.SMlog("Discovery for iscsi data targetIQN %s," " portal %s returned empty list" " Trying another path if available" % (self.iscsi.targetIQN, self.iscsi.target)) continue except: util.SMlog("Discovery failed for iscsi data targetIQN" " %s, portal %s. Trying another path if" " available" % (self.iscsi.targetIQN, self.iscsi.target)) continue try: iscsilib.login(self.iscsi.target, self.iscsi.targetIQN, self.iscsi.chapuser, self.iscsi.chappassword, self.iscsi.incoming_chapuser, self.iscsi.incoming_chappassword, self.mpath == "true") except: util.SMlog("Login failed for iscsi data targetIQN %s," " portal %s. Trying another path" " if available" % (self.iscsi.targetIQN, self.iscsi.target)) continue target_success = True; forced_login = True # A session should be active. if not util.wait_for_path(self.iscsi.path, ISCSISR.MAX_TIMEOUT): util.SMlog("%s has no associated LUNs" % self.iscsi.targetIQN) continue scsiid_path = "/dev/disk/by-id/scsi-" + self.SCSIid if not util.wait_for_path(scsiid_path, ISCSISR.MAX_TIMEOUT): util.SMlog("%s not found" %scsiid_path) continue for file in filter(self.iscsi.match_lun, util.listdir(self.iscsi.path)): lun_path = os.path.join(self.iscsi.path,file) lun_dev = scsiutil.getdev(lun_path) try: lun_scsiid = scsiutil.getSCSIid(lun_dev) except: util.SMlog("getSCSIid failed on %s in iscsi %s: LUN" " offline or iscsi path down" % (lun_dev, self.iscsi.path)) continue util.SMlog("dev from lun %s %s" %(lun_dev, lun_scsiid)) if lun_scsiid == self.SCSIid: util.SMlog("lun match in %s" %self.iscsi.path) dev_match = True # No more need to raise ISCSITarget exception. # Resetting attempt_discovery attempt_discovery = False break if dev_match: if iii == 0: break util.SMlog("IQN reordering needed") new_iscsiSRs = [] IQNs = {} IQNstring = "" # iscsiSRs can be seen as a circular buffer: the head now is the matching one for kkk in range(iii, len(self.iscsiSRs)) + range(0, iii): new_iscsiSRs.append(self.iscsiSRs[kkk]) ipaddr = self.iscsiSRs[kkk].target port = self.iscsiSRs[kkk].port iqn = self.iscsiSRs[kkk].targetIQN key = "%s,%s,%s" % (ipaddr,port,iqn) # The final string must preserve the order without repetition if not IQNs.has_key(key): IQNs[key] = "" IQNstring += "%s|" % key util.SMlog("IQNstring is now %s" %IQNstring) self.iscsiSRs = new_iscsiSRs util.SMlog("iqn %s is leading now" %self.iscsiSRs[0].targetIQN) # Updating pbd entry, if any try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) if pbd <> None and self.dconf.has_key('multiSession'): util.SMlog("Updating multiSession in PBD") dconf = self.session.xenapi.PBD.get_device_config(pbd) dconf['multiSession'] = IQNstring self.session.xenapi.PBD.set_device_config(pbd, dconf) except: pass break if not target_success and attempt_discovery: raise xs_errors.XenError('ISCSITarget') # Check for any unneeded open iscsi sessions if forced_login == True: try: iscsilib.ensure_daemon_running_ok(self.iscsi.localIQN) iscsilib.logout(self.iscsi.target, self.iscsi.targetIQN) forced_login = False except: raise xs_errors.XenError('ISCSILogout') self._pathrefresh(LVHDoISCSISR, load = False) LVHDSR.LVHDSR.load(self, sr_uuid)
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)
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)
def load(self, sr_uuid): if not sr_uuid: # This is a probe call, generate a temp sr_uuid sr_uuid = util.gen_uuid() driver = SR.driver('iscsi') if self.original_srcmd.dconf.has_key('target'): self.original_srcmd.dconf[ 'targetlist'] = self.original_srcmd.dconf['target'] iscsi = driver(self.original_srcmd, sr_uuid) self.iscsiSRs = [] self.iscsiSRs.append(iscsi) if self.dconf['target'].find( ',') == 0 or self.dconf['targetIQN'] == "*": # Instantiate multiple sessions self.iscsiSRs = [] if self.dconf['targetIQN'] == "*": IQN = "any" else: IQN = self.dconf['targetIQN'] dict = {} try: if self.dconf.has_key('multiSession'): IQNs = self.dconf['multiSession'].split("|") for IQN in IQNs: if IQN: dict[IQN] = "" else: for tgt in self.dconf['target'].split(','): try: tgt_ip = util._convertDNS(tgt) except: raise xs_errors.XenError('DNSError') iscsilib.ensure_daemon_running_ok(iscsi.localIQN) map = iscsilib.discovery(tgt_ip, iscsi.port, iscsi.chapuser, iscsi.chappassword, targetIQN=IQN) util.SMlog("Discovery for IP %s returned %s" % (tgt, map)) for i in range(0, len(map)): (portal, tpgt, iqn) = map[i] (ipaddr, port) = portal.split(',')[0].split(':') key = "%s,%s,%s" % (ipaddr, port, iqn) dict[key] = "" # Compose the IQNstring first IQNstring = "" for key in dict.iterkeys(): IQNstring += "%s|" % key # Now load the individual iSCSI base classes for key in dict.iterkeys(): (ipaddr, port, iqn) = key.split(',') srcmd_copy = copy.deepcopy(self.original_srcmd) srcmd_copy.dconf['target'] = ipaddr srcmd_copy.dconf['targetIQN'] = iqn srcmd_copy.dconf['multiSession'] = IQNstring util.SMlog("Setting targetlist: %s" % srcmd_copy.dconf['targetlist']) self.iscsiSRs.append(driver(srcmd_copy, sr_uuid)) pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) if pbd <> None and not self.dconf.has_key('multiSession'): dconf = self.session.xenapi.PBD.get_device_config(pbd) dconf['multiSession'] = IQNstring self.session.xenapi.PBD.set_device_config(pbd, dconf) except: util.logException("LVHDoISCSISR.load") self.iscsi = self.iscsiSRs[0] # Be extremely careful not to throw exceptions here since this function # is the main one used by all operations including probing and creating pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if not self.dconf.has_key('SCSIid') and self.dconf.has_key( 'LUNid') and pbd <> None: # UPGRADE FROM RIO: add SCSIid key to device_config util.SMlog("Performing upgrade from Rio") scsiid = self._getSCSIid_from_LUN(sr_uuid) device_config = self.session.xenapi.PBD.get_device_config(pbd) device_config['SCSIid'] = scsiid device_config['upgraded_from_rio'] = 'true' self.session.xenapi.PBD.set_device_config(pbd, device_config) self.dconf['SCSIid'] = scsiid # Apart from the upgrade case, user must specify a SCSIid if not self.dconf.has_key('SCSIid'): self._LUNprint(sr_uuid) raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(LVHDoISCSISR) LVHDSR.LVHDSR.load(self, sr_uuid)
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)
def load(self, sr_uuid): if not sr_uuid: # This is a probe call, generate a temp sr_uuid sr_uuid = util.gen_uuid() driver = SR.driver('iscsi') if self.original_srcmd.dconf.has_key('target'): self.original_srcmd.dconf['targetlist'] = self.original_srcmd.dconf['target'] iscsi = driver(self.original_srcmd, sr_uuid) self.iscsiSRs = [] self.iscsiSRs.append(iscsi) if self.dconf['target'].find(',') == 0 or self.dconf['targetIQN'] == "*": # Instantiate multiple sessions self.iscsiSRs = [] if self.dconf['targetIQN'] == "*": IQN = "any" else: IQN = self.dconf['targetIQN'] dict = {} try: if self.dconf.has_key('multiSession'): IQNs = self.dconf['multiSession'].split("|") for IQN in IQNs: if IQN: dict[IQN] = "" else: for tgt in self.dconf['target'].split(','): try: tgt_ip = util._convertDNS(tgt) except: raise xs_errors.XenError('DNSError') iscsilib.ensure_daemon_running_ok(iscsi.localIQN) map = iscsilib.discovery(tgt_ip,iscsi.port,iscsi.chapuser,iscsi.chappassword,targetIQN=IQN) util.SMlog("Discovery for IP %s returned %s" % (tgt,map)) for i in range(0,len(map)): (portal,tpgt,iqn) = map[i] (ipaddr,port) = portal.split(',')[0].split(':') key = "%s,%s,%s" % (ipaddr,port,iqn) dict[key] = "" # Compose the IQNstring first IQNstring = "" for key in dict.iterkeys(): IQNstring += "%s|" % key # Now load the individual iSCSI base classes for key in dict.iterkeys(): (ipaddr,port,iqn) = key.split(',') srcmd_copy = copy.deepcopy(self.original_srcmd) srcmd_copy.dconf['target'] = ipaddr srcmd_copy.dconf['targetIQN'] = iqn srcmd_copy.dconf['multiSession'] = IQNstring util.SMlog("Setting targetlist: %s" % srcmd_copy.dconf['targetlist']) self.iscsiSRs.append(driver(srcmd_copy, sr_uuid)) pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) if pbd <> None and not self.dconf.has_key('multiSession'): dconf = self.session.xenapi.PBD.get_device_config(pbd) dconf['multiSession'] = IQNstring self.session.xenapi.PBD.set_device_config(pbd, dconf) except: util.logException("LVHDoISCSISR.load") self.iscsi = self.iscsiSRs[0] # Be extremely careful not to throw exceptions here since this function # is the main one used by all operations including probing and creating pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass if not self.dconf.has_key('SCSIid') and self.dconf.has_key('LUNid') and pbd <> None: # UPGRADE FROM RIO: add SCSIid key to device_config util.SMlog("Performing upgrade from Rio") scsiid = self._getSCSIid_from_LUN(sr_uuid) device_config = self.session.xenapi.PBD.get_device_config(pbd) device_config['SCSIid'] = scsiid device_config['upgraded_from_rio'] = 'true' self.session.xenapi.PBD.set_device_config(pbd, device_config) self.dconf['SCSIid'] = scsiid # Apart from the upgrade case, user must specify a SCSIid if not self.dconf.has_key('SCSIid'): self._LUNprint(sr_uuid) raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] self._pathrefresh(LVHDoISCSISR) LVHDSR.LVHDSR.load(self, sr_uuid)
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")
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") try: pbdref = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) if pbdref <> None: # 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)) except: pass if self.mpath == 'true' and self.dconf.has_key('SCSIid'): self.mpathmodule.refresh(self.dconf['SCSIid'], npaths) # set the device mapper's I/O scheduler self.block_setscheduler('/dev/disk/by-scsid/%s/mapper' % self.dconf['SCSIid'])
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") 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) # set the device mapper's I/O scheduler self.block_setscheduler('/dev/disk/by-scsid/%s/mapper' % self.dconf['SCSIid']) def detach(self, sr_uuid):
def load(self, sr_uuid): if not sr_uuid: # This is a probe call, generate a temp sr_uuid sr_uuid = util.gen_uuid() driver = SR.driver('iscsi') if self.original_srcmd.dconf.has_key('target'): self.original_srcmd.dconf[ 'targetlist'] = self.original_srcmd.dconf['target'] iscsi = driver(self.original_srcmd, sr_uuid) self.iscsiSRs = [] self.iscsiSRs.append(iscsi) if self.dconf['target'].find( ',') == 0 or self.dconf['targetIQN'] == "*": # Instantiate multiple sessions self.iscsiSRs = [] if self.dconf['targetIQN'] == "*": IQN = "any" else: IQN = self.dconf['targetIQN'] dict = {} IQNstring = "" IQNs = [] try: if self.dconf.has_key('multiSession'): IQNs = self.dconf['multiSession'].split("|") for IQN in IQNs: if IQN: dict[IQN] = "" else: try: IQNs.remove(IQN) except: # Exceptions are not expected but just in case pass # Order in multiSession must be preserved. It is important for dual-controllers. # IQNstring cannot be built with a dictionary iteration because of this IQNstring = self.dconf['multiSession'] else: for tgt in self.dconf['target'].split(','): try: tgt_ip = util._convertDNS(tgt) except: raise xs_errors.XenError('DNSError') iscsilib.ensure_daemon_running_ok(iscsi.localIQN) map = iscsilib.discovery(tgt_ip, iscsi.port, iscsi.chapuser, iscsi.chappassword, targetIQN=IQN) util.SMlog("Discovery for IP %s returned %s" % (tgt, map)) for i in range(0, len(map)): (portal, tpgt, iqn) = map[i] (ipaddr, port) = iscsilib.parse_IP_port(portal) try: util._testHost(ipaddr, long(port), 'ISCSITarget') except: util.SMlog("Target Not reachable: (%s:%s)" % (ipaddr, port)) continue key = "%s,%s,%s" % (ipaddr, port, iqn) dict[key] = "" # Again, do not mess up with IQNs order. Dual controllers will benefit from that if IQNstring == "": # Compose the IQNstring first for key in dict.iterkeys(): IQNstring += "%s|" % key # Reinitialize and store iterator key_iterator = dict.iterkeys() else: key_iterator = IQNs # Now load the individual iSCSI base classes for key in key_iterator: (ipaddr, port, iqn) = key.split(',') srcmd_copy = copy.deepcopy(self.original_srcmd) srcmd_copy.dconf['target'] = ipaddr srcmd_copy.dconf['targetIQN'] = iqn srcmd_copy.dconf['multiSession'] = IQNstring util.SMlog("Setting targetlist: %s" % srcmd_copy.dconf['targetlist']) self.iscsiSRs.append(driver(srcmd_copy, sr_uuid)) pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) if pbd <> None and not self.dconf.has_key('multiSession'): dconf = self.session.xenapi.PBD.get_device_config(pbd) dconf['multiSession'] = IQNstring self.session.xenapi.PBD.set_device_config(pbd, dconf) except: util.logException("OCFSoISCSISR.load") self.iscsi = self.iscsiSRs[0] # Be extremely careful not to throw exceptions here since this function # is the main one used by all operations including probing and creating pbd = None try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) except: pass # Apart from the upgrade case, user must specify a SCSIid if not self.dconf.has_key('SCSIid'): # Dual controller issue self.LUNs = {} # Dict for LUNs from all the iscsi objects for ii in range(0, len(self.iscsiSRs)): self.iscsi = self.iscsiSRs[ii] self._LUNprint(sr_uuid) for key in self.iscsi.LUNs: self.LUNs[key] = self.iscsi.LUNs[key] self.print_LUNs_XML() self.iscsi = self.iscsiSRs[0] # back to original value raise xs_errors.XenError('ConfigSCSIid') self.SCSIid = self.dconf['SCSIid'] # This block checks if the first iscsi target contains the right SCSIid. # If not it scans the other iscsi targets because chances are that more # than one controller is present dev_match = False forced_login = False # No need to check if only one iscsi target is present if len(self.iscsiSRs) == 1: pass else: target_success = False attempt_discovery = False for iii in range(0, len(self.iscsiSRs)): # Check we didn't leave any iscsi session open # If exceptions happened before, the cleanup function has worked on the right target. if forced_login == True: try: iscsilib.ensure_daemon_running_ok(self.iscsi.localIQN) iscsilib.logout(self.iscsi.target, self.iscsi.targetIQN) forced_login = False except: raise xs_errors.XenError('ISCSILogout') self.iscsi = self.iscsiSRs[iii] util.SMlog("path %s" % self.iscsi.path) util.SMlog("iscsci data: targetIQN %s, portal %s" % (self.iscsi.targetIQN, self.iscsi.target)) iscsilib.ensure_daemon_running_ok(self.iscsi.localIQN) if not iscsilib._checkTGT(self.iscsi.targetIQN): attempt_discovery = True try: # Ensure iscsi db has been populated map = iscsilib.discovery( self.iscsi.target, self.iscsi.port, self.iscsi.chapuser, self.iscsi.chappassword, targetIQN=self.iscsi.targetIQN) if len(map) == 0: util.SMlog( "Discovery for iscsi data targetIQN %s," " portal %s returned empty list" " Trying another path if available" % (self.iscsi.targetIQN, self.iscsi.target)) continue except: util.SMlog("Discovery failed for iscsi data targetIQN" " %s, portal %s. Trying another path if" " available" % (self.iscsi.targetIQN, self.iscsi.target)) continue try: iscsilib.login(self.iscsi.target, self.iscsi.targetIQN, self.iscsi.chapuser, self.iscsi.chappassword, self.iscsi.incoming_chapuser, self.iscsi.incoming_chappassword, self.mpath == "true") except: util.SMlog("Login failed for iscsi data targetIQN %s," " portal %s. Trying another path" " if available" % (self.iscsi.targetIQN, self.iscsi.target)) continue target_success = True forced_login = True # A session should be active. if not util.wait_for_path(self.iscsi.path, ISCSISR.MAX_TIMEOUT): util.SMlog("%s has no associated LUNs" % self.iscsi.targetIQN) continue scsiid_path = "/dev/disk/by-id/scsi-" + self.SCSIid if not util.wait_for_path(scsiid_path, ISCSISR.MAX_TIMEOUT): util.SMlog("%s not found" % scsiid_path) continue for file in filter(self.iscsi.match_lun, util.listdir(self.iscsi.path)): lun_path = os.path.join(self.iscsi.path, file) lun_dev = scsiutil.getdev(lun_path) try: lun_scsiid = scsiutil.getSCSIid(lun_dev) except: util.SMlog("getSCSIid failed on %s in iscsi %s: LUN" " offline or iscsi path down" % (lun_dev, self.iscsi.path)) continue util.SMlog("dev from lun %s %s" % (lun_dev, lun_scsiid)) if lun_scsiid == self.SCSIid: util.SMlog("lun match in %s" % self.iscsi.path) dev_match = True # No more need to raise ISCSITarget exception. # Resetting attempt_discovery attempt_discovery = False break if dev_match: if iii == 0: break util.SMlog("IQN reordering needed") new_iscsiSRs = [] IQNs = {} IQNstring = "" # iscsiSRs can be seen as a circular buffer: the head now is the matching one for kkk in range(iii, len(self.iscsiSRs)) + range(0, iii): new_iscsiSRs.append(self.iscsiSRs[kkk]) ipaddr = self.iscsiSRs[kkk].target port = self.iscsiSRs[kkk].port iqn = self.iscsiSRs[kkk].targetIQN key = "%s,%s,%s" % (ipaddr, port, iqn) # The final string must preserve the order without repetition if not IQNs.has_key(key): IQNs[key] = "" IQNstring += "%s|" % key util.SMlog("IQNstring is now %s" % IQNstring) self.iscsiSRs = new_iscsiSRs util.SMlog("iqn %s is leading now" % self.iscsiSRs[0].targetIQN) # Updating pbd entry, if any try: pbd = util.find_my_pbd(self.session, self.host_ref, self.sr_ref) if pbd <> None and self.dconf.has_key('multiSession'): util.SMlog("Updating multiSession in PBD") dconf = self.session.xenapi.PBD.get_device_config( pbd) dconf['multiSession'] = IQNstring self.session.xenapi.PBD.set_device_config( pbd, dconf) except: pass break if not target_success and attempt_discovery: raise xs_errors.XenError('ISCSITarget') # Check for any unneeded open iscsi sessions if forced_login == True: try: iscsilib.ensure_daemon_running_ok(self.iscsi.localIQN) iscsilib.logout(self.iscsi.target, self.iscsi.targetIQN) forced_login = False except: raise xs_errors.XenError('ISCSILogout') self._pathrefresh(OCFSoISCSISR, load=False) OCFSSR.OCFSSR.load(self, sr_uuid)