From de565dd2420f2d2a4a4f6fd12b0bc48af87a4e7d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 15 Mar 2019 17:12:34 -0500 Subject: [PATCH] common/blkdev: handle devices with ID_MODEL as "LVM PV ..." but valid ID_MODEL_ENC Some devices appear like so: E: ID_MODEL=LVM PV LUClYG-Oyte-jcM6-npfZ-ncsl-ycL0-bkOH0m on /dev/sdn E: ID_MODEL_ENC=WDC\x20WDS200T2B0A-00SM50\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20 E: ID_SERIAL=WDC_WDS200T2B0A-00SM50_183503800168 E: ID_SERIAL_SHORT=183503800168 To avoid upsetting our prioritization, defer to ID_MODEL_ENC over ID_MODEL if ID_MODEL has "LVM PV" in it (as opposed to just using ID_SERIAL). Signed-off-by: Sage Weil --- src/ceph-volume/ceph_volume/util/device.py | 4 +- src/common/blkdev.cc | 20 +++++++ src/common/blkdev.h | 1 + .../blkdev-udevadm-info-samples/cpach.sdn | 53 +++++++++++++++++++ .../cpach.sdn.devid | 1 + src/test/common/test_blkdev.cc | 16 ++++++ 6 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/test/common/blkdev-udevadm-info-samples/cpach.sdn create mode 100644 src/test/common/blkdev-udevadm-info-samples/cpach.sdn.devid diff --git a/src/ceph-volume/ceph_volume/util/device.py b/src/ceph-volume/ceph_volume/util/device.py index d07b39593eb..ae7cf6c56e8 100644 --- a/src/ceph-volume/ceph_volume/util/device.py +++ b/src/ceph-volume/ceph_volume/util/device.py @@ -199,9 +199,11 @@ class Device(object): Please keep this implementation in sync with get_device_id() in src/common/blkdev.cc """ - props = ['ID_VENDOR','ID_MODEL','ID_SERIAL_SHORT', 'ID_SERIAL', + props = ['ID_VENDOR', 'ID_MODEL', 'ID_MODEL_ENC', 'ID_SERIAL_SHORT', 'ID_SERIAL', 'ID_SCSI_SERIAL'] p = disk.udevadm_property(self.abspath, props) + if p.get('ID_MODEL','').startswith('LVM PV '): + p['ID_MODEL'] = p.get('ID_MODEL_ENC').replace('\\x20', ' ').strip() if 'ID_VENDOR' in p and 'ID_MODEL' in p and 'ID_SCSI_SERIAL' in p: dev_id = '_'.join([p['ID_VENDOR'], p['ID_MODEL'], p['ID_SCSI_SERIAL']]) diff --git a/src/common/blkdev.cc b/src/common/blkdev.cc index 555cef953d3..35b9bbb275a 100644 --- a/src/common/blkdev.cc +++ b/src/common/blkdev.cc @@ -28,6 +28,7 @@ #include #include #include +#include //#include "common/debug.h" #include "include/scope_guard.h" #include "include/uuid.h" @@ -433,6 +434,16 @@ bool get_vdo_utilization(int fd, uint64_t *total, uint64_t *avail) return true; } +std::string _decode_model_enc(const std::string& in) +{ + auto v = boost::replace_all_copy(in, "\\x20", " "); + if (auto found = v.find_last_not_of(" "); found != v.npos) { + v.erase(found + 1); + } + std::replace(v.begin(), v.end(), ' ', '_'); + return v; +} + // trying to use udev first, and if it doesn't work, we fall back to // reading /sys/block/$devname/device/(vendor/model/serial). std::string get_device_id(const std::string& devname, @@ -472,6 +483,15 @@ std::string get_device_id(const std::string& devname, data = udev_device_get_property_value(dev, "ID_MODEL"); if (data) { id_model = data; + // sometimes, ID_MODEL is "LVM ..." but ID_MODEL_ENC is correct (but + // encoded with \x20 for space). + if (id_model.substr(0, 7) == "LVM PV ") { + std::string enc = udev_device_get_property_value(dev, "ID_MODEL_ENC"); + enc = _decode_model_enc(enc); + if (enc.size()) { + id_model = enc; + } + } } data = udev_device_get_property_value(dev, "ID_SERIAL_SHORT"); if (data) { diff --git a/src/common/blkdev.h b/src/common/blkdev.h index 4df433f76af..d471df22dc5 100644 --- a/src/common/blkdev.h +++ b/src/common/blkdev.h @@ -22,6 +22,7 @@ enum blkdev_prop_t { extern int get_device_by_path(const char *path, char* partition, char* device, size_t max); +extern std::string _decode_model_enc(const std::string& in); // helper, exported only so we can unit test extern std::string get_device_id(const std::string& devname, std::string *err=0); diff --git a/src/test/common/blkdev-udevadm-info-samples/cpach.sdn b/src/test/common/blkdev-udevadm-info-samples/cpach.sdn new file mode 100644 index 00000000000..a47a5270a38 --- /dev/null +++ b/src/test/common/blkdev-udevadm-info-samples/cpach.sdn @@ -0,0 +1,53 @@ +P: /devices/pci0000:80/0000:80:01.0/0000:82:00.0/host10/port-10:0/expander-10:0/port-10:0:13/end_device-10:0:13/target10:0:13/10:0:13:0/block/sdn +N: sdn +S: disk/by-id/ata-WDC_WDS200T2B0A-00SM50_183503800168 +S: disk/by-id/lvm-pv-uuid-LUClYG-Oyte-jcM6-npfZ-ncsl-ycL0-bkOH0m +S: disk/by-id/wwn-0x5001b448b96ce4fd +S: disk/by-path/pci-0000:82:00.0-sas-exp0x50030480091072bf-phy29-lun-0 +E: DEVLINKS=/dev/disk/by-path/pci-0000:82:00.0-sas-exp0x50030480091072bf-phy29-lun-0 /dev/disk/by-id/wwn-0x5001b448b96ce4fd /dev/disk/by-id/ata-WDC_WDS200T2B0A-00SM50_183503800168 /dev/disk/by-id/lvm-pv-uuid-LUClYG-Oyte-jcM6-npfZ-ncsl-ycL0-bkOH0m +E: DEVNAME=/dev/sdn +E: DEVPATH=/devices/pci0000:80/0000:80:01.0/0000:82:00.0/host10/port-10:0/expander-10:0/port-10:0:13/end_device-10:0:13/target10:0:13/10:0:13:0/block/sdn +E: DEVTYPE=disk +E: ID_ATA=1 +E: ID_ATA_DOWNLOAD_MICROCODE=1 +E: ID_ATA_FEATURE_SET_APM=1 +E: ID_ATA_FEATURE_SET_APM_CURRENT_VALUE=254 +E: ID_ATA_FEATURE_SET_APM_ENABLED=1 +E: ID_ATA_FEATURE_SET_PM=1 +E: ID_ATA_FEATURE_SET_PM_ENABLED=1 +E: ID_ATA_FEATURE_SET_SECURITY=1 +E: ID_ATA_FEATURE_SET_SECURITY_ENABLED=0 +E: ID_ATA_FEATURE_SET_SECURITY_ENHANCED_ERASE_UNIT_MIN=2 +E: ID_ATA_FEATURE_SET_SECURITY_ERASE_UNIT_MIN=2 +E: ID_ATA_FEATURE_SET_SMART=1 +E: ID_ATA_FEATURE_SET_SMART_ENABLED=1 +E: ID_ATA_ROTATION_RATE_RPM=0 +E: ID_ATA_SATA=1 +E: ID_ATA_SATA_SIGNAL_RATE_GEN1=1 +E: ID_ATA_SATA_SIGNAL_RATE_GEN2=1 +E: ID_ATA_WRITE_CACHE=1 +E: ID_ATA_WRITE_CACHE_ENABLED=1 +E: ID_BUS=ata +E: ID_FS_TYPE=LVM2_member +E: ID_FS_USAGE=raid +E: ID_FS_UUID=LUClYG-Oyte-jcM6-npfZ-ncsl-ycL0-bkOH0m +E: ID_FS_UUID_ENC=LUClYG-Oyte-jcM6-npfZ-ncsl-ycL0-bkOH0m +E: ID_FS_VERSION=LVM2 001 +E: ID_MODEL=LVM PV LUClYG-Oyte-jcM6-npfZ-ncsl-ycL0-bkOH0m on /dev/sdn +E: ID_MODEL_ENC=WDC\x20WDS200T2B0A-00SM50\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20 +E: ID_PATH=pci-0000:82:00.0-sas-exp0x50030480091072bf-phy29-lun-0 +E: ID_PATH_TAG=pci-0000_82_00_0-sas-exp0x50030480091072bf-phy29-lun-0 +E: ID_REVISION=X61190WD +E: ID_SERIAL=WDC_WDS200T2B0A-00SM50_183503800168 +E: ID_SERIAL_SHORT=183503800168 +E: ID_TYPE=disk +E: ID_WWN=0x5001b448b96ce4fd +E: ID_WWN_WITH_EXTENSION=0x5001b448b96ce4fd +E: MAJOR=8 +E: MINOR=208 +E: SUBSYSTEM=block +E: SYSTEMD_ALIAS=/dev/block/8:208 +E: SYSTEMD_READY=1 +E: SYSTEMD_WANTS=lvm2-pvscan@8:208.service +E: TAGS=:systemd: +E: USEC_INITIALIZED=20972398 diff --git a/src/test/common/blkdev-udevadm-info-samples/cpach.sdn.devid b/src/test/common/blkdev-udevadm-info-samples/cpach.sdn.devid new file mode 100644 index 00000000000..004460cf757 --- /dev/null +++ b/src/test/common/blkdev-udevadm-info-samples/cpach.sdn.devid @@ -0,0 +1 @@ +WDC_WDS200T2B0A-00SM50_183503800168 diff --git a/src/test/common/test_blkdev.cc b/src/test/common/test_blkdev.cc index d80459001f9..9dec5297217 100644 --- a/src/test/common/test_blkdev.cc +++ b/src/test/common/test_blkdev.cc @@ -91,3 +91,19 @@ TEST_F(BlockDevTest, is_rotational) EXPECT_FALSE(sda.is_rotational()); EXPECT_TRUE(sdb.is_rotational()); } + +TEST(blkdev, _decode_model_enc) +{ + + const char *foo[][2] = { + { "WDC\\x20WDS200T2B0A-00SM50\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20", + "WDC_WDS200T2B0A-00SM50" }, + { 0, 0}, + }; + + for (unsigned i = 0; foo[i][0]; ++i) { + std::string d = _decode_model_enc(foo[i][0]); + cout << " '" << foo[i][0] << "' -> '" << d << "'" << std::endl; + ASSERT_EQ(std::string(foo[i][1]), d); + } +} -- 2.39.5