Skip to content
Browse files

CA-63779; EQL/SMI-S CVSM tests fail with "SR has no attached PBDs".

1)  Adding a safe host rescan module. This makes sure it is only invocation resc
anning a particular hostid.
2) _attachLUN_bylunid, should also add mpath maps for the LUN, if multipathing i
s enabled.
  • Loading branch information...
1 parent 810daf9 commit df08bd454a64cc66d0db61b0a341fdc02fe61326 Harsh Puri committed Aug 4, 2011
Showing with 134 additions and 1 deletion.
  1. +1 −0 Makefile
  2. +10 −1 drivers/ISCSISR.py
  3. +120 −0 drivers/scsi_host_rescan.py
  4. +3 −0 mk/sm.spec.in
View
1 Makefile
@@ -20,6 +20,7 @@ SM_LIBS += lvutil
SM_LIBS += lvmcache
SM_LIBS += util
SM_LIBS += scsiutil
+SM_LIBS += scsi_host_rescan
SM_LIBS += vhdutil
SM_LIBS += lvhdutil
SM_LIBS += xs_errors
View
11 drivers/ISCSISR.py
@@ -453,10 +453,11 @@ def _scan_IQNs(self):
map.append(("%s:%d" % (self.targetlist,self.port),"0","*"))
self.print_entries(map)
- def _attach_LUN_bylunid(self, lunid):
+ def _attach_LUN_bylunid(self, lunid, mpath = False):
if not self.attached:
raise xs_errors.XenError('SRUnavailable')
connected = []
+ cur_SCSIid = None
for val in self.adapter:
if not self.pathdict.has_key(val):
continue
@@ -498,6 +499,14 @@ def _attach_LUN_bylunid(self, lunid):
util.SMlog("Unable to detect LUN attached to host on path [%s]" % path)
continue
connected.append(path)
+
+ # if multipath enabled, refresh the mpath mapper
+ cur_scsibuspath = glob.glob('/dev/disk/by-scsibus/*-%s:0:0:%s' % (host,lunid))
+ cur_SCSIid = os.path.basename(cur_scsibuspath[0]).split("-")[0]
+ if mpath:
+ self._mpathHandle()
+ self.mpathmodule.refresh(cur_SCSIid, len(connected))
+
return connected
def _attach_LUN_byserialid(self, serialid):
View
120 drivers/scsi_host_rescan.py
@@ -0,0 +1,120 @@
+#!/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.
+#
+# This module implements a safe way to rescan a scsi host so that:
+# - at any time there is at most 1 rescan happening on a system for a hostid
+# - we have as few rescans as possible
+
+import lock
+import util
+import os
+import time
+import glob
+from datetime import datetime
+from xmlrpclib import DateTime
+
+HOST_LOCK_NAME_FORMAT = 'host%s'
+RESCAN_LOCK_NAME = 'rescan'
+START_TIME_FILE_PATH_FORMAT = '/var/run/host%s_starttime_%s'
+
+def _rescan_hostID(host):
+ util.SMlog("Performing rescan of host ID %s" % host)
+ path = '/sys/class/scsi_host/host%s/scan' % host
+ if os.path.exists(path):
+ try:
+ scanstring = "- - -"
+ f=open(path, 'w')
+ f.write('%s\n' % scanstring)
+ f.close()
+ # allow some time for undiscovered LUNs/channels to appear
+ time.sleep(2)
+ except Exception, e:
+ util.SMlog("Failed to perform full rescan of host: %s. "\
+ "Error: %s" % (host, str(e)))
+ raise Exception(str(e))
+
+def rescan(hostid):
+ try:
+ try:
+ # get the current time, call it x
+ curr_time = datetime.utcnow()
+
+ # acquire common lock
+ l = lock.Lock(RESCAN_LOCK_NAME, HOST_LOCK_NAME_FORMAT % hostid)
+ l.acquire()
+
+ while(1):
+ # check if starttime_anything exists
+ tryRescan = False
+ files = glob.glob(START_TIME_FILE_PATH_FORMAT % (hostid, '*'))
+ if len(files) == 0:
+ # if not, create starttime_x
+ path = START_TIME_FILE_PATH_FORMAT % (hostid, str(curr_time))
+ path = path.replace(' ', '_')
+ open(path, 'w').close()
+
+ # release common lock
+ l.release()
+
+ # perform host rescan
+ _rescan_hostID(hostid)
+
+ # acquire common lock
+ l.acquire()
+
+ # remove starttime_x
+ os.unlink(path)
+
+ # release common lock and exit
+ l.release()
+ break
+ else:
+ # if it does
+ # read the start time
+ start_time = files[0].split(START_TIME_FILE_PATH_FORMAT % (hostid, ''))[1]
+ start_time = DateTime(start_time.replace('__', ' '))
+
+ while(1):
+ # stick around till start_time exists
+ # drop common lock
+ l.release()
+
+ # sleep for a sec
+ time.sleep(1)
+
+ # acquire common lock
+ l.acquire()
+
+ # check if start time exists
+ if len(glob.glob(START_TIME_FILE_PATH_FORMAT % \
+ (hostid, '*'))) == 0:
+ tryRescan = False
+ if DateTime(str(curr_time)) < start_time:
+ # we are cool, this started before the rescan
+ # drop common lock and go home
+ l.release()
+ else:
+ # try to start a rescan
+ tryRescan = True
+ break
+ # else continue by default
+
+ if not tryRescan:
+ break
+
+ except Exception, e:
+ util.SMlog("Failed to perform rescan of host: %s. "\
+ "Error: %s" % (hostid, str(e)))
+ finally:
+ l.release()
+
View
3 mk/sm.spec.in
@@ -188,6 +188,9 @@ rm -rf $RPM_BUILD_ROOT
/opt/xensource/sm/scsiutil.py
/opt/xensource/sm/scsiutil.pyc
/opt/xensource/sm/scsiutil.pyo
+/opt/xensource/sm/scsi_host_rescan.py
+/opt/xensource/sm/scsi_host_rescan.pyc
+/opt/xensource/sm/scsi_host_rescan.pyo
/opt/xensource/sm/snapwatchd/_xslib.so
/opt/xensource/sm/snapwatchd/snapwatchd
/opt/xensource/sm/snapwatchd/xslib.py

0 comments on commit df08bd4

Please sign in to comment.
Something went wrong with that request. Please try again.