]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/blkdev: include by-path path for each device in metadata 33726/head
authorSage Weil <sage@redhat.com>
Sat, 14 Dec 2019 16:06:40 +0000 (10:06 -0600)
committerYaarit Hatuka <yaarit@redhat.com>
Wed, 4 Mar 2020 03:52:06 +0000 (03:52 +0000)
Signed-off-by: Sage Weil <sage@redhat.com>
(cherry picked from commit 74e49d5ce956033e4294de3001fedf8b0af6c8f7)

src/common/blkdev.cc
src/common/blkdev.h

index 6ee8539900369bed46b299c690fda424f5537cd0..f3758cd8c5f95226ad599e84938e61bd9a7a1fd1 100644 (file)
@@ -675,6 +675,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)
 {
@@ -882,6 +910,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 {
@@ -1061,6 +1099,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)
 {
@@ -1210,6 +1258,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)
 {
@@ -1231,6 +1289,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,
@@ -1250,5 +1309,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 e0e6d342b1baee99227855c1bb919fbbf770f01a..58e09c89773674990b370b02ad4c1aea0d65702a 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,