From 310fbb6467d31df5f40e216d4fdddebaeb76025f Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Fri, 27 Nov 2009 15:25:00 +0100 Subject: [PATCH] DRBD: ignore unreadable meta devices The DRBD driver can ignore dead disks but not dead meta devices (for which it refuses to configure the minor). To handle this case, we check that the meta device is readable and if not we ignore it (the same as when backend._RecursiveAssembleBD didn't find it). A needed change is the move of some checks and initialisers before this test (which is before the super().__init__ call), but that should be fine. Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Guido Trotter <ultrotter@google.com> --- lib/bdev.py | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/lib/bdev.py b/lib/bdev.py index 79913456e..86f27d12a 100644 --- a/lib/bdev.py +++ b/lib/bdev.py @@ -34,6 +34,10 @@ from ganeti import constants from ganeti import objects +# Size of reads in _CanReadDevice +_DEVICE_READ_SIZE = 128 * 1024 + + def _IgnoreError(fn, *args, **kwargs): """Executes the given function, ignoring BlockDeviceErrors. @@ -66,6 +70,20 @@ def _ThrowError(msg, *args): raise errors.BlockDeviceError(msg) +def _CanReadDevice(path): + """Check if we can read from the given device. + + This tries to read the first 128k of the device. + + """ + try: + utils.ReadFile(path, size=_DEVICE_READ_SIZE) + return True + except EnvironmentError, err: + logging.warning("Can't read from device %s", path, exc_info=True) + return False + + class BlockDev(object): """Block device abstract class. @@ -960,6 +978,17 @@ class DRBD8(BaseDRBD): def __init__(self, unique_id, children, size): if children and children.count(None) > 0: children = [] + if len(children) not in (0, 2): + raise ValueError("Invalid configuration data %s" % str(children)) + if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 6: + raise ValueError("Invalid configuration data %s" % str(unique_id)) + (self._lhost, self._lport, + self._rhost, self._rport, + self._aminor, self._secret) = unique_id + if children: + if not _CanReadDevice(children[1].dev_path): + logging.info("drbd%s: Ignoring unreadable meta device", self._aminor) + children = [] super(DRBD8, self).__init__(unique_id, children, size) self.major = self._DRBD_MAJOR version = self._GetVersion() @@ -968,13 +997,6 @@ class DRBD8(BaseDRBD): " usage: kernel is %s.%s, ganeti wants 8.x", version['k_major'], version['k_minor']) - if len(children) not in (0, 2): - raise ValueError("Invalid configuration data %s" % str(children)) - if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 6: - raise ValueError("Invalid configuration data %s" % str(unique_id)) - (self._lhost, self._lport, - self._rhost, self._rport, - self._aminor, self._secret) = unique_id if (self._lhost is not None and self._lhost == self._rhost and self._lport == self._rport): raise ValueError("Invalid configuration data, same local/remote %s" % -- GitLab