From 74e49d5ce956033e4294de3001fedf8b0af6c8f7 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 14 Dec 2019 10:06:40 -0600 Subject: [PATCH] common/blkdev: include by-path path for each device in metadata Signed-off-by: Sage Weil --- src/common/blkdev.cc | 68 ++++++++++++++++++++++++++++++++++++++++++++ src/common/blkdev.h | 5 ++++ 2 files changed, 73 insertions(+) diff --git a/src/common/blkdev.cc b/src/common/blkdev.cc index 165829129cf80..8ffdba8c6300d 100644 --- a/src/common/blkdev.cc +++ b/src/common/blkdev.cc @@ -659,6 +659,34 @@ static int block_device_run_vendor_nvme( return ret; } +std::string get_device_path(const std::string& devname, + std::string *err) +{ + std::set links; + int r = easy_readdir("/dev/disk/by-path", &links); + if (r < 0) { + *err = "unable to list contents of /dev/disk/by-path: "s + + cpp_strerror(r); + return {}; + } + for (auto& i : links) { + char fn[PATH_MAX]; + char target[PATH_MAX+1]; + snprintf(fn, sizeof(fn), "/dev/disk/by-path/%s", i.c_str()); + int r = readlink(fn, target, sizeof(target)); + if (r < 0 || r >= (int)sizeof(target)) + continue; + target[r] = 0; + if ((unsigned)r > devname.size() + 1 && + strncmp(target + r - devname.size(), devname.c_str(), r) == 0 && + target[r - devname.size() - 1] == '/') { + return fn; + } + } + *err = "no symlink to "s + devname + " in /dev/disk/by-path"; + return {}; +} + static int block_device_run_smartctl(const string& devname, int timeout, std::string *result) { @@ -885,6 +913,16 @@ std::string get_device_id(const std::string& devname, return std::string(); } +std::string get_device_path(const std::string& devname, + std::string *err) +{ + // FIXME: implement me + if (err) { + *err = "not implemented"; + } + return std::string(); +} + #elif defined(__FreeBSD__) const char *BlkDev::sysfsdir() const { @@ -1045,6 +1083,16 @@ std::string get_device_id(const std::string& devname, return std::string(); } +std::string get_device_path(const std::string& devname, + std::string *err) +{ + // FIXME: implement me for freebsd + if (err) { + *err = "not implemented for FreeBSD"; + } + return std::string(); +} + int block_device_run_smartctl(const char *device, int timeout, std::string *result) { @@ -1189,6 +1237,16 @@ std::string get_device_id(const std::string& devname, return std::string(); } +std::string get_device_path(const std::string& devname, + std::string *err) +{ + // not implemented + if (err) { + *err = "not implemented"; + } + return std::string(); +} + int block_device_run_smartctl(const char *device, int timeout, std::string *result) { @@ -1210,6 +1268,7 @@ int block_device_run_nvme(const char *device, const char *vendor, int timeout, #endif + void get_device_metadata( const std::set& devnames, std::map *pm, @@ -1229,5 +1288,14 @@ void get_device_metadata( } else { (*errs)[dev] = " no unique device id for "s + dev + ": " + err; } + string path = get_device_path(dev, &err); + if (path.size()) { + if (!devpaths.empty()) { + devpaths += ","; + } + devpaths += dev + "=" + path; + } else { + (*errs)[dev] + " no unique device path for "s + dev + ": " + err; + } } } diff --git a/src/common/blkdev.h b/src/common/blkdev.h index 31c6c7f10bcca..488e4b787abe5 100644 --- a/src/common/blkdev.h +++ b/src/common/blkdev.h @@ -28,6 +28,11 @@ extern std::string _decode_model_enc(const std::string& in); // helper, exporte // get $vendor_$model_$serial style device id extern std::string get_device_id(const std::string& devname, std::string *err=0); + +// get /dev/disk/by-path/... style device id that is stable for a disk slot across reboots etc +extern std::string get_device_path(const std::string& devname, + std::string *err=0); + // populate daemon metadata map with device info extern void get_device_metadata( const std::set& devnames, -- 2.39.5