]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common/blkdev: add get_device_id() helper.
authorYaarit Hatuka <yaarithatuka@gmail.com>
Mon, 4 Jun 2018 04:01:36 +0000 (00:01 -0400)
committerSage Weil <sage@redhat.com>
Sat, 9 Jun 2018 19:25:22 +0000 (14:25 -0500)
Signed-off-by: Yaarit Hatuka yaarithatuka@gmail.com
src/CMakeLists.txt
src/common/blkdev.cc
src/common/blkdev.h

index e26fc79ce6f25dcf75105ee8e79b0cc9117b82df..78e21a669705cbaa5efa29a5ce05cbd8b51f69d2 100644 (file)
@@ -641,7 +641,8 @@ set(ceph_common_deps
   ${BLKIN_LIBRARIES}
   ${CRYPTO_LIBS}
   ${CMAKE_THREAD_LIBS_INIT}
-  ${CMAKE_DL_LIBS})
+  ${CMAKE_DL_LIBS}
+  ${UDEV_LIBRARIES})
 if(HAVE_RDMA)
   list(APPEND ceph_common_deps ${RDMA_LIBRARY})
 endif()
@@ -1043,7 +1044,7 @@ if(WITH_RBD)
   if(WITH_KRBD)
     add_library(krbd STATIC krbd.cc
       $<TARGET_OBJECTS:parse_secret_objs>)
-    target_link_libraries(krbd ${KEYUTILS_LIBRARIES} ${UDEV_LIBRARIES})
+    target_link_libraries(krbd ${KEYUTILS_LIBRARIES})
   endif()
   add_subdirectory(librbd)
   if(WITH_FUSE)
index 0cd5bafd2acfc768a0d8485d6ff16c5bc971c9b5..7de7671119f41f68a70d00705d11dc39efa46628 100644 (file)
@@ -17,6 +17,8 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <dirent.h>
+#include <libudev.h>
+//#include "common/debug.h"
 #include "include/uuid.h"
 #include "blkdev.h"
 
@@ -31,6 +33,8 @@
 
 static const char *sandbox_dir = "";
 
+static std::string get_block_device_string_property_wrap(const std::string &devname, const std::string &property); 
+
 void set_block_device_sandbox_dir(const char *dir)
 {
   if (dir)
@@ -209,11 +213,21 @@ bool block_device_is_rotational(const char *devname)
   return get_block_device_int_property(devname, "queue/rotational") > 0;
 }
 
+int block_device_vendor(const char *devname, char *vendor, size_t max)
+{
+  return get_block_device_string_property(devname, "device/vendor", vendor, max);
+}
+
 int block_device_model(const char *devname, char *model, size_t max)
 {
   return get_block_device_string_property(devname, "device/model", model, max);
 }
 
+int block_device_serial(const char *devname, char *serial, size_t max)
+{
+  return get_block_device_string_property(devname, "device/serial", serial, max);
+}
+
 int get_device_by_fd(int fd, char *partition, char *device, size_t max)
 {
   struct stat st;
@@ -357,6 +371,75 @@ bool get_vdo_utilization(int fd, uint64_t *total, uint64_t *avail)
   return true;
 }
 
+// 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)
+{
+  struct udev_device *dev;
+  static struct udev *udev;
+  const char *data;
+  std::string device_id;
+
+  udev = udev_new();
+  if (!udev) {
+    //derr << "failed to run udev_new(), when calling for device " << devname << dendl;
+    return {};
+  }
+  dev = udev_device_new_from_subsystem_sysname(udev, "block", devname.c_str());
+  if (!dev) {
+    //derr << "failed to run udev_device_new_from_subsystem_sysname() for " << devname << dendl;
+    udev_unref(udev);
+    return {};
+  }
+
+  // "ID_SERIAL_SHORT" returns only the serial number;
+  // "ID_SERIAL" returns vendor model_serial.
+  data = udev_device_get_property_value(dev, "ID_SERIAL");
+  if (data) {
+    device_id = data;
+  }
+
+  udev_device_unref(dev);
+  udev_unref(udev);
+
+  if (!device_id.empty()) {
+    //dout << devname << " serial number: " << data << dendl;
+    std::replace(device_id.begin(), device_id.end(), ' ', '_');
+    return device_id;
+  }
+
+  // either udev_device_get_property_value() failed, or succeeded but returned nothing;
+  // trying to read from files.
+  //derr << "udev could not retrieve serial number of " << devname << dendl;
+
+  std::string vendor, model, serial;
+  vendor = get_block_device_string_property_wrap(devname, "device/vendor");
+  model = get_block_device_string_property_wrap(devname, "device/model");
+  serial = get_block_device_string_property_wrap(devname, "device/serial");
+
+  // "none" is here for indication reasons only, for a start.
+  device_id = (vendor.empty() ? "none" : vendor) + "_"
+    + (model.empty() ? "none" : model) + "_"
+    + (serial.empty() ? "none" : serial);
+
+  std::replace(device_id.begin(), device_id.end(), ' ', '_');
+  return device_id;
+}
+
+std::string get_block_device_string_property_wrap(const std::string &devname,
+                                                 const std::string &property)
+{
+  char buff[1024] = {0};
+  std::string prop_val;
+  int ret = get_block_device_string_property(devname.c_str(), property.c_str(), buff, sizeof(buff));
+  if (ret < 0) {
+    //derr << "Could not retrieve content of " << property << " file of " << devname << dendl;
+    return {};
+  }
+  prop_val = buff;
+  return prop_val;
+}
+
 #elif defined(__APPLE__)
 #include <sys/disk.h>
 
index badf5c993ff83f98a4065961d13386f6217b0b62..d15439d28b9f2e26cec6c9746175eb4ee60220f6 100644 (file)
@@ -23,9 +23,12 @@ extern int64_t get_block_device_string_property(
        char *val, size_t maxlen);
 extern bool block_device_support_discard(const char *devname);
 extern bool block_device_is_rotational(const char *devname);
+extern int block_device_vendor(const char *devname, char *vendor, size_t max);
 extern int block_device_model(const char *devname, char *model, size_t max);
+extern int block_device_serial(const char *devname, char *serial, size_t max);
 
 extern void get_dm_parents(const std::string& dev, std::set<std::string> *ls);
+extern std::string get_device_id(const std::string& devname);
 
 // for VDO