def test_vg_invalidate_lvs(tmp_storage): dev_size = 1 * GiB dev = tmp_storage.create_device(dev_size) vg_name = str(uuid.uuid4()) lvm.set_read_only(False) lvm.createVG(vg_name, [dev], "initial-tag", 128) lvm.createLV(vg_name, "lv1", 128, activate=False) # Reload cache. pv = lvm.getPV(dev) vg = lvm.getVG(vg_name) lv = lvm.getLV(vg_name)[0] assert lvm._lvminfo._pvs == {dev: pv} assert lvm._lvminfo._vgs == {vg_name: vg} assert lvm._lvminfo._lvs == {(vg_name, "lv1"): lv} # Invalidate VG including LVs. lvm.invalidateVG(vg_name) assert lvm._lvminfo._pvs == {dev: pv} assert lvm._lvminfo._vgs == {vg_name: lvm.Stale(vg_name)} assert lvm._lvminfo._lvs == {(vg_name, "lv1"): lvm.Stale("lv1")}
def test_lv_stale_reload_all_stale(stale_lv): vg_name, good_lv_name, stale_lv_name = stale_lv # Invalidate all lvs in single vg. lvm.invalidateVG(vg_name, invalidateLVs=True) # Only the good lv is reported. lvs = [lv.name for lv in lvm.getLV(vg_name)] assert lvs == [good_lv_name]
def test_pv_stale_reload_all_stale(stale_pv): vg_name, good_pv_name, stale_pv_name = stale_pv # Invalidate VG and its PVs. lvm.invalidateVG(vg_name, invalidatePVs=True) # Report only the good pv. pv_names = [pv.name for pv in lvm.getAllPVs()] assert pv_names == [good_pv_name]
def test_vg_stale_reload_all_stub(stale_vg): good_vg_name, stale_vg_name = stale_vg # Invalidate vgs. lvm.invalidateVG(good_vg_name) lvm.invalidateVG(stale_vg_name) # Report only the good vg. vgs = [vg.name for vg in lvm.getAllVGs()] assert vgs == [good_vg_name]
def test_pv_stale_reload_all_stale(stale_pv): vg_name, good_pv_name, stale_pv_name = stale_pv # Invalidate VG and its PVs. lvm.invalidateVG(vg_name, invalidatePVs=True) # Reloading all PVs will return them as Unreadable due to missing # stale PV. assert set(lvm.getAllPVs()) == { lvm.Unreadable(good_pv_name), lvm.Unreadable(stale_pv_name) }
def test_vg_invalidate(tmp_storage): dev_size = 1 * GiB dev1 = tmp_storage.create_device(dev_size) dev2 = tmp_storage.create_device(dev_size) vg1_name = str(uuid.uuid4()) vg2_name = str(uuid.uuid4()) lvm.set_read_only(False) lvm.createVG(vg1_name, [dev1], "initial-tag", 128) lvm.createLV(vg1_name, "lv1", 128, activate=False) lvm.createVG(vg2_name, [dev2], "initial-tag", 128) lvm.createLV(vg2_name, "lv2", 128, activate=False) # Reload cache. pv1 = lvm.getPV(dev1) vg1 = lvm.getVG(vg1_name) lv1 = lvm.getLV(vg1_name)[0] pv2 = lvm.getPV(dev2) vg2 = lvm.getVG(vg2_name) lv2 = lvm.getLV(vg2_name)[0] assert lvm._lvminfo._pvs == {dev1: pv1, dev2: pv2} assert lvm._lvminfo._vgs == {vg1_name: vg1, vg2_name: vg2} assert lvm._lvminfo._lvs == { (vg1_name, "lv1"): lv1, (vg2_name, "lv2"): lv2, } # Invalidate VG including LVs. lvm.invalidateVG(vg1_name, invalidateLVs=False) assert lvm._lvminfo._pvs == {dev1: pv1, dev2: pv2} assert lvm._lvminfo._vgs == { vg1_name: lvm.Stale(vg1_name), vg2_name: vg2, } assert lvm._lvminfo._lvs == { (vg1_name, "lv1"): lv1, (vg2_name, "lv2"): lv2, } # getVGs() always reloads the cache. clear_stats() lvm.getVGs([vg1_name, vg2_name]) check_stats(hits=0, misses=1) assert lvm._lvminfo._vgs == {vg1_name: vg1, vg2_name: vg2}
def test_pv_stale_reload_one_stale(stale_pv): vg_name, good_pv_name, stale_pv_name = stale_pv # Invalidate VG and its PVs. lvm.invalidateVG(vg_name, invalidatePVs=True) # The good pv is still in the cache. pv = lvm.getPV(good_pv_name) assert pv.name == good_pv_name # The stale pv shuld be removed. with pytest.raises(se.InaccessiblePhysDev): lvm.getPV(stale_pv_name)
def test_lv_stale_reload_one_stale(stale_lv): vg_name, good_lv_name, stale_lv_name = stale_lv # Invalidate all lvs in single vg. lvm.invalidateVG(vg_name, invalidateLVs=True) # The good lv is still in the cache. lv = lvm.getLV(vg_name, good_lv_name) assert lv.name == good_lv_name # The stale lv should be removed. with pytest.raises(se.LogicalVolumeDoesNotExistError): lvm.getLV(vg_name, stale_lv_name)
def test_pv_stale_reload_one_stale(stale_pv): vg_name, good_pv_name, stale_pv_name = stale_pv # Invalidate VG and its PVs. lvm.invalidateVG(vg_name, invalidatePVs=True) # The good pv is still in the cache. pv = lvm.getPV(good_pv_name) assert pv.name == good_pv_name # Reloading the stale pv marks it as Unreadable. pv = lvm.getPV(stale_pv_name) assert pv == lvm.Unreadable(stale_pv_name)
def test_vg_stale_reload_one_stale(stale_vg): good_vg_name, stale_vg_name = stale_vg # Invalidate vgs. lvm.invalidateVG(good_vg_name) lvm.invalidateVG(stale_vg_name) # The good vg is still in the cache. vg = lvm.getVG(good_vg_name) assert vg.name == good_vg_name # The stale vg was removed. with pytest.raises(se.VolumeGroupDoesNotExist): lvm.getVG(stale_vg_name)
def test_vg_stale_reload_all_stale(stale_vg): good_vg_name, stale_vg_name = stale_vg # Invalidate vgs. lvm.invalidateVG(good_vg_name) lvm.invalidateVG(stale_vg_name) clear_stats() # Report only the good vg. vgs = [vg.name for vg in lvm.getAllVGs()] assert vgs == [good_vg_name] check_stats(hits=0, misses=1) # Second call for getAllVGs() will add cache hit. lvm.getAllVGs() check_stats(hits=1, misses=1)
def getVolumeTag(sdUUID, volUUID, tagPrefix): tags = lvm.getLV(sdUUID, volUUID).tags if sc.TAG_VOL_UNINIT in tags: log.warning("Reloading uninitialized volume %s/%s", sdUUID, volUUID) lvm.invalidateVG(sdUUID) tags = lvm.getLV(sdUUID, volUUID).tags if sc.TAG_VOL_UNINIT in tags: log.error("Found uninitialized volume: %s/%s", sdUUID, volUUID) raise se.VolumeDoesNotExist("%s/%s" % (sdUUID, volUUID)) for tag in tags: if tag.startswith(tagPrefix): return tag[len(tagPrefix):] else: log.error("Missing tag %s in volume: %s/%s. tags: %s", tagPrefix, sdUUID, volUUID, tags) raise se.MissingTagOnLogicalVolume(volUUID, tagPrefix)
def test_vg_invalidate_lvs_pvs(tmp_storage): dev_size = 1 * GiB dev = tmp_storage.create_device(dev_size) vg_name = str(uuid.uuid4()) lvm.set_read_only(False) lvm.createVG(vg_name, [dev], "initial-tag", 128) lvm.createLV(vg_name, "lv1", 128, activate=False) # Reload cache. pv = lvm.getPV(dev) vg = lvm.getVG(vg_name) lv = lvm.getLV(vg_name)[0] assert lvm._lvminfo._pvs == {dev: pv} clear_stats() lvm._lvminfo.getPvs(vg_name) # getPVs() first finds the VG using getVG(), so there is a cache hit. # No stale PVs for the VG so getPVs() will have another cache hit. check_stats(hits=2, misses=0) assert lvm._lvminfo._vgs == {vg_name: vg} assert lvm._lvminfo._lvs == {(vg_name, "lv1"): lv} # Invalidate VG including LVs and PVs. lvm.invalidateVG(vg_name, invalidatePVs=True) assert lvm._lvminfo._vgs == {vg_name: lvm.Stale(vg_name)} assert lvm._lvminfo._pvs == {dev: lvm.Stale(dev)} clear_stats() lvm._lvminfo.getPvs(vg_name) # getPVs() will not find the invalidated VG in cache, so there is a miss. # There are stale PVs for the VG so getPVs() will have another cache miss. check_stats(hits=0, misses=2) assert lvm._lvminfo._lvs == {(vg_name, "lv1"): lvm.Stale("lv1")}
def test_vg_invalidate_lvs(tmp_storage): dev_size = 1 * GiB dev = tmp_storage.create_device(dev_size) vg_name = str(uuid.uuid4()) lvm.set_read_only(False) lvm.createVG(vg_name, [dev], "initial-tag", 128) lvm.createLV(vg_name, "lv1", 128, activate=False) # Reload cache. pv = lvm.getPV(dev) vg = lvm.getVG(vg_name) clear_stats() lv = lvm.getLV(vg_name)[0] check_stats(hits=0, misses=1) # Accessing LVs always access storage. # TODO: Use cache if VG did not change. lvm.getLV(vg_name) check_stats(hits=0, misses=2) assert lvm._lvminfo._pvs == {dev: pv} assert lvm._lvminfo._vgs == {vg_name: vg} assert lvm._lvminfo._lvs == {(vg_name, "lv1"): lv} # Invalidate VG including LVs. lvm.invalidateVG(vg_name) assert lvm._lvminfo._pvs == {dev: pv} assert lvm._lvminfo._vgs == {vg_name: lvm.Stale(vg_name)} assert lvm._lvminfo._lvs == {(vg_name, "lv1"): lvm.Stale("lv1")} # Accessing LVs always access storage. # TODO: Use cache if VG did not change. clear_stats() lvm.getLV(vg_name) check_stats(hits=0, misses=1)
def test_lv_extend_reduce(tmp_storage): dev_size = 20 * GiB dev = tmp_storage.create_device(dev_size) vg_name = str(uuid.uuid4()) lv_name = str(uuid.uuid4()) lvm.set_read_only(False) lvm.createVG(vg_name, [dev], "initial-tag", 128) lvm.createLV(vg_name, lv_name, 1024) lvm.extendLV(vg_name, lv_name, 2048) lv = lvm.getLV(vg_name, lv_name) assert int(lv.size) == 2 * GiB # Extending LV to same does nothing. lvm.extendLV(vg_name, lv_name, 2048) lvm.invalidateVG(vg_name) lv = lvm.getLV(vg_name, lv_name) assert int(lv.size) == 2 * GiB # Extending LV to smaller size does nothing. lvm.extendLV(vg_name, lv_name, 1024) lvm.invalidateVG(vg_name) lv = lvm.getLV(vg_name, lv_name) assert int(lv.size) == 2 * GiB # Reducing active LV requires force. lvm.reduceLV(vg_name, lv_name, 1024, force=True) lv = lvm.getLV(vg_name, lv_name) assert int(lv.size) == 1 * GiB