From 232d28b283dfe25eb2ae613e9852d4639b1ca156 Mon Sep 17 00:00:00 2001 From: Yaarit Hatuka Date: Mon, 4 Jun 2018 00:01:36 -0400 Subject: [PATCH] common/blkdev: add get_device_id() helper. Signed-off-by: Yaarit Hatuka yaarithatuka@gmail.com --- src/CMakeLists.txt | 5 +-- src/common/blkdev.cc | 83 ++++++++++++++++++++++++++++++++++++++++++++ src/common/blkdev.h | 3 ++ 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e26fc79ce6f25..78e21a669705c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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_link_libraries(krbd ${KEYUTILS_LIBRARIES} ${UDEV_LIBRARIES}) + target_link_libraries(krbd ${KEYUTILS_LIBRARIES}) endif() add_subdirectory(librbd) if(WITH_FUSE) diff --git a/src/common/blkdev.cc b/src/common/blkdev.cc index 0cd5bafd2acfc..7de7671119f41 100644 --- a/src/common/blkdev.cc +++ b/src/common/blkdev.cc @@ -17,6 +17,8 @@ #include #include #include +#include +//#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 diff --git a/src/common/blkdev.h b/src/common/blkdev.h index badf5c993ff83..d15439d28b9f2 100644 --- a/src/common/blkdev.h +++ b/src/common/blkdev.h @@ -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 *ls); +extern std::string get_device_id(const std::string& devname); // for VDO -- 2.39.5