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