From f6eaed125db30ff5ccc96b1af10f9e42fe4364c1 Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Mon, 16 Feb 2009 12:17:18 +0000 Subject: [PATCH] Convert IOErrors for /proc/drbd into our errors If /proc/drbd can't be opened, this raises an IOError, but all the error-handling behaviour in backend treats only BlockDeviceErrors. This creates a plain failure in cluster verify and in other RPC calls. This patch simply converts EnvironmentErrors into BlockDeviceErrors, and also changes the RPC result for NV_DRBDLIST and its handling to be able to show the error. The other RPC calls work by default now, due the existing error handling. Reviewed-by: ultrotter --- lib/backend.py | 4 ++-- lib/bdev.py | 15 +++++++++++---- lib/cmdlib.py | 22 +++++++++++++--------- test/ganeti.bdev_unittest.py | 7 +++++++ 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/lib/backend.py b/lib/backend.py index b3e3f49e9..c1723004c 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -437,9 +437,9 @@ def VerifyNode(what, cluster_name): if constants.NV_DRBDLIST in what: try: used_minors = bdev.DRBD8.GetUsedDevs().keys() - except errors.BlockDeviceError: + except errors.BlockDeviceError, err: logging.warning("Can't get used minors list", exc_info=True) - used_minors = [] + used_minors = str(err) result[constants.NV_DRBDLIST] = used_minors return result diff --git a/lib/bdev.py b/lib/bdev.py index d68f39e2a..545cc0b57 100644 --- a/lib/bdev.py +++ b/lib/bdev.py @@ -639,11 +639,18 @@ class BaseDRBD(BlockDev): """Return data from /proc/drbd. """ - stat = open(filename, "r") try: - data = stat.read().splitlines() - finally: - stat.close() + stat = open(filename, "r") + try: + data = stat.read().splitlines() + finally: + stat.close() + except EnvironmentError, err: + if err.errno == errno.ENOENT: + _ThrowError("The file %s cannot be opened, check if the module" + " is loaded (%s)", filename, str(err)) + else: + _ThrowError("Can't read the DRBD proc file %s: %s", filename, str(err)) if not data: _ThrowError("Can't read any data from %s", filename) return data diff --git a/lib/cmdlib.py b/lib/cmdlib.py index 2bc0bae27..8347140b8 100644 --- a/lib/cmdlib.py +++ b/lib/cmdlib.py @@ -757,15 +757,19 @@ class LUVerifyCluster(LogicalUnit): # check used drbd list used_minors = node_result.get(constants.NV_DRBDLIST, []) - for minor, (iname, must_exist) in drbd_map.items(): - if minor not in used_minors and must_exist: - feedback_fn(" - ERROR: drbd minor %d of instance %s is not active" % - (minor, iname)) - bad = True - for minor in used_minors: - if minor not in drbd_map: - feedback_fn(" - ERROR: unallocated drbd minor %d is in use" % minor) - bad = True + if not isinstance(used_minors, (tuple, list)): + feedback_fn(" - ERROR: cannot parse drbd status file: %s" % + str(used_minors)) + else: + for minor, (iname, must_exist) in drbd_map.items(): + if minor not in used_minors and must_exist: + feedback_fn(" - ERROR: drbd minor %d of instance %s is not active" % + (minor, iname)) + bad = True + for minor in used_minors: + if minor not in drbd_map: + feedback_fn(" - ERROR: unallocated drbd minor %d is in use" % minor) + bad = True return bad diff --git a/test/ganeti.bdev_unittest.py b/test/ganeti.bdev_unittest.py index 6b7176895..2db785c7d 100755 --- a/test/ganeti.bdev_unittest.py +++ b/test/ganeti.bdev_unittest.py @@ -106,6 +106,13 @@ class TestDRBD8Status(testutils.GanetiTestCase): self.proc_data = bdev.DRBD8._GetProcData(filename=proc_data) self.mass_data = bdev.DRBD8._MassageProcData(self.proc_data) + def testIOErrors(self): + """Test handling of errors while reading the proc file.""" + temp_file = self._CreateTempFile() + os.unlink(temp_file) + self.failUnlessRaises(errors.BlockDeviceError, + bdev.DRBD8._GetProcData, filename=temp_file) + def testMinorNotFound(self): """Test not-found-minor in /proc""" self.failUnless(9 not in self.mass_data) -- GitLab