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']])
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
+#include <boost/algorithm/string/replace.hpp>
//#include "common/debug.h"
#include "include/scope_guard.h"
#include "include/uuid.h"
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,
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) {
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);
--- /dev/null
+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
--- /dev/null
+WDC_WDS200T2B0A-00SM50_183503800168
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);
+ }
+}