Skip to content

Commit

Permalink
ceph-volume: support symlinks as devices
Browse files Browse the repository at this point in the history
This makes ceph-volume support passing symlinks as devices.

Fixes: https://tracker.ceph.com/issues/49103

Signed-off-by: Guillaume Abrioux <gabrioux@redhat.com>
  • Loading branch information
Jan Sobczak authored and guits committed Jul 27, 2022
1 parent 01112ba commit 9ddc5b7
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 3 deletions.
12 changes: 9 additions & 3 deletions src/ceph-volume/ceph_volume/devices/lvm/batch.py
Expand Up @@ -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


Expand Down Expand Up @@ -568,7 +569,8 @@ def __init__(self,
abs_size,
slots,
id_,
encryption):
encryption,
symlink=None):
self.id_ = id_
self.data = self.VolSpec(path=data_path,
rel_size=rel_size,
Expand All @@ -578,6 +580,7 @@ def __init__(self,
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,
Expand Down Expand Up @@ -629,9 +632,12 @@ def report(self):
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:
Expand Down
1 change: 1 addition & 0 deletions src/ceph-volume/ceph_volume/tests/conftest.py
Expand Up @@ -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]
Expand Down
34 changes: 34 additions & 0 deletions src/ceph-volume/ceph_volume/tests/util/test_device.py
Expand Up @@ -276,6 +276,40 @@ def test_reject_not_acceptable_device(self, fake_call, device_info):
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}}
Expand Down
9 changes: 9 additions & 0 deletions src/ceph-volume/ceph_volume/util/device.py
Expand Up @@ -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, {})
Expand Down

0 comments on commit 9ddc5b7

Please sign in to comment.