From 3764cecfc3b0a5b35634b15a4b049f433a8a22de Mon Sep 17 00:00:00 2001 From: Dirk Mueller Date: Fri, 17 Jan 2014 16:45:32 +0100 Subject: [PATCH] Deactivate LV before removing With certain versions of LVM2, removing an active LV can end up with Unable to deactivate open XXX libdevmapper exiting with 1 device(s) still suspended. which causes any lvm command afterwards to hang endlessly on trying to access the suspended volume. This seems to be caused by a race with udev, so lets be conservative and do the deactivation, then wait for udev and then finish the removal. Closes-Bug: #1270192 Change-Id: I4703133180567090878ea5047dd29d9f97ad85ab --- cinder/brick/local_dev/lvm.py | 41 ++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/cinder/brick/local_dev/lvm.py b/cinder/brick/local_dev/lvm.py index caccbb087..0c8c10f81 100644 --- a/cinder/brick/local_dev/lvm.py +++ b/cinder/brick/local_dev/lvm.py @@ -558,10 +558,41 @@ class LVM(executor.Executor): :param name: Name of LV to delete """ + + def run_udevadm_settle(): + self._execute('udevadm', 'settle', + root_helper=self._root_helper, run_as_root=True, + check_exit_code=False) + try: - self._execute('lvremove', - '-f', - '%s/%s' % (self.vg_name, name), + need_force_remove = False + # LV removal seems to be a race with udev in + # some cases (see LP #1270192), so we do it in several steps: + + # - Deactivate the LV/Snapshot, which triggers udev events + # - Wait for udev to finish its job with udevadmn settle + # - Remove the LV + + try: + self._execute('lvchange', '-y', '-an', + '%s/%s' % (self.vg_name, name), + root_helper=self._root_helper, run_as_root=True) + except putils.ProcessExecutionError as err: + mesg = (_('Error during lvchange -an: CMD: %(command)s, ' + 'RESPONSE: %(response)s') % + {'command': err.cmd, 'response': err.stderr}) + LOG.debug(mesg) + need_force_remove = True + + run_udevadm_settle() + + cmd = ['lvremove', ] + + # if deactivation failed, use the --force, lvm! + if need_force_remove: + cmd.append('-f') + cmd.append('%s/%s' % (self.vg_name, name)) + self._execute(*cmd, root_helper=self._root_helper, run_as_root=True) except putils.ProcessExecutionError as err: mesg = (_('Error reported running lvremove: CMD: %(command)s, ' @@ -570,9 +601,7 @@ class LVM(executor.Executor): LOG.debug(mesg) LOG.debug(_('Attempting udev settle and retry of lvremove...')) - self._execute('udevadm', 'settle', - root_helper=self._root_helper, - run_as_root=True) + run_udevadm_settle() self._execute('lvremove', '-f', -- 2.45.2