]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-volume: support symlinks as devices
authorJan Sobczak <jsobczak@cloudferro.com>
Fri, 20 Nov 2020 13:33:13 +0000 (14:33 +0100)
committerGuillaume Abrioux <gabrioux@redhat.com>
Tue, 2 Aug 2022 09:18:24 +0000 (11:18 +0200)
This makes ceph-volume support passing symlinks as devices.

Fixes: https://tracker.ceph.com/issues/49103
Signed-off-by: Guillaume Abrioux <gabrioux@redhat.com>
(cherry picked from commit 9ddc5b77372cd2e0d5badd433c93d147cb25c6ee)

src/ceph-volume/ceph_volume/devices/lvm/batch.py
src/ceph-volume/ceph_volume/tests/conftest.py
src/ceph-volume/ceph_volume/tests/util/test_device.py
src/ceph-volume/ceph_volume/util/device.py

index afeab60971aa6407bce0a21c6cd20efcddbf1765..90c4c22c407aadf5289d7172ed5b423cdb9938e1 100644 (file)
@@ -73,7 +73,8 @@ def get_physical_osds(devices, args):
                                      abs_size,
                                      args.osds_per_device,
                                      osd_id,
-                                     'dmcrypt' if args.dmcrypt else None))
+                                     'dmcrypt' if args.dmcrypt else None,
+                                     dev.symlink))
     return ret
 
 
@@ -568,7 +569,8 @@ class Batch(object):
                      abs_size,
                      slots,
                      id_,
-                     encryption):
+                     encryption,
+                     symlink=None):
             self.id_ = id_
             self.data = self.VolSpec(path=data_path,
                                 rel_size=rel_size,
@@ -578,6 +580,7 @@ class Batch(object):
             self.fast = None
             self.very_fast = None
             self.encryption = encryption
+            self.symlink = symlink
 
         def add_fast_device(self, path, rel_size, abs_size, slots, type_):
             self.fast = self.VolSpec(path=path,
@@ -629,9 +632,12 @@ class Batch(object):
             if self.encryption:
                 report += templates.osd_encryption.format(
                     enc=self.encryption)
+            path = self.data.path
+            if self.symlink:
+                path = f'{self.symlink} -> {self.data.path}'
             report += templates.osd_component.format(
                 _type=self.data.type_,
-                path=self.data.path,
+                path=path,
                 size=self.data.abs_size,
                 percent=self.data.rel_size)
             if self.fast:
index bfa1159b8d3a1932194bf0b08287619a1f5fb2ee..80d291a2cdb54fb93eaf6f4dbac46e2a21edeaab 100644 (file)
@@ -63,6 +63,7 @@ def mock_device():
     dev.path = '/dev/foo'
     dev.vg_name = 'vg_foo'
     dev.lv_name = 'lv_foo'
+    dev.symlink = None
     dev.vgs = [lvm.VolumeGroup(vg_name=dev.vg_name, lv_name=dev.lv_name)]
     dev.available_lvm = True
     dev.vg_size = [21474836480]
index 5c87294ddf516874a2cd64af84a93c0cde98b875..91130d34df0d7063c83adcb40ca838a7dde64107 100644 (file)
@@ -249,6 +249,41 @@ class TestDevice(object):
         disk = device.Device("/dev/dm-0")
         assert not disk.available
 
+    @patch("ceph_volume.util.disk.has_bluestore_label", lambda x: False)
+    @patch('ceph_volume.util.device.os.path.realpath')
+    @patch('ceph_volume.util.device.os.path.islink')
+    def test_accept_symlink_to_device(self,
+                                      m_os_path_islink,
+                                      m_os_path_realpath,
+                                      device_info,
+                                      fake_call):
+        m_os_path_islink.return_value = True
+        m_os_path_realpath.return_value = '/dev/sdb'
+        data = {"/dev/sdb": {"ro": 0, "size": 5368709120}}
+        lsblk = {"TYPE": "disk"}
+        device_info(devices=data,lsblk=lsblk)
+        disk = device.Device("/dev/test_symlink")
+        print(disk)
+        print(disk.sys_api)
+        assert disk.available
+
+    @patch("ceph_volume.util.disk.has_bluestore_label", lambda x: False)
+    @patch('ceph_volume.util.device.os.readlink')
+    @patch('ceph_volume.util.device.os.path.islink')
+    def test_reject_symlink_to_device_mapper(self,
+                                             m_os_path_islink,
+                                             m_os_readlink,
+                                             device_info,
+                                             fake_call):
+        m_os_path_islink.return_value = True
+        m_os_readlink.return_value = '/dev/dm-0'
+        data = {"/dev/mapper/mpatha": {"ro": 0, "size": 5368709120}}
+        lsblk = {"TYPE": "disk"}
+        device_info(devices=data,lsblk=lsblk)
+        disk = device.Device("/dev/mapper/mpatha")
+        assert disk.available
+
+    @patch("ceph_volume.util.disk.has_bluestore_label", lambda x: False)
     def test_reject_readonly_device(self, fake_call, device_info):
         data = {"/dev/cdrom": {"ro": 1}}
         lsblk = {"TYPE": "disk", "NAME": "cdrom"}
index 32b388288991bd7c5fdfe67d37c6220ac4bc61d3..8f9dea6234dcd73a8b1156118c5d5a819821303a 100644 (file)
@@ -99,6 +99,15 @@ class Device(object):
 
     def __init__(self, path, with_lsm=False, lvs=None, lsblk_all=None, all_devices_vgs=None):
         self.path = path
+        # LVs can have a vg/lv path, while disks will have /dev/sda
+        self.symlink = None
+        # check if we are a symlink
+        if os.path.islink(self.path):
+            self.symlink = self.path
+            real_path = os.path.realpath(self.path)
+            # check if we are not a device mapper
+            if "dm-" not in real_path:
+                self.path = real_path
         if not sys_info.devices:
             sys_info.devices = disk.get_devices()
         self.sys_api = sys_info.devices.get(self.path, {})