From dcffc71c2baf79b780ac73646b9c537da3db8c5e Mon Sep 17 00:00:00 2001 From: Guillaume Abrioux Date: Mon, 10 Feb 2025 16:29:04 +0000 Subject: [PATCH] ceph-volume: enhance BlockSysFs This refactores `BlockSysFs` to introduce `_get_sysfs_file_content()` for retrieving sysfs file contents in a cleaner and reusable way. It renames `self.sys_dev_block` to `self.sys_dev_block_dir` for clarity. I've added `_get_sysfs_file_content()` to centralize sysfs file reads. 3 new methodes are introduced: `blocks`, `logical_block_size`, and `size` properties for computing block device size in a structured manner. Signed-off-by: Guillaume Abrioux (cherry picked from commit 8d8f203caef526bb68a21498650d329d94ba5ea9) --- .../ceph_volume/tests/util/test_disk.py | 23 ++++++- src/ceph-volume/ceph_volume/util/disk.py | 60 +++++++++++++++++-- 2 files changed, 75 insertions(+), 8 deletions(-) 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 8c27ce402fbc4..8dbb51bd08b49 100644 --- a/src/ceph-volume/ceph_volume/tests/util/test_disk.py +++ b/src/ceph-volume/ceph_volume/tests/util/test_disk.py @@ -587,6 +587,9 @@ class TestBlockSysFs(TestCase): self.fs.create_file('/fake-area/bar2/holders/dm-0') self.fs.create_file('/fake-area/foo/holders/dm-1') self.fs.create_file('/fake-area/bar2/partition', contents='2') + self.fs.create_file('/fake-area/foo/size', contents='1024') + self.fs.create_file('/fake-area/foo/queue/logical_block_size', contents='512') + self.fs.create_file('/fake-area/foo/random-data', contents='some-random data\n') self.fs.create_dir('/sys/dev/block') self.fs.create_dir('/sys/block/foo') self.fs.create_symlink('/sys/dev/block/8:0', '/fake-area/foo') @@ -597,12 +600,28 @@ class TestBlockSysFs(TestCase): def test_init(self) -> None: b = disk.BlockSysFs('/dev/foo') assert b.path == '/dev/foo' - assert b.sys_dev_block == '/sys/dev/block' + assert b.sys_dev_block_dir == '/sys/dev/block' assert b.sys_block == '/sys/block' + def test_get_sysfs_file_content(self) -> None: + b = disk.BlockSysFs('/dev/foo') + assert b._get_sysfs_file_content('random-data') == 'some-random data' + + def test_blocks(self) -> None: + b = disk.BlockSysFs('/dev/foo') + assert b.blocks == 1024 + + def test_logical_block_size(self) -> None: + b = disk.BlockSysFs('/dev/foo') + assert b.logical_block_size == 512 + + def test_size(self) -> None: + b = disk.BlockSysFs('/dev/foo') + assert b.size == 524288 + def test_get_sys_dev_block_path(self) -> None: b = disk.BlockSysFs('/dev/foo') - assert b.get_sys_dev_block_path == '/sys/dev/block/8:0' + assert b.sys_dev_block_path == '/sys/dev/block/8:0' def test_is_partition_true(self) -> None: b = disk.BlockSysFs('/dev/bar2') diff --git a/src/ceph-volume/ceph_volume/util/disk.py b/src/ceph-volume/ceph_volume/util/disk.py index 47caaae6d31cc..2020a06c55cd6 100644 --- a/src/ceph-volume/ceph_volume/util/disk.py +++ b/src/ceph-volume/ceph_volume/util/disk.py @@ -1178,9 +1178,57 @@ class BlockSysFs: """ self.path: str = path self.name: str = os.path.basename(os.path.realpath(self.path)) - self.sys_dev_block: str = sys_dev_block + self.sys_dev_block_dir: str = sys_dev_block self.sys_block: str = sys_block + def _get_sysfs_file_content(self, path: str) -> str: + """ + Reads the content of a sysfs file. + + Args: + path (str): The relative path to the sysfs file. + + Returns: + str: The content of the file as a string, stripped of leading/trailing whitespace. + """ + content: str = '' + _path: str = os.path.join(self.sys_dev_block_path, path) + with open(_path, 'r') as f: + content = f.read().strip() + return content + + @property + def blocks(self) -> int: + """ + Retrieves the number of blocks of the block device. + + Returns: + int: The total number of blocks. + """ + result: str = self._get_sysfs_file_content('size') + return int(result) + + @property + def logical_block_size(self) -> int: + """ + Retrieves the logical block size of the block device. + + Returns: + int: The logical block size in bytes. + """ + result: str = self._get_sysfs_file_content('queue/logical_block_size') + return int(result) + + @property + def size(self) -> int: + """ + Calculates the total size of the block device in bytes. + + Returns: + int: The total size of the block device in bytes. + """ + return self.blocks * self.logical_block_size + @property def is_partition(self) -> bool: """ @@ -1189,7 +1237,7 @@ class BlockSysFs: Returns: bool: True if it is a partition, False otherwise. """ - path: str = os.path.join(self.get_sys_dev_block_path, 'partition') + path: str = os.path.join(self.sys_dev_block_path, 'partition') return os.path.exists(path) @property @@ -1201,13 +1249,13 @@ class BlockSysFs: List[str]: A list of holders (other devices) associated with this block device. """ result: List[str] = [] - path: str = os.path.join(self.get_sys_dev_block_path, 'holders') + path: str = os.path.join(self.sys_dev_block_path, 'holders') if os.path.exists(path): result = os.listdir(path) return result @property - def get_sys_dev_block_path(self) -> str: + def sys_dev_block_path(self) -> str: """ Gets the sysfs path for the current block device. @@ -1215,9 +1263,9 @@ class BlockSysFs: str: The sysfs path corresponding to this block device. """ sys_dev_block_path: str = '' - devices: List[str] = os.listdir(self.sys_dev_block) + devices: List[str] = os.listdir(self.sys_dev_block_dir) for device in devices: - path = os.path.join(self.sys_dev_block, device) + path = os.path.join(self.sys_dev_block_dir, device) if os.path.realpath(path).split('/')[-1:][0] == self.name: sys_dev_block_path = path return sys_dev_block_path -- 2.39.5