diff --git a/lib/vdsm/osinfo.py b/lib/vdsm/osinfo.py index be404f575..fb158fb31 100644 --- a/lib/vdsm/osinfo.py +++ b/lib/vdsm/osinfo.py @@ -248,6 +248,7 @@ def package_versions(): 'qemu-kvm': ('qemu-kvm', 'qemu-kvm-rhev', 'qemu-kvm-ev'), 'spice-server': ('spice-server',), 'vdsm': ('vdsm',), + 'lvm2': ('lvm2', 'lvm2-libs'), } if glusterEnabled: @@ -281,6 +282,7 @@ def package_versions(): 'qemu-kvm': 'qemu-kvm', 'spice-server': 'libspice-server1', 'vdsm': 'vdsmd', + 'lvm2': 'lvm2', } if glusterEnabled: diff --git a/lib/vdsm/storage/lvm.py b/lib/vdsm/storage/lvm.py index 38d212c58..53e100022 100644 --- a/lib/vdsm/storage/lvm.py +++ b/lib/vdsm/storage/lvm.py @@ -22,6 +22,7 @@ from itertools import chain from vdsm import constants +from vdsm import osinfo from vdsm import utils from vdsm.common import commands from vdsm.common import errors @@ -240,6 +241,15 @@ def __getattr__(self, attrName): USE_DEVICES = config.get("lvm", "config_method").lower() == "devices" +def _get_lvm_version(): + packages = osinfo.package_versions() + lvm_version = tuple( + int(v) + for v in packages['lvm2']['version'].split('.') + ) + return lvm_version + + def _prepare_device_set(devs): devices = set(d.strip() for d in chain(devs, USER_DEV_LIST)) devices.discard('') @@ -1781,11 +1791,14 @@ def extendLV(vgName, lvName, size_mb, refresh=True): def reduceLV(vgName, lvName, size_mb, force=False): + lvm_version = _get_lvm_version() log.info("Reducing LV %s/%s to %s megabytes (force=%s)", vgName, lvName, size_mb, force) cmd = ("lvreduce",) + LVM_NOBACKUP if force: cmd += ("--force",) + if lvm_version >= (2, 3, 17): + cmd += ("--fs", "ignore") cmd += ("--size", "%sm" % (size_mb,), "%s/%s" % (vgName, lvName)) try: diff --git a/tests/storage/lvm_test.py b/tests/storage/lvm_test.py index fb25ab00f..d580d190d 100644 --- a/tests/storage/lvm_test.py +++ b/tests/storage/lvm_test.py @@ -9,6 +9,7 @@ import uuid import pytest +from unittest import mock from vdsm.common import commands from vdsm.common import concurrent @@ -1776,6 +1777,27 @@ def test_lv_extend_reduce(tmp_storage): assert int(lv.size) == 1 * GiB +@pytest.mark.parametrize("lvm_version, expected_cmd", [ + ((2, 3, 16), ("lvreduce", "--autobackup", "n", "--size", + "100m", "vg/lv")), + ((2, 3, 17), ("lvreduce", "--autobackup", "n", "--fs", "ignore", "--size", + "100m", "vg/lv")) +]) +def test_reducelv_with_different_lvm_versions(lvm_version, expected_cmd): + with mock.patch.object(lvm, "_get_lvm_version", + return_value=lvm_version), \ + mock.patch.object(lvm._lvminfo, + "run_command") as mock_run_command, \ + mock.patch.object(lvm._lvminfo, "_invalidatevgs"), \ + mock.patch.object(lvm._lvminfo, "_invalidatelvs"): + + lvm.reduceLV("vg", "lv", 100) + + mock_run_command.assert_called_once_with( + expected_cmd, devices=mock.ANY + ) + + @requires_root @pytest.mark.root def test_lv_extend_with_refresh(tmp_storage):