From 52ca4a61d5d69ccfadeef8408a4711c820b98959 Mon Sep 17 00:00:00 2001 From: Teoman ONAY Date: Tue, 3 Oct 2023 21:47:16 +0200 Subject: [PATCH] ceph-volume: fixes fallback to stat in is_device and is_partition os.stat (or lstat) cannot distinguish a block device from a partition. Fixes: https://tracker.ceph.com/issues/58812 Signed-off-by: Teoman ONAY --- .../ceph_volume/tests/util/test_device.py | 8 -------- .../ceph_volume/tests/util/test_disk.py | 5 +++++ src/ceph-volume/ceph_volume/util/disk.py | 20 ++++--------------- 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/src/ceph-volume/ceph_volume/tests/util/test_device.py b/src/ceph-volume/ceph_volume/tests/util/test_device.py index e2ea026286f91..69b57c21110ee 100644 --- a/src/ceph-volume/ceph_volume/tests/util/test_device.py +++ b/src/ceph-volume/ceph_volume/tests/util/test_device.py @@ -152,14 +152,6 @@ def test_disk_is_device(self, fake_call, device_info): disk = device.Device("/dev/sda") assert disk.is_device is True - @patch("ceph_volume.util.disk.has_bluestore_label", lambda x: False) - def test_is_partition(self, fake_call, device_info): - data = {"/dev/sda1": {"foo": "bar"}} - lsblk = {"TYPE": "part", "NAME": "sda1", "PKNAME": "sda"} - device_info(devices=data, lsblk=lsblk) - disk = device.Device("/dev/sda1") - assert disk.is_partition - @patch("ceph_volume.util.disk.has_bluestore_label", lambda x: False) def test_mpath_device_is_device(self, fake_call, device_info): data = {"/dev/foo": {"foo": "bar"}} diff --git a/src/ceph-volume/ceph_volume/tests/util/test_disk.py b/src/ceph-volume/ceph_volume/tests/util/test_disk.py index ce1f9466fd567..b287530dc17fc 100644 --- a/src/ceph-volume/ceph_volume/tests/util/test_disk.py +++ b/src/ceph-volume/ceph_volume/tests/util/test_disk.py @@ -33,6 +33,11 @@ def test_is_device_type_mpath(self): def test_is_device_type_part(self): assert not disk.is_device('/dev/foo1') + @patch('ceph_volume.util.disk.os.path.exists', MagicMock(return_value=True)) + @patch('ceph_volume.util.disk.get_partitions', MagicMock(return_value={"sda1": "sda"})) + def test_is_partition(self): + assert disk.is_partition('sda1') + class TestLsblkParser(object): diff --git a/src/ceph-volume/ceph_volume/util/disk.py b/src/ceph-volume/ceph_volume/util/disk.py index 8f1bf706934c3..04104936985a4 100644 --- a/src/ceph-volume/ceph_volume/util/disk.py +++ b/src/ceph-volume/ceph_volume/util/disk.py @@ -364,30 +364,18 @@ def is_device(dev): return TYPE in ['disk', 'mpath'] # fallback to stat - return _stat_is_device(os.lstat(dev).st_mode) + return _stat_is_device(os.lstat(dev).st_mode) and not is_partition(dev) -def is_partition(dev): +def is_partition(dev: str) -> bool: """ Boolean to determine if a given device is a partition, like /dev/sda1 """ if not os.path.exists(dev): return False - # use lsblk first, fall back to using stat - TYPE = lsblk(dev).get('TYPE') - if TYPE: - return TYPE == 'part' - - # fallback to stat - stat_obj = os.stat(dev) - if _stat_is_device(stat_obj.st_mode): - return False - major = os.major(stat_obj.st_rdev) - minor = os.minor(stat_obj.st_rdev) - if os.path.exists('/sys/dev/block/%d:%d/partition' % (major, minor)): - return True - return False + partitions = get_partitions() + return dev.split("/")[-1] in partitions def is_ceph_rbd(dev):