From 6ff038a9c3d671fe78c1af356d467b04c0281de4 Mon Sep 17 00:00:00 2001 From: anthony Date: Fri, 17 Dec 2010 15:53:08 -0800 Subject: [PATCH] delete ISCSISR.py --- .../xenserver/xenserver56/ISCSISR.py | 670 ------------------ .../vm/hypervisor/xenserver/xenserver56/patch | 1 - 2 files changed, 671 deletions(-) delete mode 100755 scripts/vm/hypervisor/xenserver/xenserver56/ISCSISR.py diff --git a/scripts/vm/hypervisor/xenserver/xenserver56/ISCSISR.py b/scripts/vm/hypervisor/xenserver/xenserver56/ISCSISR.py deleted file mode 100755 index a46a2353e11..00000000000 --- a/scripts/vm/hypervisor/xenserver/xenserver56/ISCSISR.py +++ /dev/null @@ -1,670 +0,0 @@ -#!/usr/bin/python -# Copyright (C) 2006-2007 XenSource Ltd. -# Copyright (C) 2008-2009 Citrix Ltd. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published -# by the Free Software Foundation; version 2.1 only. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# ISCSISR: ISCSI software initiator SR driver -# - -import SR, VDI, SRCommand, util -import statvfs, time, LUNperVDI -import os, socket, sys, re, glob -import xml.dom.minidom -import shutil, xmlrpclib -import scsiutil, iscsilib -import xs_errors, errno - -CAPABILITIES = ["SR_PROBE","VDI_CREATE","VDI_DELETE","VDI_ATTACH", - "VDI_DETACH", "VDI_INTRODUCE"] - -CONFIGURATION = [ [ 'target', 'IP address or hostname of the iSCSI target (required)' ], \ - [ 'targetIQN', 'The IQN of the target LUN group to be attached (required)' ], \ - [ 'chapuser', 'The username to be used during CHAP authentication (optional)' ], \ - [ 'chappassword', 'The password to be used during CHAP authentication (optional)' ], \ - [ 'port', 'The network port number on which to query the target (optional)' ], \ - [ 'multihomed', 'Enable multi-homing to this target, true or false (optional, defaults to same value as host.other_config:multipathing)' ] ] - -DRIVER_INFO = { - 'name': 'iSCSI', - 'description': 'Base ISCSI SR driver, provides a LUN-per-VDI. Does not support creation of VDIs but accesses existing LUNs on a target.', - 'vendor': 'Citrix Systems Inc', - 'copyright': '(C) 2008 Citrix Systems Inc', - 'driver_version': '1.0', - 'required_api_version': '1.0', - 'capabilities': CAPABILITIES, - 'configuration': CONFIGURATION - } - -INITIATORNAME_FILE = '/etc/iscsi/initiatorname.iscsi' -SECTOR_SHIFT = 9 -DEFAULT_PORT = 3260 -# 2^16 Max port number value -MAXPORT = 65535 -MAX_TIMEOUT = 15 -MAX_LUNID_TIMEOUT = 60 -ISCSI_PROCNAME = "iscsi_tcp" - -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 - - - @util.transformpasswords - 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.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) - 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 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"] - 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') - - self.attached = False - - def create(self, sr_uuid, size): - # Check whether an SR already exists - SRs = self.session.xenapi.SR.get_all_records() - for sr in SRs: - record = SRs[sr] - sm_config = record["sm_config"] - if sm_config.has_key('targetIQN') and \ - sm_config['targetIQN'] == self.targetIQN: - raise xs_errors.XenError('SRInUse') - self.attach(sr_uuid) - # Wait up to MAX_TIMEOUT for devices to appear - util.wait_for_path(self.path, MAX_TIMEOUT) - - if self._loadvdis() > 0: - scanrecord = SR.ScanRecord(self) - scanrecord.synchronise() - try: - self.detach(sr_uuid) - except: - pass - self.sm_config = self.session.xenapi.SR.get_sm_config(self.sr_ref) - self.sm_config['disktype'] = 'Raw' - self.sm_config['datatype'] = 'ISCSI' - self.sm_config['target'] = self.target - self.sm_config['targetIQN'] = self.targetIQN - self.sm_config['multipathable'] = 'true' - self.session.xenapi.SR.set_sm_config(self.sr_ref, self.sm_config) - return - - def delete(self, sr_uuid): - self.detach(sr_uuid) - return - - def probe(self): - SRs = self.session.xenapi.SR.get_all_records() - Recs = {} - for sr in SRs: - record = SRs[sr] - sm_config = record["sm_config"] - if sm_config.has_key('targetIQN') and \ - sm_config['targetIQN'] == self.targetIQN: - Recs[record["uuid"]] = sm_config - return self.srlist_toxml(Recs) - - - def scan(self, sr_uuid): - if not self.passthrough: - if not self.attached: - raise xs_errors.XenError('SRUnavailable') - self.refresh() - time.sleep(2) # it seems impossible to tell when a scan's finished - self._loadvdis() - self.physical_utilisation = self.physical_size - for uuid, vdi in self.vdis.iteritems(): - if vdi.managed: - self.physical_utilisation += vdi.size - self.virtual_allocation = self.physical_utilisation - return super(ISCSISR, self).scan(sr_uuid) - - def vdi(self, uuid): - return LUNperVDI.RAWVDI(self, uuid) - - 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_LUN_bylunid(self, lunid): - if not self.attached: - raise xs_errors.XenError('SRUnavailable') - connected = [] - for val in self.adapter: - if not self.pathdict.has_key(val): - continue - rec = self.pathdict[val] - path = os.path.join(rec['path'],"LUN%s" % lunid) - util.SMlog("path: %s" % path) - realpath = os.path.realpath(path) - util.SMlog("realpath: %s" % realpath) - host = self.adapter[val] - if not self.devs.has_key(realpath): - l = [realpath, host, 0, 0, lunid] - scsiutil.scsi_dev_ctrl(l,"add") - if not util.wait_for_path(path, MAX_LUNID_TIMEOUT): - util.SMlog("Unable to detect LUN attached to host on path [%s]" % path) - continue - else: - # Verify that we are not seeing a stale LUN map - try: - real_SCSIid = scsiutil.getSCSIid(realpath) - cur_scsibuspath = glob.glob('/dev/disk/by-scsibus/*-%s:0:0:%s' % (host,lunid)) - cur_SCSIid = os.path.basename(cur_scsibuspath[0]).split("-")[0] - assert(cur_SCSIid == real_SCSIid) - except: - scsiutil.rescan([host]) - if not os.path.exists('/dev/disk/by-scsibus/%s-%s:0:0:%s' % \ - (real_SCSIid,host,lunid)): - util.SMlog("Unable to detect LUN attached to host after bus re-probe") - continue - connected.append(path) - return connected - - def _attach_LUN_byserialid(self, serialid): - if not self.attached: - raise xs_errors.XenError('SRUnavailable') - connected = [] - for val in self.adapter: - if not self.pathdict.has_key(val): - continue - rec = self.pathdict[val] - path = os.path.join(rec['path'],"SERIAL-%s" % serialid) - realpath = os.path.realpath(path) - if not self.devs.has_key(realpath): - if not util.wait_for_path(path, 5): - util.SMlog("Unable to detect LUN attached to host on serial path [%s]" % path) - continue - connected.append(path) - return connected - - def _detach_LUN_bylunid(self, lunid, SCSIid): - if not self.attached: - raise xs_errors.XenError('SRUnavailable') - if self.mpath == 'true' and len(SCSIid): - self.mpathmodule.reset(SCSIid, True) - util.remove_mpathcount_field(self.session, self.host_ref, self.sr_ref, SCSIid) - for val in self.adapter: - if not self.pathdict.has_key(val): - continue - rec = self.pathdict[val] - path = os.path.join(rec['path'],"LUN%s" % lunid) - realpath = os.path.realpath(path) - if self.devs.has_key(realpath): - util.SMlog("Found key: %s" % realpath) - scsiutil.scsi_dev_ctrl(self.devs[realpath], 'remove') - # Wait for device to disappear - if not util.wait_for_nopath(realpath, MAX_LUNID_TIMEOUT): - util.SMlog("Device has not disappeared after %d seconds" % \ - MAX_LUNID_TIMEOUT) - else: - util.SMlog("Device [%s,%s] disappeared" % (realpath,path)) - - def _attach_LUN_bySCSIid(self, SCSIid): - if not self.attached: - raise xs_errors.XenError('SRUnavailable') - - path = self.mpathmodule.path(SCSIid) - if not util.pathexists(path): - self.refresh() - if not util.wait_for_path(path, MAX_TIMEOUT): - util.SMlog("Unable to detect LUN attached to host [%s]" \ - % path) - return False - return True - - - # This function queries the session for the attached LUNs - def _loadvdis(self): - count = 0 - if not os.path.exists(self.path): - return 0 - for file in filter(self.match_lun, util.listdir(self.path)): - vdi_path = os.path.join(self.path,file) - LUNid = file.replace("LUN","") - uuid = scsiutil.gen_uuid_from_string(scsiutil.getuniqueserial(vdi_path)) - obj = self.vdi(uuid) - obj._query(vdi_path, LUNid) - self.vdis[uuid] = obj - self.physical_size += obj.size - count += 1 - return count - - def refresh(self): - for val in self.adapter: - util.SMlog("Rescanning host adapter %s" % self.adapter[val]) - scsiutil.rescan([self.adapter[val]]) - - # Helper function for LUN-per-VDI VDI.introduce - def _getLUNbySMconfig(self, sm_config): - if not sm_config.has_key('LUNid'): - raise xs_errors.XenError('VDIUnavailable') - LUNid = long(sm_config['LUNid']) - if not len(self._attach_LUN_bylunid(LUNid)): - raise xs_errors.XenError('VDIUnavailable') - return os.path.join(self.path,"LUN%d" % LUNid) - - def print_LUNs(self): - self.LUNs = {} - if os.path.exists(self.path): - for file in util.listdir(self.path): - if file.find("LUN") != -1 and file.find("_") == -1: - vdi_path = os.path.join(self.path,file) - LUNid = file.replace("LUN","") - obj = self.vdi(self.uuid) - obj._query(vdi_path, LUNid) - self.LUNs[obj.uuid] = obj - - dom = xml.dom.minidom.Document() - element = dom.createElement("iscsi-target") - dom.appendChild(element) - for uuid in self.LUNs: - val = self.LUNs[uuid] - entry = dom.createElement('LUN') - element.appendChild(entry) - - for attr in ('vendor', 'serial', 'LUNid', \ - 'size', 'SCSIid'): - try: - aval = getattr(val, attr) - except AttributeError: - continue - - if aval: - subentry = dom.createElement(attr) - entry.appendChild(subentry) - textnode = dom.createTextNode(str(aval)) - subentry.appendChild(textnode) - - print >>sys.stderr,dom.toprettyxml() - - def print_entries(self, map): - dom = xml.dom.minidom.Document() - element = dom.createElement("iscsi-target-iqns") - dom.appendChild(element) - count = 0 - for address,tpgt,iqn in map: - entry = dom.createElement('TGT') - element.appendChild(entry) - subentry = dom.createElement('Index') - entry.appendChild(subentry) - textnode = dom.createTextNode(str(count)) - subentry.appendChild(textnode) - - try: - addr,port = address.split(":") - except: - addr = address - port = DEFAULT_PORT - subentry = dom.createElement('IPAddress') - entry.appendChild(subentry) - textnode = dom.createTextNode(str(addr)) - subentry.appendChild(textnode) - - if int(port) != DEFAULT_PORT: - subentry = dom.createElement('Port') - entry.appendChild(subentry) - textnode = dom.createTextNode(str(port)) - subentry.appendChild(textnode) - - subentry = dom.createElement('TargetIQN') - entry.appendChild(subentry) - textnode = dom.createTextNode(str(iqn)) - subentry.appendChild(textnode) - count += 1 - print >>sys.stderr,dom.toprettyxml() - - def srlist_toxml(self, SRs): - dom = xml.dom.minidom.Document() - element = dom.createElement("SRlist") - dom.appendChild(element) - - for val in SRs: - record = SRs[val] - entry = dom.createElement('SR') - element.appendChild(entry) - - subentry = dom.createElement("UUID") - entry.appendChild(subentry) - textnode = dom.createTextNode(val) - subentry.appendChild(textnode) - - subentry = dom.createElement("Target") - entry.appendChild(subentry) - textnode = dom.createTextNode(record['target']) - subentry.appendChild(textnode) - - subentry = dom.createElement("TargetIQN") - entry.appendChild(subentry) - textnode = dom.createTextNode(record['targetIQN']) - subentry.appendChild(textnode) - return dom.toprettyxml() - - def match_lun(self, s): - regex = re.compile("_") - if regex.search(s,0): - return False - regex = re.compile("LUN") - return regex.search(s, 0) - - -if __name__ == '__main__': - SRCommand.run(ISCSISR, DRIVER_INFO) -else: - SR.registerSR(ISCSISR) diff --git a/scripts/vm/hypervisor/xenserver/xenserver56/patch b/scripts/vm/hypervisor/xenserver/xenserver56/patch index 0959e1cd177..d3dc7881cd8 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56/patch @@ -11,7 +11,6 @@ # If [source path] does not start with '/' or '~', then it is relative path to the location of the patch file. scsiutil.py=/opt/xensource/sm NFSSR.py=/opt/xensource/sm -ISCSISR.py=/opt/xensource/sm LUNperVDI.py=/opt/xensource/sm nfs.py=/opt/xensource/sm vmops=..,0755,/etc/xapi.d/plugins