Skip to content

Commit 28e7894

Browse files
author
Deli Zhang
authored
Merge pull request #86 from DeliZhangX/private/deliz/CP-32847
CP-32847: Support manually block/unblock path
2 parents f4288d9 + 074fa09 commit 28e7894

File tree

5 files changed

+63
-36
lines changed

5 files changed

+63
-36
lines changed

src/XenCert/StorageHandler.py

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import commands
2222
import glob
2323
import random
24+
import operator
2425
from xml.dom import minidom
2526
import StorageHandlerUtil
2627
from XenCertLog import Print, PrintOnSameLine, XenCertPrint
@@ -88,11 +89,12 @@ def run(self):
8889
XenCertPrint("Could not write through the allocated disk space on test disk, please check the storage configuration manually. Exception: %s" % str(e))
8990

9091
class WaitForFailover(Thread):
91-
def __init__(self, session, scsiid, activePaths, noOfPaths):
92+
def __init__(self, session, scsiid, activePaths, noOfPaths, checkFunc):
9293
Thread.__init__(self)
9394
self.scsiid = scsiid
9495
self.activePaths = activePaths
9596
self.noOfPaths = noOfPaths
97+
self.checkFunc = checkFunc
9698

9799
def run(self):
98100
# Here wait for the expected number of paths to fail.
@@ -104,7 +106,8 @@ def run(self):
104106
while not pathsFailed and failoverTime < 50:
105107
try:
106108
(retVal, listPathConfigNew) = StorageHandlerUtil.get_path_status(self.scsiid, True)
107-
if self.noOfPaths == ((int)(self.activePaths) - len(listPathConfigNew)):
109+
currNoOfPaths = (int)(self.activePaths) - len(listPathConfigNew)
110+
if self.checkFunc(currNoOfPaths, self.noOfPaths):
108111
pathsFailed = True
109112
time.sleep(1)
110113
failoverTime += 1
@@ -245,8 +248,9 @@ def MPConfigVerificationTests(self):
245248

246249
if not os.path.exists(self.storage_conf['pathHandlerUtil']):
247250
raise Exception("Path handler util specified for multipathing tests does not exist!")
248-
249-
if self.storage_conf['storage_type'] == 'hba' and self.storage_conf['pathInfo'] is None:
251+
252+
isManBlock = os.path.basename(self.storage_conf['pathHandlerUtil']) == "blockunblockpaths"
253+
if self.storage_conf['storage_type'] == 'hba' and self.storage_conf['pathInfo'] is None and not isManBlock:
250254
raise Exception("Path related information not specified for storage type hba.")
251255

252256
if self.storage_conf['count'] is not None:
@@ -306,7 +310,7 @@ def MPConfigVerificationTests(self):
306310
global speedOfCopy
307311
Print("")
308312
Print("Iteration 1:\n")
309-
Print(" -> No manual blocking of paths.")
313+
Print(" -> No manual/script blocking of paths.")
310314
s = TimedDeviceIO(self.session.xenapi.VBD.get_device(vbd_ref))
311315
s.start()
312316
s.join()
@@ -325,29 +329,37 @@ def MPConfigVerificationTests(self):
325329
displayOperationStatus(True)
326330
checkPoint += 1
327331

328-
if len(self.listPathConfig) > 1:
332+
if len(self.listPathConfig) > 1:
329333
for i in range(2, iterationCount):
330334
maxTimeTaken = 0
331335
throughputForMaxTime = ''
332336
totalCheckPoints += 2
333-
Print("Iteration %d:\n" % i)
334-
if not self.RandomlyFailPaths():
335-
raise Exception("Failed to block paths.")
336-
337-
XenCertPrint("Dev Path Config = '%s', no of Blocked switch Paths = '%s'" % (self.listPathConfig, self.noOfPaths))
338-
339-
# Fail path calculation needs to be done only in case of hba SRs
340-
if "blockunblockhbapaths" in \
341-
self.storage_conf['pathHandlerUtil'].split('/')[-1]:
342-
#Calculate the number of devices to be found after the path block
343-
devicesToFail = (len(self.listPathConfig)/self.noOfTotalPaths) * self.noOfPaths
344-
XenCertPrint("Expected devices to fail: %s" % devicesToFail)
337+
Print("Iteration %d:\n" % i)
338+
339+
if isManBlock:
340+
Print(" -> Wait for manually blocking paths")
341+
self.WaitManualBlockUnblockPaths()
342+
devicesToFail = 1
343+
checkFunc = operator.ge
345344
else:
346-
devicesToFail = self.noOfPaths
345+
if not self.RandomlyFailPaths():
346+
raise Exception("Failed to block paths.")
347+
348+
XenCertPrint("Dev Path Config = '%s', no of Blocked switch Paths = '%s'" % (self.listPathConfig, self.noOfPaths))
349+
350+
# Fail path calculation needs to be done only in case of hba SRs
351+
if "blockunblockhbapaths" in \
352+
self.storage_conf['pathHandlerUtil'].split('/')[-1]:
353+
#Calculate the number of devices to be found after the path block
354+
devicesToFail = (len(self.listPathConfig)/self.noOfTotalPaths) * self.noOfPaths
355+
XenCertPrint("Expected devices to fail: %s" % devicesToFail)
356+
else:
357+
devicesToFail = self.noOfPaths
358+
checkFunc = operator.eq
347359

348-
s = WaitForFailover(self.session, device_config['SCSIid'], len(self.listPathConfig), devicesToFail)
360+
s = WaitForFailover(self.session, device_config['SCSIid'], len(self.listPathConfig), devicesToFail, checkFunc)
349361
s.start()
350-
362+
351363
while s.isAlive():
352364
timeTaken = 0
353365
s1 = TimedDeviceIO(self.session.xenapi.VBD.get_device(vbd_ref))
@@ -363,19 +375,25 @@ def MPConfigVerificationTests(self):
363375
if timeTaken > maxTimeTaken:
364376
maxTimeTaken = timeTaken
365377
throughputForMaxTime = speedOfCopy
366-
378+
367379
if pathsFailed:
368380
Print(" - Paths failover time: %s seconds" % failoverTime)
369381
Print(" - Maximum IO completion time: %s. Data: %s. Throughput: %s" % (maxTimeTaken, '1MB', throughputForMaxTime))
370382
displayOperationStatus(True)
371383
checkPoint += 1
372384
else:
373385
displayOperationStatus(False)
374-
self.BlockUnblockPaths(False, self.storage_conf['pathHandlerUtil'], self.noOfPaths, self.blockedpathinfo)
386+
if not isManBlock:
387+
self.BlockUnblockPaths(False, self.storage_conf['pathHandlerUtil'], self.noOfPaths, self.blockedpathinfo)
375388
raise Exception(" - Paths did not failover within expected time.")
376-
377-
self.BlockUnblockPaths(False, self.storage_conf['pathHandlerUtil'], self.noOfPaths, self.blockedpathinfo)
378-
Print(" -> Unblocking paths, waiting for restoration.")
389+
390+
if isManBlock:
391+
Print(" -> Wait for manually unblocking paths and restoration")
392+
self.WaitManualBlockUnblockPaths()
393+
else:
394+
self.BlockUnblockPaths(False, self.storage_conf['pathHandlerUtil'], self.noOfPaths, self.blockedpathinfo)
395+
Print(" -> Unblocking paths, waiting for restoration.")
396+
379397
count = 0
380398
pathsMatch = False
381399
while not pathsMatch and count < 120:
@@ -652,7 +670,19 @@ def BlockUnblockPaths(self, blockOrUnblock, script, noOfPaths, passthrough):
652670
raise Exception(" - The path block/unblock utility returned an error: %s." % stderr)
653671
return stdout
654672
except Exception, e:
655-
raise e
673+
raise e
674+
675+
def WaitManualBlockUnblockPaths(self):
676+
try:
677+
cmd = [self.storage_conf['pathHandlerUtil']]
678+
(rc, stdout, stderr) = util.doexec(cmd, '')
679+
XenCertPrint(
680+
"The path manually block/unblock utility returned rc: %s stdout: '%s', stderr: '%s'" % (rc, stdout, stderr))
681+
if rc != 0:
682+
raise Exception(" - The path manually block/unblock utility returned an error: %s." % stderr)
683+
return stdout
684+
except Exception, e:
685+
raise e
656686

657687
def __del__(self):
658688
XenCertPrint("Reached Storagehandler destructor")

src/XenCert/blockunblockhbapaths-brocade

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def blockUnblockPort(blockOrUnblock, ip, username, password, port):
4242
XenCertPrint("calling %s" % ' '.join(XenCertCommon.getCmdsWithHiddenPassword(cmd)))
4343
util.doexec(cmd, '')
4444
except Exception, e:
45-
util.SMlog("There was an exception in blocking port: %s" % port)
45+
util.SMlog("There was an exception in blocking port: %s, exception: %s" % (port, str(e)))
4646

4747
# Test Cmdline args
4848
if len(sys.argv) != 4:

src/XenCert/blockunblockhbapaths-cisco

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def blockUnblockPort(blockOrUnblock, ip, username, password, port):
4242
XenCertPrint("calling %s" % ' '.join(XenCertCommon.getCmdsWithHiddenPassword(cmd)))
4343
util.doexec(cmd, '')
4444
except Exception, e:
45-
util.SMlog("There was an exception in blocking port: %s" % port)
45+
util.SMlog("There was an exception in blocking port: %s, exception: %s" % (port, str(e)))
4646

4747
# Test Cmdline args
4848
if len(sys.argv) != 4:

src/XenCert/blockunblockhbapaths-qlogic

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def blockUnblockPort(blockOrUnblock, ip, username, password, port):
4242
XenCertPrint("calling %s" % ' '.join(XenCertCommon.getCmdsWithHiddenPassword(cmd)))
4343
util.doexec(cmd, '')
4444
except Exception, e:
45-
util.SMlog("There was an exception in blocking port: %s" % port)
45+
util.SMlog("There was an exception in blocking port: %s, exception: %s" % (port, str(e)))
4646

4747
# Test Cmdline args
4848
if len(sys.argv) != 4:

src/XenCert/blockunblockpaths

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,14 @@ if len(sys.argv) == 5:
4848
cmd = [sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]]
4949
XenCertPrint('blockunblockpaths - now call %s and wait for block/unblock to finish.' % cmd)
5050
(rc, stdout, stderr) = util.doexec(cmd, '')
51-
if rc == 0:
52-
retVal = stdout
53-
else:
54-
retVal = stderr
51+
retVal = stdout if rc == 0 else stderr
5552
elif len(sys.argv) == 1:
5653
XenCertPrint('blockunblockpaths - called without any arguments, just wait for block/unblock to finish.')
57-
54+
5855
while block_unblock_over != '1':
5956
time.sleep(1)
6057
block_unblock_over = xs_handle.read('', '/xencert/block-unblock-over')
61-
58+
6259
os.system('xenstore-rm /xencert')
6360
del xs_handle
6461
sys.stdout.write(retVal)

0 commit comments

Comments
 (0)