mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
dbus: Add function for running lconvert --repair on RAID LVs
This commit is contained in:
parent
9259892627
commit
c77f2697ee
@ -552,6 +552,14 @@ def lv_vdo_deduplication(lv_path, enable, dedup_options):
|
|||||||
return call(cmd)
|
return call(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
def lv_raid_repair(lv_path, new_pvs, repair_options):
|
||||||
|
cmd = ['lvconvert', '-y', '--repair']
|
||||||
|
cmd.append(lv_path)
|
||||||
|
cmd.extend(new_pvs)
|
||||||
|
cmd.extend(options_to_cli_args(repair_options))
|
||||||
|
return call(cmd)
|
||||||
|
|
||||||
|
|
||||||
def supports_json():
|
def supports_json():
|
||||||
cmd = ['help']
|
cmd = ['help']
|
||||||
rc, out, err = call(cmd)
|
rc, out, err = call(cmd)
|
||||||
|
@ -795,6 +795,39 @@ class Lv(LvCommon):
|
|||||||
cache_options), cb, cbe)
|
cache_options), cb, cbe)
|
||||||
cfg.worker_q.put(r)
|
cfg.worker_q.put(r)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _repair_raid_lv(lv_uuid, lv_name, new_pvs, repair_options):
|
||||||
|
# Make sure we have a dbus object representing it
|
||||||
|
pv_dests = []
|
||||||
|
dbo = LvCommon.validate_dbus_object(lv_uuid, lv_name)
|
||||||
|
|
||||||
|
# If we have PVs, verify them
|
||||||
|
if len(new_pvs):
|
||||||
|
for pv in new_pvs:
|
||||||
|
pv_dbus_obj = cfg.om.get_object_by_path(pv)
|
||||||
|
if not pv_dbus_obj:
|
||||||
|
raise dbus.exceptions.DBusException(
|
||||||
|
LV_INTERFACE,
|
||||||
|
'PV Destination (%s) not found' % pv)
|
||||||
|
|
||||||
|
pv_dests.append(pv_dbus_obj.lvm_id)
|
||||||
|
|
||||||
|
LvCommon.handle_execute(*cmdhandler.lv_raid_repair(
|
||||||
|
dbo.lvm_id, pv_dests, repair_options))
|
||||||
|
return "/"
|
||||||
|
|
||||||
|
@dbus.service.method(
|
||||||
|
dbus_interface=LV_INTERFACE,
|
||||||
|
in_signature='aoia{sv}',
|
||||||
|
out_signature='o',
|
||||||
|
async_callbacks=('cb', 'cbe'))
|
||||||
|
def RepairRaidLv(self, new_pvs, tmo, repair_options, cb, cbe):
|
||||||
|
r = RequestEntry(
|
||||||
|
tmo, Lv._repair_raid_lv,
|
||||||
|
(self.Uuid, self.lvm_id, new_pvs,
|
||||||
|
repair_options), cb, cbe, return_tuple=False)
|
||||||
|
cfg.worker_q.put(r)
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyPep8Naming
|
# noinspection PyPep8Naming
|
||||||
@utils.dbus_property(VDO_POOL_INTERFACE, 'OperatingMode', 's')
|
@utils.dbus_property(VDO_POOL_INTERFACE, 'OperatingMode', 's')
|
||||||
|
@ -577,9 +577,13 @@ class TestDbusService(unittest.TestCase):
|
|||||||
vg.Remove(dbus.Int32(g_tmo), EOD))
|
vg.Remove(dbus.Int32(g_tmo), EOD))
|
||||||
self._check_consistency()
|
self._check_consistency()
|
||||||
|
|
||||||
def _pv_remove(self, pv):
|
def _pv_remove(self, pv, force=False):
|
||||||
|
if force:
|
||||||
|
options = dbus.Dictionary({'--force': '--force', '--yes': ''}, 'sv')
|
||||||
|
else:
|
||||||
|
options = EOD
|
||||||
rc = self.handle_return(
|
rc = self.handle_return(
|
||||||
pv.Pv.Remove(dbus.Int32(g_tmo), EOD))
|
pv.Pv.Remove(dbus.Int32(g_tmo), options))
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
def test_pv_remove_add(self):
|
def test_pv_remove_add(self):
|
||||||
@ -2262,6 +2266,60 @@ class TestDbusService(unittest.TestCase):
|
|||||||
|
|
||||||
self.handle_return(vg.Vg.Remove(dbus.Int32(g_tmo), EOD))
|
self.handle_return(vg.Vg.Remove(dbus.Int32(g_tmo), EOD))
|
||||||
|
|
||||||
|
def test_lv_raid_repair(self):
|
||||||
|
if len(self.objs[PV_INT]) < 3:
|
||||||
|
self.skipTest("we need at least 3 PVs to run LV repair test")
|
||||||
|
|
||||||
|
lv_name = lv_n()
|
||||||
|
vg = self._vg_create(pv_paths=[self.objs[PV_INT][0].object_path,
|
||||||
|
self.objs[PV_INT][1].object_path]).Vg
|
||||||
|
lv = self._test_lv_create(
|
||||||
|
vg.LvCreateRaid,
|
||||||
|
(dbus.String(lv_name), dbus.String('raid1'), dbus.UInt64(mib(16)),
|
||||||
|
dbus.UInt32(0), dbus.UInt32(0), dbus.Int32(g_tmo), EOD),
|
||||||
|
vg, LV_BASE_INT)
|
||||||
|
|
||||||
|
# deactivate the RAID LV (can't force remove PV with active LVs)
|
||||||
|
self.handle_return(lv.Lv.Deactivate(
|
||||||
|
dbus.UInt64(0), dbus.Int32(g_tmo), EOD))
|
||||||
|
lv.update()
|
||||||
|
self.assertFalse(lv.LvCommon.Active)
|
||||||
|
|
||||||
|
# remove second PV using --force --force
|
||||||
|
self._pv_remove(self.objs[PV_INT][1], force=True)
|
||||||
|
|
||||||
|
# activate the RAID LV (can't repair inactive LVs)
|
||||||
|
self.handle_return(lv.Lv.Activate(
|
||||||
|
dbus.UInt64(0), dbus.Int32(g_tmo), EOD))
|
||||||
|
lv.update()
|
||||||
|
self.assertTrue(lv.LvCommon.Active)
|
||||||
|
|
||||||
|
# LV should be "broken" now
|
||||||
|
self.assertEqual(lv.LvCommon.Health[1], "partial")
|
||||||
|
|
||||||
|
# add the third PV to the VG
|
||||||
|
path = self.handle_return(vg.Extend(
|
||||||
|
dbus.Array([self.objs[PV_INT][2].object_path], signature="o"),
|
||||||
|
dbus.Int32(g_tmo), EOD))
|
||||||
|
self.assertTrue(path == '/')
|
||||||
|
|
||||||
|
# repair the RAID LV using the third PV
|
||||||
|
rc = self.handle_return(
|
||||||
|
lv.Lv.RepairRaidLv(
|
||||||
|
dbus.Array([self.objs[PV_INT][2].object_path], 'o'),
|
||||||
|
dbus.Int32(g_tmo), EOD))
|
||||||
|
|
||||||
|
self.assertEqual(rc, '/')
|
||||||
|
self._check_consistency()
|
||||||
|
|
||||||
|
lv.update()
|
||||||
|
|
||||||
|
self.assertEqual(lv.LvCommon.Health[1], "unspecified")
|
||||||
|
|
||||||
|
# cleanup: remove the wiped PV from the VG and re-create it to have a clean PV
|
||||||
|
call_lvm(["vgreduce", "--removemissing", vg.Name])
|
||||||
|
self._pv_create(self.objs[PV_INT][1].Pv.Name)
|
||||||
|
|
||||||
def _test_lv_method_interface(self, lv):
|
def _test_lv_method_interface(self, lv):
|
||||||
self._rename_lv_test(lv)
|
self._rename_lv_test(lv)
|
||||||
self._test_activate_deactivate(lv)
|
self._test_activate_deactivate(lv)
|
||||||
|
Loading…
Reference in New Issue
Block a user