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
This commit is contained in:
Dirk Mueller 2014-01-17 16:45:32 +01:00
parent ae5ae5079e
commit 3764cecfc3
1 changed files with 35 additions and 6 deletions

View File

@ -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',