summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-04-08 20:27:27 +0000
committerGerrit Code Review <review@openstack.org>2015-04-08 20:27:27 +0000
commitf07713139394758f0734055b5a3389a8a13538cf (patch)
tree11e76e481e7a485519bde87f4e10f836876740ab
parentbc86661c33fd7aab3ceb62a2a81608a8cf5296d2 (diff)
parent2fe4de571e925e26c77bffbda908f16e375b8a83 (diff)
downloadcinder-f07713139394758f0734055b5a3389a8a13538cf.tar.gz
Merge "Fix multipath device discovery when UFN is enabled."
-rw-r--r--cinder/brick/initiator/linuxscsi.py37
-rw-r--r--cinder/tests/brick/test_brick_linuxscsi.py38
2 files changed, 55 insertions, 20 deletions
diff --git a/cinder/brick/initiator/linuxscsi.py b/cinder/brick/initiator/linuxscsi.py
index aa1272c08..f702df7d8 100644
--- a/cinder/brick/initiator/linuxscsi.py
+++ b/cinder/brick/initiator/linuxscsi.py
@@ -30,6 +30,7 @@ from cinder.openstack.common import loopingcall
LOG = logging.getLogger(__name__)
MULTIPATH_ERROR_REGEX = re.compile("\w{3} \d+ \d\d:\d\d:\d\d \|.*$")
+MULTIPATH_WWID_REGEX = re.compile("\((?P<wwid>.+)\)")
class LinuxSCSI(executor.Executor):
@@ -182,21 +183,26 @@ class LinuxSCSI(executor.Executor):
lines = [line for line in lines
if not re.match(MULTIPATH_ERROR_REGEX, line)]
if lines:
- line = lines[0]
- info = line.split(" ")
- # device line output is different depending
- # on /etc/multipath.conf settings.
- if info[1][:2] == "dm":
- mdev = "/dev/%s" % info[1]
- mdev_id = info[0]
- elif info[2][:2] == "dm":
- mdev = "/dev/%s" % info[2]
- mdev_id = info[1].replace('(', '')
- mdev_id = mdev_id.replace(')', '')
-
- if mdev is None:
- LOG.warn(_LW("Couldn't find multipath device %(line)s")
- % {'line': line})
+
+ # Use the device name, be it the WWID, mpathN or custom alias
+ # of a device to build the device path. This should be the
+ # first item on the first line of output from `multipath -l
+ # ${path}` or `multipath -l ${wwid}`..
+ mdev_name = lines[0].split(" ")[0]
+ mdev = '/dev/mapper/%s' % mdev_name
+
+ # Find the WWID for the LUN if we are using mpathN or aliases.
+ wwid_search = MULTIPATH_WWID_REGEX.search(lines[0])
+ if wwid_search is not None:
+ mdev_id = wwid_search.group('wwid')
+ else:
+ mdev_id = mdev_name
+
+ # Confirm that the device is present.
+ try:
+ os.stat(mdev)
+ except OSError:
+ LOG.warn(_LW("Couldn't find multipath device %s"), mdev)
return None
LOG.debug("Found multipath device = %(mdev)s"
@@ -220,6 +226,7 @@ class LinuxSCSI(executor.Executor):
if mdev is not None:
info = {"device": mdev,
"id": mdev_id,
+ "name": mdev_name,
"devices": devices}
return info
return None
diff --git a/cinder/tests/brick/test_brick_linuxscsi.py b/cinder/tests/brick/test_brick_linuxscsi.py
index cac64b2e8..0b3e35bac 100644
--- a/cinder/tests/brick/test_brick_linuxscsi.py
+++ b/cinder/tests/brick/test_brick_linuxscsi.py
@@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import os
import os.path
import string
@@ -30,11 +31,15 @@ class LinuxSCSITestCase(test.TestCase):
self.cmds = []
self.stubs.Set(os.path, 'realpath', lambda x: '/dev/sdc')
self.linuxscsi = linuxscsi.LinuxSCSI(None, execute=self.fake_execute)
+ self.fake_stat_result = os.stat(__file__)
def fake_execute(self, *cmd, **kwargs):
self.cmds.append(string.join(cmd))
return "", None
+ def fake_stat(self, path):
+ return self.fake_stat_result
+
def test_echo_scsi_command(self):
self.linuxscsi.echo_scsi_command("/some/path", "1")
expected_commands = ['tee -a /some/path']
@@ -110,7 +115,7 @@ class LinuxSCSITestCase(test.TestCase):
('multipath -f 350002ac20398383d'), ]
self.assertEqual(expected_commands, self.cmds)
- def test_find_multipath_device_3par(self):
+ def test_find_multipath_device_3par_ufn(self):
def fake_execute(*cmd, **kwargs):
out = ("mpath6 (350002ac20398383d) dm-3 3PARdata,VV\n"
"size=2.0G features='0' hwhandler='0' wp=rw\n"
@@ -121,10 +126,15 @@ class LinuxSCSITestCase(test.TestCase):
return out, None
self.stubs.Set(self.linuxscsi, '_execute', fake_execute)
+ self.stubs.SmartSet(os, 'stat', self.fake_stat)
info = self.linuxscsi.find_multipath_device('/dev/sde')
LOG.error("info = %s" % info)
- self.assertEqual("/dev/dm-3", info["device"])
+
+ self.assertEqual("350002ac20398383d", info['id'])
+ self.assertEqual("mpath6", info['name'])
+ self.assertEqual("/dev/mapper/mpath6", info['device'])
+
self.assertEqual("/dev/sde", info['devices'][0]['device'])
self.assertEqual("0", info['devices'][0]['host'])
self.assertEqual("0", info['devices'][0]['id'])
@@ -152,10 +162,16 @@ class LinuxSCSITestCase(test.TestCase):
return out, None
self.stubs.Set(self.linuxscsi, '_execute', fake_execute)
+ self.stubs.SmartSet(os, 'stat', self.fake_stat)
info = self.linuxscsi.find_multipath_device('/dev/sde')
LOG.error("info = %s" % info)
- self.assertEqual("/dev/dm-2", info["device"])
+
+ self.assertEqual("36005076da00638089c000000000004d5", info["id"])
+ self.assertEqual("36005076da00638089c000000000004d5", info["name"])
+ self.assertEqual("/dev/mapper/36005076da00638089c000000000004d5",
+ info["device"])
+
self.assertEqual("/dev/sde", info['devices'][0]['device'])
self.assertEqual("6", info['devices'][0]['host'])
self.assertEqual("0", info['devices'][0]['channel'])
@@ -180,10 +196,16 @@ class LinuxSCSITestCase(test.TestCase):
return out, None
self.stubs.Set(self.linuxscsi, '_execute', fake_execute)
+ self.stubs.SmartSet(os, 'stat', self.fake_stat)
info = self.linuxscsi.find_multipath_device('/dev/sdd')
LOG.error("info = %s" % info)
- self.assertEqual("/dev/dm-2", info["device"])
+
+ self.assertEqual("36005076303ffc48e0000000000000101", info["id"])
+ self.assertEqual("36005076303ffc48e0000000000000101", info["name"])
+ self.assertEqual("/dev/mapper/36005076303ffc48e0000000000000101",
+ info["device"])
+
self.assertEqual("/dev/sdd", info['devices'][0]['device'])
self.assertEqual("6", info['devices'][0]['host'])
self.assertEqual("0", info['devices'][0]['channel'])
@@ -209,10 +231,16 @@ class LinuxSCSITestCase(test.TestCase):
return out, None
self.stubs.Set(self.linuxscsi, '_execute', fake_execute)
+ self.stubs.SmartSet(os, 'stat', self.fake_stat)
info = self.linuxscsi.find_multipath_device('/dev/sdd')
LOG.error("info = %s" % info)
- self.assertEqual("/dev/dm-2", info["device"])
+
+ self.assertEqual("36005076303ffc48e0000000000000101", info["id"])
+ self.assertEqual("36005076303ffc48e0000000000000101", info["name"])
+ self.assertEqual("/dev/mapper/36005076303ffc48e0000000000000101",
+ info["device"])
+
self.assertEqual("/dev/sdd", info['devices'][0]['device'])
self.assertEqual("6", info['devices'][0]['host'])
self.assertEqual("0", info['devices'][0]['channel'])