From c0517ea1db2419997412a0f0a51953215a233eae Mon Sep 17 00:00:00 2001 From: Jan Fajerski Date: Wed, 21 Nov 2018 13:20:45 +0100 Subject: [PATCH] ceph-volume: add device_id field to inventory output This intends to mimic the C++ implementation in src/common/blkdev.cc. Signed-off-by: Jan Fajerski (cherry picked from commit 41da5e9a4334628db09e3166eaceff79b9b6c7e0) --- src/ceph-volume/ceph_volume/util/device.py | 17 +++++++++ src/ceph-volume/ceph_volume/util/disk.py | 41 ++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/ceph-volume/ceph_volume/util/device.py b/src/ceph-volume/ceph_volume/util/device.py index 1810448869b1b..b94628cf86434 100644 --- a/src/ceph-volume/ceph_volume/util/device.py +++ b/src/ceph-volume/ceph_volume/util/device.py @@ -79,6 +79,7 @@ class Device(object): self._is_lvm_member = None self._parse() self.available, self.rejected_reasons = self._check_reject_reasons() + self.device_id = self._get_device_id() def __lt__(self, other): ''' @@ -172,6 +173,22 @@ class Device(object): output['lvs'] = [lv.report() for lv in self.lvs] return output + def _get_device_id(self): + props = ['ID_MODEL','ID_SERIAL_SHORT'] + dev_id = disk.udevadm_property(self.abspath, props) + if all([prop in dev_id and dev_id[prop] for prop in props]): + values = [dev_id[prop].replace(' ', '_') for prop in props] + return '_'.join(values) + else: + # the else branch should fallback to using sysfs and ioctl to + # retrieve device_id on FreeBSD. Still figuring out if/how the + # python ioctl implementation does that on FreeBSD + return '' + return '' + + + + def _set_lvm_membership(self): if self._is_lvm_member is None: # this is contentious, if a PV is recognized by LVM but has no diff --git a/src/ceph-volume/ceph_volume/util/disk.py b/src/ceph-volume/ceph_volume/util/disk.py index ccc2ff7a15226..1b1c4d8af138d 100644 --- a/src/ceph-volume/ceph_volume/util/disk.py +++ b/src/ceph-volume/ceph_volume/util/disk.py @@ -170,6 +170,47 @@ def device_family(device): return devices +def udevadm_property(device, properties=[]): + """ + Query udevadm for information about device properties. + Optionally pass a list of properties to return. A requested property might + not be returned if not present. + + Expected output format:: + # udevadm info --query=property --name=/dev/sda :( + DEVNAME=/dev/sda + DEVTYPE=disk + ID_ATA=1 + ID_BUS=ata + ID_MODEL=SK_hynix_SC311_SATA_512GB + ID_PART_TABLE_TYPE=gpt + ID_PART_TABLE_UUID=c8f91d57-b26c-4de1-8884-0c9541da288c + ID_PATH=pci-0000:00:17.0-ata-3 + ID_PATH_TAG=pci-0000_00_17_0-ata-3 + ID_REVISION=70000P10 + ID_SERIAL=SK_hynix_SC311_SATA_512GB_MS83N71801150416A + TAGS=:systemd: + USEC_INITIALIZED=16117769 + ... + """ + out = _udevadm_info(device) + ret = {} + for line in out: + p, v = line.split('=', 1) + if not properties or p in properties: + ret[p] = v + return ret + + +def _udevadm_info(device): + """ + Call udevadm and return the output + """ + cmd = ['udevadm', 'info', '--query=property', device] + out, _err, _rc = process.call(cmd) + return out + + def lsblk(device, columns=None, abspath=False): """ Create a dictionary of identifying values for a device using ``lsblk``. -- 2.39.5