def _find_LUN(svid): basepath = "/dev/disk/by-csldev/" if svid.startswith("NETAPP_"): # special attention for NETAPP SVIDs svid_parts = svid.split("__") globstr = basepath + "NETAPP__LUN__" + "*" + svid_parts[2] + "*" + svid_parts[-1] + "*" else: globstr = basepath + svid + "*" path = util.wait_for_path_multi(globstr, MAX_TIMEOUT) if not len(path): return [] #Find CSLDEV paths svid_to_use = re.sub("-[0-9]*:[0-9]*:[0-9]*:[0-9]*$","",os.path.basename(path)) devs = scsiutil._genReverseSCSIidmap(svid_to_use, pathname="csldev") #Find scsiID for dev in devs: try: SCSIid = scsiutil.getSCSIid(dev) except: pass #Find root device and return if not SCSIid: return [] else: device=mpath_dmp.path(SCSIid) XenCertPrint("DEBUG: device path : %s"%(device)) return [device]
def attach(self, sr_uuid, vdi_uuid): # Perform a device scan for all paths, to check for any LUN resize scsi_id = self.sm_config['SCSIid'] devices = scsiutil._genReverseSCSIidmap(scsi_id) xapi_session = self.session.xenapi # At the vdi attach stage if devices are not found against the scsi_id, # the two reasons would be 1. The machine is slave on which a bus scan # was not performed, perform a bus scan to rectify the same. 2. Genuine # HBA bus error, throw an error back. if len(devices) == 0: devscan.adapters() devices = scsiutil._genReverseSCSIidmap(scsi_id) # If no devices are found after a bus rescan, flag an error if len(devices) == 0: raise xs_errors.XenError('InvalidDev', \ opterr=('No HBA Device detected with SCSI Id[%s]') % scsi_id) # Run a query on devices against the scsi id to refresh the size dev_lun_info = scsiutil.cacheSCSIidentifiers() for dev in devices: self._query(dev, dev_lun_info[dev][4], vdi_uuid) #Update xapi with the new size vdi_ref = self.sr.session.xenapi.VDI.get_by_uuid(vdi_uuid) self.sr.session.xenapi.VDI.set_virtual_size(vdi_ref, str(self.size)) # Multipath enable if self.sr.mpath == "true": self.sr.mpathmodule.refresh(scsi_id, len(devices)) self.path = self.sr.mpathmodule.path(scsi_id) # The SCSIid is already stored inside SR sm_config. # We need only to trigger mpathcount try: cmd = ['/opt/xensource/sm/mpathcount.py', scsi_id] util.pread2(cmd) except: util.SMlog("RawHBA: something wrong with mpathcount") ret = VDI.VDI.attach(self, sr_uuid, vdi_uuid) self.sr.update_stats(self.size) return ret
def attach(self, sr_uuid, vdi_uuid): # Perform a device scan for all paths, to check for any LUN resize scsi_id = self.sm_config['SCSIid'] devices = scsiutil._genReverseSCSIidmap(scsi_id) xapi_session = self.session.xenapi # At the vdi attach stage if devices are not found against the scsi_id, # the two reasons would be 1. The machine is slave on which a bus scan # was not performed, perform a bus scan to rectify the same. 2. Genuine # HBA bus error, throw an error back. if len(devices) == 0: devscan.adapters() devices = scsiutil._genReverseSCSIidmap(scsi_id) # If no devices are found after a bus rescan, flag an error if len(devices) == 0: raise xs_errors.XenError('InvalidDev', \ opterr=('No HBA Device detected with SCSI Id[%s]') % scsi_id) # Run a query on devices against the scsi id to refresh the size dev_lun_info = scsiutil.cacheSCSIidentifiers() for dev in devices: self._query(dev, dev_lun_info[dev][4], vdi_uuid) #Update xapi with the new size vdi_ref = self.sr.session.xenapi.VDI.get_by_uuid(vdi_uuid) self.sr.session.xenapi.VDI.set_virtual_size(vdi_ref, str(self.size)) # Multipath enable if self.sr.mpath == "true": self.sr.mpathmodule.refresh(scsi_id, len(devices)) self.path = self.sr.mpathmodule.path(scsi_id) # The SCSIid is already stored inside SR sm_config. # We need only to trigger mpathcount try: cmd = [os.path.join(constants.SM_DEST, 'mpathcount.py'), scsi_id] util.pread2(cmd) except: util.SMlog("RawHBA: something wrong with mpathcount") ret = VDI.VDI.attach(self, sr_uuid, vdi_uuid) self.sr.update_stats(self.size) return ret
def map_by_scsibus(sid,npaths=0): # Synchronously creates/refreshs the MP map for a single SCSIid. # Gathers the device vector from /dev/disk/by-scsibus - we expect # there to be 'npaths' paths util.SMlog("map_by_scsibus: sid=%s" % sid) devices = [] # Wait for up to 60 seconds for n devices to appear for attempt in range(0,60): devices = scsiutil._genReverseSCSIidmap(sid) # If we've got the right number of paths, or we don't know # how many devices there ought to be, tell multipathd about # the paths, and return. if(len(devices)>=npaths or npaths==0): # Enable this device's sid: it could be blacklisted # We expect devices to be blacklisted according to their # wwid only. We go through the list of paths until we have # a definite answer about the device's blacklist status. # If the path we are checking is down, we cannot tell. for dev in devices: try: if wwid_conf.is_blacklisted(dev): try: wwid_conf.edit_wwid(sid) except: util.SMlog("WARNING: exception raised while " "attempting to modify multipath.conf") try: mpath_cli.reconfigure() except: util.SMlog("WARNING: exception raised while " "attempting to reconfigure") time.sleep(5) break except wwid_conf.WWIDException as e: util.SMlog(e.errstr) else: util.SMlog("Device 'SCSI_id: {}' is inaccessible; " "All paths are down.".format(sid)) __map_explicit(devices) return time.sleep(1) __map_explicit(devices)
def map_by_scsibus(sid, npaths=0): # Synchronously creates/refreshs the MP map for a single SCSIid. # Gathers the device vector from /dev/disk/by-scsibus - we expect # there to be 'npaths' paths util.SMlog("map_by_scsibus: sid=%s" % sid) devices = [] # Wait for up to 60 seconds for n devices to appear for attempt in range(0, 60): devices = scsiutil._genReverseSCSIidmap(sid) # If we've got the right number of paths, or we don't know # how many devices there ought to be, tell multipathd about # the paths, and return. if (len(devices) >= npaths or npaths == 0): # Enable this device's sid: it could be blacklisted # We expect devices to be blacklisted according to their # wwid only. We go through the list of paths until we have # a definite answer about the device's blacklist status. # If the path we are checking is down, we cannot tell. for dev in devices: try: if wwid_conf.is_blacklisted(dev): try: wwid_conf.edit_wwid(sid) except: util.SMlog("WARNING: exception raised while " "attempting to modify multipath.conf") try: mpath_cli.reconfigure() except: util.SMlog("WARNING: exception raised while " "attempting to reconfigure") time.sleep(5) break except wwid_conf.WWIDException as e: util.SMlog(e.errstr) else: util.SMlog("Device 'SCSI_id: {}' is inaccessible; " "All paths are down.".format(sid)) __map_explicit(devices) return time.sleep(1) __map_explicit(devices)
def _find_LUN(svid): basepath = "/dev/disk/by-csldev/" if svid.startswith("NETAPP_"): # special attention for NETAPP SVIDs svid_parts = svid.split("__") globstr = basepath + "NETAPP__LUN__" + "*" + svid_parts[2] + "*" + svid_parts[-1] + "*" else: globstr = basepath + svid + "*" path = util.wait_for_path_multi(globstr, MAX_TIMEOUT) if not len(path): return [] svid_to_use = re.sub("-[0-9]*:[0-9]*:[0-9]*:[0-9]*$","",os.path.basename(path)) return scsiutil._genReverseSCSIidmap(svid_to_use, pathname="csldev")
def GetConfig(scsiid): try: retVal = True configMap = {} device = scsiutil._genReverseSCSIidmap(scsiid)[0] XenCertPrint("GetConfig - device: %s" % device) cmd = ["/usr/lib/udev/scsi_id", "--replace-whitespace", "--whitelisted", "--export", device] ret = util.pread2(cmd) XenCertPrint("GetConfig - scsi_if output: %s" % ret) for tuple in ret.split('\n'): if tuple.find('=') != -1: configMap[tuple.split('=')[0]] = tuple.split('=')[1] except Exception, e: XenCertPrint("There was an exception getting SCSI device config. Exception: %s" % str(e)) retVal = False
def _query(self, path, id, uuid=None, scsi_id=None): """Overloaded function with mostly duplicated code""" if uuid: self.uuid = uuid else: util.SMlog("RawHBA: uuid should not be generated..") self.uuid = scsiutil.gen_uuid_from_string( scsiutil.getuniqueserial(path) ) if scsi_id: self.SCSIid = scsi_id else: # It is usually unnecessary to calculate it again but scsi_id # is used as a flag in this function and we cannot guarantee # this info is already available at call time self.SCSIid = scsiutil.getSCSIid(path) self.location = self.uuid self.vendor = scsiutil.getmanufacturer(path) self.serial = scsiutil.getserial(path) self.LUNid = id # Handle resize done at the array size. The resize gets reflected # only when the vdi is not in detached state. Do this if we the vdi # is known to xapi try: vdi_ref = self.sr.session.xenapi.VDI.get_by_uuid(self.uuid) # Check if the vbd is not in attached state, do a LUN rescan # to reflect the array LUN dev = [path] if scsi_id: # We want all the devices with this scsi_id dev = scsiutil._genReverseSCSIidmap(scsi_id) if self.sr.srcmd.cmd == "vdi_attach": scsiutil.refreshdev(dev) elif not B_util.is_vdi_attached(self.sr.session, vdi_ref): scsiutil.refreshdev(dev) except: pass self.size = scsiutil.getsize(path) self.path = path sm_config = util.default(self, "sm_config", lambda: {}) sm_config['LUNid'] = str(self.LUNid) sm_config['SCSIid'] = self.SCSIid # Make sure to use kernel blkback (not blktap3) for raw LUNs sm_config['backend-kind'] = 'vbd' self.sm_config = sm_config
def _find_LUN(svid): basepath = "/dev/disk/by-csldev/" if svid.startswith("NETAPP_"): # special attention for NETAPP SVIDs svid_parts = svid.split("__") globstr = basepath + "NETAPP__LUN__" + "*" + svid_parts[ 2] + "*" + svid_parts[-1] + "*" else: globstr = basepath + svid + "*" path = util.wait_for_path_multi(globstr, MAX_TIMEOUT) if not len(path): return [] svid_to_use = re.sub("-[0-9]*:[0-9]*:[0-9]*:[0-9]*$", "", os.path.basename(path)) return scsiutil._genReverseSCSIidmap(svid_to_use, pathname="csldev")
def GetConfig(scsiid): try: retVal = True configMap = {} device = scsiutil._genReverseSCSIidmap(scsiid)[0] XenCertPrint("GetConfig - device: %s" % device) list = device.split('/')[1] justDev = device.split('/')[2] XenCertPrint("GetConfig - just the device: %s" % justDev) cmd = ["scsi_id", "-u", "-g", "-x", "-s", "/block/%s" % justDev, "-d", device] ret = util.pread2(cmd) XenCertPrint("GetConfig - scsi_if output: %s" % ret) for tuple in ret.split('\n'): if tuple.find('=') != -1: configMap[tuple.split('=')[0]] = tuple.split('=')[1] except Exception, e: XenCertPrint("There was an exception getting SCSI device config. Exception: %s" % str(e)) retVal = False
def map_by_scsibus(sid, npaths=0): # Synchronously creates/refreshs the MP map for a single SCSIid. # Gathers the device vector from /dev/disk/by-scsibus - we expect # there to be 'npaths' paths util.SMlog("map_by_scsibus: sid=%s" % sid) devices = [] # Wait for up to 60 seconds for n devices to appear for attempt in range(0, 60): devices = scsiutil._genReverseSCSIidmap(sid) # If we've got the right number of paths, or we don't know # how many devices there ought to be, tell multipathd about # the paths, and return. if (len(devices) >= npaths or npaths == 0): # Enable this device's sid: it could be blacklisted # We expect devices to be blacklisted according to their # wwid only. Checking the first one is sufficient if wwid_conf.is_blacklisted(devices[0]): try: wwid_conf.edit_wwid(sid) except: util.SMlog("WARNING: exception raised while attempting to" " modify multipath.conf") try: mpath_cli.reconfigure() except: util.SMlog("WARNING: exception raised while attempting to" " reconfigure") time.sleep(5) __map_explicit(devices) return time.sleep(1) __map_explicit(devices)
def set_scheduler(dev, str): devices = [] if not scsiutil.match_dm(dev): # Remove partition numbers devices.append(diskFromPartition(dev).replace('/', '!')) else: rawdev = diskFromPartition(dev) devices = map(lambda x: os.path.realpath(x)[5:], scsiutil._genReverseSCSIidmap(rawdev.split('/')[-1])) for d in devices: path = "/sys/block/%s/queue/scheduler" % d if not os.path.exists(path): SMlog("no path %s" % path) return try: f = open(path, 'w') f.write("%s\n" % str) f.close() SMlog("Set scheduler to [%s] on dev [%s]" % (str,d)) except: SMlog("Error setting scheduler to [%s] on dev [%s]" % (str,d)) pass
def map_by_scsibus(sid,npaths=0): # Synchronously creates/refreshs the MP map for a single SCSIid. # Gathers the device vector from /dev/disk/by-scsibus - we expect # there to be 'npaths' paths util.SMlog("map_by_scsibus: sid=%s" % sid) devices = [] # Wait for up to 60 seconds for n devices to appear for attempt in range(0,60): devices = scsiutil._genReverseSCSIidmap(sid) # If we've got the right number of paths, or we don't know # how many devices there ought to be, tell multipathd about # the paths, and return. if(len(devices)>=npaths or npaths==0): # Enable this device's sid: it could be blacklisted # We expect devices to be blacklisted according to their # wwid only. Checking the first one is sufficient if wwid_conf.is_blacklisted(devices[0]): try: wwid_conf.edit_wwid(sid) except: util.SMlog("WARNING: exception raised while attempting to" " modify multipath.conf") try: mpath_cli.reconfigure() except: util.SMlog("WARNING: exception raised while attempting to" " reconfigure") time.sleep(5) __map_explicit(devices) return time.sleep(1) __map_explicit(devices)
def map_by_scsibus(sid, npaths=0): # Synchronously creates/refreshs the MP map for a single SCSIid. # Gathers the device vector from /dev/disk/by-scsibus - we expect # there to be 'npaths' paths util.SMlog("map_by_scsibus: sid=%s" % sid) devices = [] # Wait for up to 60 seconds for n devices to appear for attempt in range(0, 60): devices = scsiutil._genReverseSCSIidmap(sid) # If we've got the right number of paths, or we don't know # how many devices there ought to be, tell multipathd about # the paths, and return. if (len(devices) >= npaths or npaths == 0): __map_explicit(devices) return time.sleep(1) __map_explicit(devices)
def set_scheduler(dev, str): devices = [] if not scsiutil.match_dm(dev): # Remove partition numbers devices.append(diskFromPartition(dev).replace('/', '!')) else: rawdev = diskFromPartition(dev) devices = map(lambda x: os.path.realpath(x)[5:], scsiutil._genReverseSCSIidmap(rawdev.split('/')[-1])) for d in devices: path = "/sys/block/%s/queue/scheduler" % d if not os.path.exists(path): SMlog("no path %s" % path) return try: f = open(path, 'w') f.write("%s\n" % str) f.close() SMlog("Set scheduler to [%s] on dev [%s]" % (str, d)) except: SMlog("Error setting scheduler to [%s] on dev [%s]" % (str, d)) pass
def map_by_scsibus(sid,npaths=0): # Synchronously creates/refreshs the MP map for a single SCSIid. # Gathers the device vector from /dev/disk/by-scsibus - we expect # there to be 'npaths' paths util.SMlog("map_by_scsibus: sid=%s" % sid) devices = [] # Wait for up to 60 seconds for n devices to appear for attempt in range(0,60): devices = scsiutil._genReverseSCSIidmap(sid) # If we've got the right number of paths, or we don't know # how many devices there ought to be, tell multipathd about # the paths, and return. if(len(devices)>=npaths or npaths==0): __map_explicit(devices) return time.sleep(1) __map_explicit(devices)
def get_TargetID_LunNUM(SCSIid): devices = scsiutil._genReverseSCSIidmap(SCSIid) cmd = [MPPGETAIDLNOBIN, devices[0]] return util.pread2(cmd).split('\n')[0]
def add(scsi_id): devices = scsiutil._genReverseSCSIidmap(scsi_id) for device in devices: realpath = os.path.realpath(device) base = os.path.basename(realpath) mpath_cli.add_path(base)