Change in vdsm[master]: hsm: Rescan multipath if device is missing when scanning dev...

nsoffer at redhat.com nsoffer at redhat.com
Wed Nov 6 01:05:39 UTC 2013


Nir Soffer has uploaded a new change for review.

Change subject: hsm: Rescan multipath if device is missing when scanning devices
......................................................................

hsm: Rescan multipath if device is missing when scanning devices

commit 15c7f74365cb5 introduced a regression where multipath rescan is
never performed if a device is found missing when scanning devices. This
can cause a host to become non-operational when extending a vg.

This patch fix the regression and adds the missing unittests, hopefully
preventing the next regression in this hard to verify code.

Change-Id: I00d5be2f73b644c194625e08654784e0aad64aee
Signed-off-by: Nir Soffer <nsoffer at redhat.com>
---
M tests/Makefile.am
A tests/hsmTests.py
M vdsm/storage/hsm.py
3 files changed, 109 insertions(+), 6 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/42/20942/1

diff --git a/tests/Makefile.am b/tests/Makefile.am
index cae93a5..229e0bc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -36,6 +36,7 @@
 	glusterTestData.py \
 	guestIFTests.py \
 	hooksTests.py \
+	hsmTests.py \
 	ipwrapperTests.py \
 	jsonRpcTests.py \
 	jsonRpcUtils.py \
diff --git a/tests/hsmTests.py b/tests/hsmTests.py
new file mode 100644
index 0000000..cf55abb
--- /dev/null
+++ b/tests/hsmTests.py
@@ -0,0 +1,101 @@
+#
+# Copyright 2013 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301  USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import os
+
+from testrunner import VdsmTestCase as TestCaseBase
+import monkeypatch
+from storage import hsm
+
+
+class StatelessHsm(hsm.HSM):
+    """
+    HSM has too many dependencies to create an object for testing. This
+    subclass has no dependencies and is goog enough for testing methods that do
+    not use object state.
+    """
+    def __init__(self):
+        pass
+
+
+class FakeExists(object):
+
+    def __init__(self, pathes):
+        self.pathes = set(pathes)
+
+    def __call__(self, path):
+        return path in self.pathes
+
+
+class FakeMultipath(object):
+
+    def __init__(self, pathes=()):
+        self.log = ''
+        self.pathes = set(pathes)
+
+    def rescan(self):
+        self.log += 'rescan;'
+        os.path.exists.pathes = self.pathes
+
+
+ at monkeypatch.MonkeyClass(hsm, 'multipath', FakeMultipath())
+class ScanDevicesVisibilityTests(TestCaseBase):
+
+    def testEmpty(self):
+        sh = StatelessHsm()
+        self.assertEquals(sh.scanDevicesVisibility([]), {})
+        self.assertEquals(hsm.multipath.log, '')
+
+    @monkeypatch.MonkeyPatch(os.path, 'exists', FakeExists(['/dev/mapper/a',
+                             '/dev/mapper/b', '/dev/mapper/c']))
+    def testAllVisible(self):
+        sh = StatelessHsm()
+        res = sh.scanDevicesVisibility(['a', 'b', 'c'])
+        self.assertEquals(res, {'a': True, 'b': True, 'c': True})
+        self.assertEquals(hsm.multipath.log, '')
+
+    @monkeypatch.MonkeyPatch(os.path, 'exists', FakeExists(['/dev/mapper/a',
+                             '/dev/mapper/b']))
+    @monkeypatch.MonkeyPatch(hsm, 'multipath', FakeMultipath(['/dev/mapper/a',
+                             '/dev/mapper/b']))
+    def testRescanIfMissing(self):
+        sh = StatelessHsm()
+        res = sh.scanDevicesVisibility(['a', 'b', 'c'])
+        self.assertEquals(res, {'a': True, 'b': True, 'c': False})
+        self.assertEquals(hsm.multipath.log, 'rescan;')
+
+    @monkeypatch.MonkeyPatch(os.path, 'exists', FakeExists(['/dev/mapper/a',
+                             '/dev/mapper/b']))
+    @monkeypatch.MonkeyPatch(hsm, 'multipath', FakeMultipath(['/dev/mapper/a',
+                             '/dev/mapper/b', '/dev/mapper/c']))
+    def testVisibleAfterRescan(self):
+        sh = StatelessHsm()
+        res = sh.scanDevicesVisibility(['a', 'b', 'c'])
+        self.assertEquals(res, {'a': True, 'b': True, 'c': True})
+
+    @monkeypatch.MonkeyPatch(os.path, 'exists', FakeExists(['/dev/mapper/a',
+                             '/dev/mapper/b']))
+    @monkeypatch.MonkeyPatch(hsm, 'multipath',
+                             FakeMultipath(['/dev/mapper/a']))
+    def testInvisibleAfterRescan(self):
+        sh = StatelessHsm()
+        res = sh.scanDevicesVisibility(['a', 'b', 'c'])
+        self.assertEquals(res, {'a': True, 'b': False, 'c': False})
diff --git a/vdsm/storage/hsm.py b/vdsm/storage/hsm.py
index 25340f5..1daae79 100644
--- a/vdsm/storage/hsm.py
+++ b/vdsm/storage/hsm.py
@@ -1983,13 +1983,14 @@
 
     @public
     def scanDevicesVisibility(self, guids):
-        visible = lambda guid: (guid, os.path.exists(
-                                os.path.join("/dev/mapper", guid)))
-        visibleDevs = map(visible, guids)
-        if not all(visibleDevs):
+        def visible(guid):
+            path = os.path.join("/dev/mapper", guid)
+            return os.path.exists(path)
+        visibility = map(visible, guids)
+        if not all(visibility):
             multipath.rescan()
-            visibleDevs = map(visible, guids)
-        return dict(visibleDevs)
+            visibility = map(visible, guids)
+        return dict(zip(guids, visibility))
 
     @public
     def getDevicesVisibility(self, guids, options=None):


-- 
To view, visit http://gerrit.ovirt.org/20942
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I00d5be2f73b644c194625e08654784e0aad64aee
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsoffer at redhat.com>


More information about the vdsm-patches mailing list