def attach(self, sr_uuid): if not self._checkmount(): self.validate_remotepath(False) util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget') io_timeout = util.get_nfs_timeout(self.session, sr_uuid) self.mount_remotepath(sr_uuid, io_timeout) self.attached = True
def create(self, sr_uuid, size): util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget') self.validate_remotepath(True) if self._checkmount(): raise xs_errors.XenError('NFSAttached') # Set the target path temporarily to the base dir # so that we can create the target SR directory self.remotepath = self.dconf['serverpath'].encode('utf-8') try: self.mount_remotepath(sr_uuid) except Exception as exn: try: os.rmdir(self.path) except: pass raise exn if not self.nosubdir: newpath = os.path.join(self.path, sr_uuid) if util.ioretry(lambda: util.pathexists(newpath)): if len(util.ioretry(lambda: util.listdir(newpath))) != 0: self.detach(sr_uuid) raise xs_errors.XenError('SRExists') else: try: util.ioretry(lambda: util.makedirs(newpath)) except util.CommandException as inst: if inst.code != errno.EEXIST: self.detach(sr_uuid) raise xs_errors.XenError( 'NFSCreate', opterr='remote directory creation error is %d' % inst.code) self.detach(sr_uuid)
def attach(self, sr_uuid): self.validate_remotepath(False) #self.remotepath = os.path.join(self.dconf['serverpath'], sr_uuid) self.remotepath = self.dconf['serverpath'] util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget') self.mount_remotepath(sr_uuid)
def attach(self, sr_uuid): if not self._checkmount(): self.validate_remotepath(False) util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget') #Extract timeout and retrans values, if any io_timeout = nfs.get_nfs_timeout(self.other_config) io_retrans = nfs.get_nfs_retrans(self.other_config) self.mount_remotepath(sr_uuid, timeout=io_timeout, retrans=io_retrans) self.attached = True
def _scan_IQNs(self): # Verify iSCSI target and port util._testHost(self.target, self.port, 'ISCSITarget') # Test and set the initiatorname file iscsilib.ensure_daemon_running_ok(self.localIQN) map = iscsilib.discovery(self.target, self.port, self.chapuser, self.chappassword) map.append(("%s:%d" % (self.targetlist,self.port),"0","*")) self.print_entries(map)
def attach(self, sr_uuid): dbg_prt("[rbdsr] attach") ### Getting MON list using admin key above ceph_mon_list_xml = self._getCEPH_response('ceph mon_status -f xml') ceph_mon_list = self._formatMON_list(ceph_mon_list_xml) # We got accurate list of monitor addresses, need pass that list of IPs to rbd add srting accurate_address_string = '' ''' TODO: very long list-to-string conversion, should be something like: address_string = ''.join(ceph_mon_list).replace('\n',',') if len(ceph_mon_list) >= 1''' if len(ceph_mon_list) >= 1: address_string = '' for address in ceph_mon_list: address_string += address.replace('\n', ',') self.dconf['targetlist'] = address_string[:-1] accurate_address_string = address_string[:-1] else: accurate_address_string = ceph_mon_list ### Getting admin key using ssh command if self.dconf.has_key('SCSIid') and self.dconf['SCSIid']: util._testHost(self.dconf['target'].split(',')[0], long(self.dconf['port']), 'RBD Monitor') rbd_auth_output = self._getCEPH_response( 'ceph auth list| grep admin -A1| grep key') rbd_auth_key = self._formatCEPH_key(rbd_auth_output) rbd_image_name = self.dconf['SCSIid'] dbg_prt("[rbdsr] rbd image name: %s", rbd_image_name) attach_string = '%s name=admin,secret=%s %s %s' % ( accurate_address_string, rbd_auth_key, self.dconf['targetIQN'], rbd_image_name) if not os.path.exists('/sys/bus/rbd'): os.execlp("modprobe", "modprobe", "rbd") rbd_disk_path = '/dev/disk/by-id/scsi-%s' % rbd_image_name rbd_scsi_path = '/dev/disk/by-scsid/%s' % rbd_image_name rbd_block_index = self._getRBD_index(rbd_image_name) if not os.path.exists(rbd_disk_path) and not rbd_block_index: dbg_prt("[rbdsr] add rbd device begin:") try: rbd_add = open('/sys/bus/rbd/add', 'w') rbd_add.write(attach_string) rbd_add.close() rbd_image_index = str(self._getRBD_index(rbd_image_name)) os.symlink('/dev/rbd%s' % rbd_image_index, rbd_disk_path) os.makedirs(rbd_scsi_path) os.symlink('../../../rbd%s' % rbd_image_index, '%s/rbd%s' % (rbd_scsi_path, rbd_image_index)) self.attached = True except IOError, e: util.SMlog('the error is %s' % e) self.attached = False else: dbg_prt("[rbdsr] rbd_disk_path:%s , rbd_block_index:%s", rbd_disk_path, rbd_block_index)
def _scan_IQNs(self): # Verify iSCSI target and port util._testHost(self.target, self.port, 'ISCSITarget') # Test and set the initiatorname file iscsilib.ensure_daemon_running_ok(self.localIQN) map = iscsilib.discovery(self.target, self.port, self.chapuser, self.chappassword) map.append(("%s:%d" % (self.targetlist, self.port), "0", "*")) self.print_entries(map)
def attach(self, sr_uuid): dbg_prt("[rbdsr] attach") ### Getting MON list using admin key above ceph_mon_list_xml = self._getCEPH_response('ceph mon_status -f xml') ceph_mon_list = self._formatMON_list(ceph_mon_list_xml) # We got accurate list of monitor addresses, need pass that list of IPs to rbd add srting accurate_address_string = '' ''' TODO: very long list-to-string conversion, should be something like: address_string = ''.join(ceph_mon_list).replace('\n',',') if len(ceph_mon_list) >= 1''' if len(ceph_mon_list) >= 1: address_string = '' for address in ceph_mon_list: address_string += address.replace('\n',',') self.dconf['targetlist'] = address_string[:-1] accurate_address_string = address_string[:-1] else: accurate_address_string = ceph_mon_list ### Getting admin key using ssh command if self.dconf.has_key('SCSIid') and self.dconf['SCSIid']: util._testHost(self.dconf['target'].split(',')[0], long(self.dconf['port']), 'RBD Monitor') rbd_auth_output = self._getCEPH_response('ceph auth list| grep admin -A1| grep key') rbd_auth_key = self._formatCEPH_key(rbd_auth_output) rbd_image_name = self.dconf['SCSIid'] dbg_prt("[rbdsr] rbd image name: %s",rbd_image_name) attach_string = '%s name=admin,secret=%s %s %s' % (accurate_address_string, rbd_auth_key, self.dconf['targetIQN'], rbd_image_name) if not os.path.exists('/sys/bus/rbd'): os.execlp("modprobe", "modprobe", "rbd") rbd_disk_path = '/dev/disk/by-id/scsi-%s' % rbd_image_name rbd_scsi_path = '/dev/disk/by-scsid/%s' % rbd_image_name rbd_block_index = self._getRBD_index(rbd_image_name) if not os.path.exists(rbd_disk_path) and not rbd_block_index: dbg_prt("[rbdsr] add rbd device begin:") try: rbd_add = open('/sys/bus/rbd/add','w') rbd_add.write(attach_string) rbd_add.close() rbd_image_index = str(self._getRBD_index(rbd_image_name)) os.symlink('/dev/rbd%s' % rbd_image_index , rbd_disk_path) os.makedirs(rbd_scsi_path) os.symlink('../../../rbd%s' % rbd_image_index, '%s/rbd%s' % (rbd_scsi_path,rbd_image_index)) self.attached = True except IOError, e: util.SMlog('the error is %s' % e) self.attached = False else: dbg_prt("[rbdsr] rbd_disk_path:%s , rbd_block_index:%s",rbd_disk_path,rbd_block_index)
def attach(self, sr_uuid): rbd_index = self._getRBDIndex(self.dconf['image']) if self.dconf.has_key('image') and \ self.dconf['image'] and \ os.path.exists('/dev/rbd%s' % rbd_index): self.attached = True return if self.dconf.has_key('image') and self.dconf['image']: rbd_image = self.dconf['image'] for target in self.dconf['target'].split(','): util._testHost(target, long(self.dconf['port']), 'RBD Monitor') attach_string = '{targets} name={user},secret={secret} {pool} {image}' attach_values = { 'targets': self.dconf['targetlist'], 'user': self.dconf['user'], 'secret': '<protected>', 'pool': self.dconf['pool'], 'image': rbd_image } util.SMlog('Attach string: %s' % attach_string.format(**attach_values)) attach_values['secret'] = self.dconf['auth'] if not os.path.exists('/sys/bus/rbd'): os.execlp('modprobe', 'modprobe', 'rbd') rbd_disk_path = '/dev/disk/by-id/scsi-%s' % rbd_image rbd_scsi_path = '/dev/disk/by-scsid/%s' % rbd_image if not os.path.exists(rbd_disk_path) and not rbd_index: try: with open('/sys/bus/rbd/add', 'w') as rbd_add: rbd_add.write(attach_string.format(**attach_values)) # # update rbd_index after attaching # rbd_index = self._getRBDIndex(self.dconf['image']) os.symlink('/dev/rbd%s' % rbd_index, rbd_disk_path) os.makedirs(rbd_scsi_path) os.symlink('../../../rbd%s' % rbd_index, '%s/rbd%s' % (rbd_scsi_path, rbd_index)) self.attached = True self.SCSIid = rbd_index except IOError, e: util.SMlog('Attach thrown exception and the error is %s' % e) self.attached = False
def create(self, sr_uuid, size): util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget') self.validate_remotepath(True) if self._checkmount(): raise xs_errors.XenError('NFSAttached') # Set the target path temporarily to the base dir # so that we can create the target SR directory self.remotepath = self.dconf['serverpath'] try: self.mount_remotepath(sr_uuid) except Exception, exn: try: os.rmdir(self.path) except: pass raise exn
def probe(self): # Verify NFS target and port util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget') self.validate_remotepath(True) self.check_server() temppath = os.path.join(SR.MOUNT_BASE, PROBE_MOUNTPOINT) self.mount(temppath, self.dconf['serverpath']) try: return nfs.scan_srlist(temppath) finally: try: nfs.unmount(temppath, True) except: pass
def probe(self): # Verify NFS target and port util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget') self.validate_remotepath(True) self.check_server() temppath = os.path.join(SR.MOUNT_BASE, PROBE_MOUNTPOINT) self.mount(temppath, self.remotepath) try: return nfs.scan_srlist(temppath, self.dconf) finally: try: nfs.unmount(temppath, True) except: pass
def create(self, sr_uuid, size): util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget') self.validate_remotepath(True) if self._checkmount(): raise xs_errors.XenError('NFSAttached') # Set the target path temporarily to the base dir # so that we can create the target SR directory self.remotepath = self.dconf['serverpath'].encode('utf-8') try: self.mount_remotepath(sr_uuid) except Exception, exn: try: os.rmdir(self.path) except: pass raise exn
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) = 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): 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, self._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 ) == 'ISCSI login failed, verify CHAP credentials': 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 attach(self, sr_uuid): self.validate_remotepath(False) self.remotepath = os.path.join(self.dconf['serverpath'], sr_uuid) util._testHost(self.dconf['server'], NFSPORT, 'NFSTarget') io_timeout = util.get_nfs_timeout(self.session, sr_uuid) self.mount_remotepath(sr_uuid, io_timeout)
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)
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")
def attach(self, sr_uuid): """Std. attach""" # Very-Legacy mode means the ISOs are in the local fs - so no need to attach. if 'legacy_mode' in self.dconf: # Verify path exists if not os.path.exists(self.mountpoint): raise xs_errors.XenError('ISOLocalPath') return # Check whether we're already mounted if self._checkmount(): return # Create the mountpoint if it's not already there if not util.isdir(self.mountpoint): util.makedirs(self.mountpoint) mountcmd = [] location = util.to_plain_string(self.dconf['location']) # TODO: Have XC standardise iso type string protocol = 'nfs_iso' options = '' if 'type' in self.dconf: protocol = self.dconf['type'] elif ":/" not in location: protocol = 'cifs' if 'options' in self.dconf: options = self.dconf['options'].split(' ') if protocol == 'cifs': options = filter(lambda x: x != "", options) else: options = self.getNFSOptions(options) # SMB options are passed differently for create via # XC/xe sr-create and create via xe-mount-iso-sr # In both cases check if SMB version is passed are not. # If not use self.smbversion. if protocol == 'cifs': if 'type' in self.dconf: # Create via XC or sr-create # Check for username and password mountcmd = ["mount.cifs", location, self.mountpoint] if 'vers' in self.dconf: self.is_smbversion_specified = True self.smbversion = self.dconf['vers'] util.SMlog("self.dconf['vers'] = %s" % self.dconf['vers']) self.appendCIFSMountOptions(mountcmd) else: # Creation via xe-mount-iso-sr try: mountcmd = ["mount", location, self.mountpoint] if options and options[0] == '-o': pos = options[1].find('vers=') if pos == -1: options[1] += ',' + self.getSMBVersion() else: self.smbversion = self.getSMBVersionFromOptions( options[1]) self.is_smbversion_specified = True else: raise ValueError mountcmd.extend(options) except ValueError: raise xs_errors.XenError('ISOInvalidXeMountOptions') # Check the validity of 'smbversion'. # Raise an exception for any invalid version. if self.smbversion not in [SMB_VERSION_1, SMB_VERSION_3]: raise xs_errors.XenError('ISOInvalidSMBversion') # Attempt mounting try: if protocol == 'nfs_iso': # For NFS, do a soft mount with tcp as protocol. Since ISO SR is # going to be r-only, a failure in nfs link can be reported back # to the process waiting. serv_path = location.split(':') util._testHost(serv_path[0], NFSPORT, 'NFSTarget') nfs.soft_mount(self.mountpoint, serv_path[0], serv_path[1], 'tcp', useroptions=options, nfsversion=self.nfsversion) else: smb3_fail_reason = None if self.smbversion in SMB_VERSION_3: util.SMlog('ISOSR mount over smb 3.0') try: self.mountOverSMB(mountcmd) except util.CommandException as inst: if not self.is_smbversion_specified: util.SMlog('Retrying ISOSR mount over smb 1.0') smb3_fail_reason = inst.reason # mountcmd is constructed such that the last two # items will contain -o argument and its value. del mountcmd[-2:] self.smbversion = SMB_VERSION_1 if not options: self.appendCIFSMountOptions(mountcmd) else: if options[0] == '-o': # regex can be used here since we have # already validated version entry options[1] = re.sub( 'vers=3.0', 'vers=1.0', options[1]) mountcmd.extend(options) self.mountOverSMB(mountcmd) else: raise xs_errors.XenError('ISOMountFailure', opterr=inst.reason) else: util.SMlog('ISOSR mount over smb 1.0') self.mountOverSMB(mountcmd) except util.CommandException as inst: if not self.is_smbversion_specified: raise xs_errors.XenError('ISOMountFailure', opterr=smb3_fail_reason) else: raise xs_errors.XenError('ISOMountFailure', opterr=inst.reason) # Check the iso_path is accessible if not self._checkmount(): self.detach(sr_uuid) raise xs_errors.XenError('ISOSharenameFailure')
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
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)
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) = 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): 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, self._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) 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) == 'ISCSI login failed, verify CHAP credentials': 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 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