]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common/blkdev: include by-path path for each device in metadata
authorSage Weil <sage@redhat.com>
Sat, 14 Dec 2019 16:06:40 +0000 (10:06 -0600)
committerSage Weil <sage@redhat.com>
Mon, 16 Dec 2019 13:16:44 +0000 (07:16 -0600)
Signed-off-by: Sage Weil <sage@redhat.com>
src/common/blkdev.cc
src/common/blkdev.h

index 165829129cf808dd11467db8e41fa65f50f56a9b..8ffdba8c6300d17064f64c661dfd1427983a7822 100644 (file)
@@ -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<std::string> 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<std::string>& devnames,
   std::map<std::string,std::string> *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;
+    }
   }
 }
index 31c6c7f10bcca3a031291c01ca11f7431c60afbf..488e4b787abe56b9444f128af016d86d033c9110 100644 (file)
@@ -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<std::string>& devnames,