diff --git a/tests/lvm_test.py b/tests/lvm_test.py index 7b3f9985a..9c5f83ef3 100644 --- a/tests/lvm_test.py +++ b/tests/lvm_test.py @@ -332,6 +332,7 @@ def setUp(self): self.addCleanup(self._clean_up) self.dev_file = create_sparse_tempfile("lvm_test", self._sparse_size) self.dev_file2 = create_sparse_tempfile("lvm_test", self._sparse_size) + self.dev_file3 = create_sparse_tempfile("lvm_test", self._sparse_size) try: self.loop_dev = create_lio_device(self.dev_file) except RuntimeError as e: @@ -340,6 +341,10 @@ def setUp(self): self.loop_dev2 = create_lio_device(self.dev_file2) except RuntimeError as e: raise RuntimeError("Failed to setup loop device for testing: %s" % e) + try: + self.loop_dev3 = create_lio_device(self.dev_file3) + except RuntimeError as e: + raise RuntimeError("Failed to setup loop device for testing: %s" % e) def _clean_up(self): try: @@ -352,6 +357,11 @@ def _clean_up(self): except: pass + try: + BlockDev.lvm_pvremove(self.loop_dev3, None) + except: + pass + try: delete_lio_device(self.loop_dev) except RuntimeError: @@ -366,6 +376,13 @@ def _clean_up(self): pass os.unlink(self.dev_file2) + try: + delete_lio_device(self.loop_dev3) + except RuntimeError: + # just move on, we can do no better here + pass + os.unlink(self.dev_file3) + class LvmTestPVcreateRemove(LvmPVonlyTestCase): @tag_test(TestTags.CORE) def test_pvcreate_and_pvremove(self): @@ -775,6 +792,79 @@ def test_lvcreate_lvremove(self): with self.assertRaises(GLib.GError): BlockDev.lvm_lvremove("testVG", "testLV", True, None) +class LvmTestPartialLVs(LvmPVVGLVTestCase): + @tag_test(TestTags.CORE) + def test_lvpartial(self): + """Verify that missing PVs are detected and can be dealt with""" + + succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None) + self.assertTrue(succ) + + succ = BlockDev.lvm_pvcreate(self.loop_dev2, 0, 0, None) + self.assertTrue(succ) + + succ = BlockDev.lvm_pvcreate(self.loop_dev3, 0, 0, None) + self.assertTrue(succ) + + succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev, self.loop_dev2, self.loop_dev3], 0, None) + self.assertTrue(succ) + + info = BlockDev.lvm_pvinfo(self.loop_dev2) + self.assertTrue(info) + self.assertFalse(info.missing) + self.assertEqual(info.vg_name, "testVG") + loop_dev2_pv_uuid = info.pv_uuid + + # Create a mirrored LV on the first two PVs + succ = BlockDev.lvm_lvcreate("testVG", "testLV", 512 * 1024**2, "raid1", [self.loop_dev, self.loop_dev2], None) + self.assertTrue(succ) + + info = BlockDev.lvm_lvinfo("testVG", "testLV") + self.assertTrue(info) + self.assertEqual(info.health_status, "") + + # Disconnect the second PV, this should cause it to be flagged + # as missing, and testLV to be reported as "partial". + # + # XXX - actually, shouldn't it be reported as "degraded"? + # + delete_lio_device(self.loop_dev2) + + pvs = BlockDev.lvm_pvs() + found = False + for pv in pvs: + if pv.pv_uuid == loop_dev2_pv_uuid: + found = True + self.assertTrue(pv.missing) + self.assertEqual(pv.vg_name, "testVG") + self.assertTrue(found) + + info = BlockDev.lvm_lvinfo("testVG", "testLV") + self.assertTrue(info) + self.assertEqual(info.health_status, "partial") + + # repair testLV with the third PV + with wait_for_sync("testVG", "testLV"): + succ = BlockDev.lvm_lvrepair("testVG", "testLV", [self.loop_dev3]) + self.assertTrue(succ) + + info = BlockDev.lvm_lvinfo("testVG", "testLV") + self.assertTrue(info) + self.assertEqual(info.health_status, "") + self.assertEqual(info.sync_percent, 100) + + # remove records of missing PVs + succ = BlockDev.lvm_vgreduce("testVG", None, None) + self.assertTrue(succ) + + pvs = BlockDev.lvm_pvs() + found = False + for pv in pvs: + if pv.pv_uuid == loop_dev2_pv_uuid: + found = True + self.assertFalse(found) + + class LvmTestLVcreateWithExtra(LvmPVVGLVTestCase): def __init__(self, *args, **kwargs): LvmPVVGLVTestCase.__init__(self, *args, **kwargs) @@ -884,6 +974,9 @@ def test_lvcreate_type(self): info = BlockDev.lvm_lvinfo("testVG", "testLV") self.assertEqual(info.segtype, "raid1") + # it should be fully synched + self.assertEqual(info.sync_percent, 100) + succ = BlockDev.lvm_lvremove("testVG", "testLV", True, None) self.assertTrue(succ)