]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
blkdev: FreeBSD support 24658/head
authorAlan Somers <asomers@gmail.com>
Thu, 28 Sep 2017 20:13:15 +0000 (14:13 -0600)
committerKefu Chai <kchai@redhat.com>
Fri, 19 Oct 2018 11:37:42 +0000 (19:37 +0800)
Signed-off-by: Alan Somers <asomers@gmail.com>
CMakeLists.txt
src/common/blkdev.cc
src/os/bluestore/KernelDevice.cc
src/test/CMakeLists.txt
src/test/common/CMakeLists.txt

index 1708ad173c35dcb390a395e9864aef9ed5f29dd2..94d0f474dee31b899924fd6588e1cf70d8671dc4 100644 (file)
@@ -215,6 +215,10 @@ if(LINUX)
   set(HAVE_UDEV ${UDEV_FOUND})
   find_package(blkid REQUIRED)
   set(HAVE_BLKID ${BLKID_FOUND})
+elseif(FREEBSD)
+  set(HAVE_UDEV OFF)
+  set(HAVE_LIBAIO OFF)
+  set(HAVE_BLKID OFF)
 else()
   set(HAVE_UDEV OFF)
   message(STATUS "Not using udev")
index f9e9b2220154c1893da00c997ac649b81df913fc..6ff18634bed088f32df74957348c8b1a3b3b4478 100644 (file)
@@ -7,11 +7,18 @@
  *
  * This is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software 
+ * License version 2.1, as published by the Free Software
  * Foundation.  See file COPYING.
- * 
+ *
  */
 
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#include <geom/geom_disk.h>
+#include <sys/disk.h>
+#include <fcntl.h>
+#endif
+
 #include <errno.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
@@ -63,14 +70,6 @@ int get_device_by_path(const char *path, char* partition, char* device,
 
 #endif
 
-static const char *blkdev_props2strings[] = {
-  [BLKDEV_PROP_DEV]                 = "dev",
-  [BLKDEV_PROP_DISCARD_GRANULARITY] = "queue/discard_granularity",
-  [BLKDEV_PROP_MODEL]               = "device/model",
-  [BLKDEV_PROP_ROTATIONAL]          = "queue/rotational",
-  [BLKDEV_PROP_SERIAL]              = "device/serial",
-  [BLKDEV_PROP_VENDOR]              = "device/vendor",
-};
 
 BlkDev::BlkDev(int f)
   : fd(f)
@@ -80,10 +79,6 @@ BlkDev::BlkDev(const std::string& devname)
   : devname(devname)
 {}
 
-const char *BlkDev::sysfsdir() const {
-  return "/sys";
-}
-
 int BlkDev::get_devid(dev_t *id) const {
   struct stat st;
 
@@ -584,7 +579,6 @@ bool get_vdo_utilization(int fd, uint64_t *total, uint64_t *avail)
 }
 
 #elif defined(__FreeBSD__)
-#include <sys/disk.h>
 
 const char *BlkDev::sysfsdir() const {
   assert(false);  // Should never be called on FreeBSD
@@ -613,6 +607,19 @@ int BlkDev::get_size(int64_t *psize) const
 
 bool BlkDev::support_discard() const
 {
+#ifdef FREEBSD_WITH_TRIM
+  // there is no point to claim support of discard, but
+  // unable to do so.
+  struct diocgattr_arg arg;
+
+  strlcpy(arg.name, "GEOM::candelete", sizeof(arg.name));
+  arg.len = sizeof(arg.value.i);
+  if (ioctl(fd, DIOCGATTR, &arg) == 0) {
+    return (arg.value.i != 0);
+  } else {
+    return false;
+  }
+#endif
   return false;
 }
 
@@ -642,17 +649,64 @@ bool BlkDev::is_nvme() const
 
 bool BlkDev::is_rotational() const
 {
-  return false;
+#if __FreeBSD_version >= 1200049
+  struct diocgattr_arg arg;
+
+  strlcpy(arg.name, "GEOM::rotation_rate", sizeof(arg.name));
+  arg.len = sizeof(arg.value.u16);
+
+  int ioctl_ret = ioctl(fd, DIOCGATTR, &arg);
+  bool ret;
+  if (ioctl_ret < 0 || arg.value.u16 == DISK_RR_UNKNOWN)
+    // DISK_RR_UNKNOWN usually indicates an old drive, which is usually spinny
+    ret = true;
+  else if (arg.value.u16 == DISK_RR_NON_ROTATING)
+    ret = false;
+  else if (arg.value.u16 >= DISK_RR_MIN && arg.value.u16 <= DISK_RR_MAX)
+    ret = true;
+  else
+    ret = true;     // Invalid value.  Probably spinny?
+
+  return ret;
+#else
+  return true;      // When in doubt, it's probably spinny
+#endif
 }
 
 int BlkDev::model(char *model, size_t max) const
 {
-  return false;
+  struct diocgattr_arg arg;
+
+  strlcpy(arg.name, "GEOM::descr", sizeof(arg.name));
+  arg.len = sizeof(arg.value.str);
+  if (ioctl(fd, DIOCGATTR, &arg) < 0) {
+    return -errno;
+  }
+
+  // The GEOM description is of the form "vendor product" for SCSI disks
+  // and "ATA device_model" for ATA disks.  Some vendors choose to put the
+  // vendor name in device_model, and some don't.  Strip the first bit.
+  char *p = arg.value.str;
+  if (p == NULL || *p == '\0') {
+    *model = '\0';
+  } else {
+    (void) strsep(&p, " ");
+    snprintf(model, max, "%s", p);
+  }
+
+  return 0;
 }
 
-int BlkDev::serial(char *serial, size_t max) const
+int BlkDev::serial(char *serial, size_t max)
 {
-  return -EOPNOTSUPP;
+  char ident[DISK_IDENT_SIZE];
+
+  if (ioctl(fd, DIOCGIDENT, ident) < 0)
+    return -errno;
+
+  snprintf(serial, max, "%s", ident);
+
+  return 0;
 }
 
 void get_dm_parents(const std::string& dev, std::set<std::string> *ls)
index bb9956bf9c8a5027500e4b896622f01830b47ea5..52388fd1081f98a0b4343c285979ed8eed01601a 100644 (file)
@@ -233,11 +233,25 @@ int KernelDevice::collect_metadata(const string& prefix, map<string,string> *pm)
   if (r < 0)
     return -errno;
   if (S_ISBLK(st.st_mode)) {
-    char buffer[1024] = {0};
-    BlkDev blkdev(fd_buffered);
-
     (*pm)[prefix + "access_mode"] = "blk";
 
+    char buffer[1024] = {0};
+    BlkDev blkdev{fd_buffered};
+    if (r = blkdev.partition(buffer, sizeof(buffer)); r) {
+      (*pm)[prefix + "partition_path"] = "unknown";
+    } else {
+      (*pm)[prefix + "partition_path"] = buffer;
+    }
+    buffer[0] = '\0';
+    if (r = blkdev.partition(buffer, sizeof(buffer)); r) {
+      (*pm)[prefix + "dev_node"] = "unknown";
+    } else {
+      (*pm)[prefix + "dev_node"] = buffer;
+    }
+    if (!r) {
+      return 0;
+    }
+    buffer[0] = '\0';
     blkdev.model(buffer, sizeof(buffer));
     (*pm)[prefix + "model"] = buffer;
 
index 49ae77e2ac5b3227ec2d87ceb095e0f3c3488c1b..43243785864ffc32b0b1149dc6a8eea23bf4ffe5 100644 (file)
@@ -447,7 +447,7 @@ if(${WITH_CEPHFS})
     cephfs)
 endif(${WITH_CEPHFS})
 
-if(HAVE_BLKID)
+if(HAVE_BLKID OR FREEBSD)
   add_executable(ceph_test_get_blkdev_props
     test_get_blkdev_props.cc
     )
@@ -458,7 +458,7 @@ if(HAVE_BLKID)
     ${BLKID_LIBRARIES}
     ${CMAKE_DL_LIBS}
     )
-endif(HAVE_BLKID)
+endif(HAVE_BLKID OR FREEBSD)
 
 # ceph_test_admin_socket_output
 
index 5692c3de0006d8eb8d1a2512e22056f8af830b31..21a54aeb677a5d80c89ec0a823122997c80c0464 100644 (file)
@@ -12,13 +12,13 @@ target_link_libraries(get_command_descriptions
   ${CMAKE_DL_LIBS}
   )
 
-if(HAVE_BLKID)
+# Though FreeBSD has blkdev support, the unittests' mocks only work in Linux
+if(HAVE_BLKID AND LINUX)
   # unittest_blkdev
   add_executable(unittest_blkdev
-    test_blkdev.cc
-    )
-  add_ceph_unittest(unittest_blkdev)
-  target_link_libraries(unittest_blkdev ceph-common ${BLKID_LIBRARIES})
+    test_blkdev.cc)
+  add_ceph_unittest(unittest_blkdev ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest_blkdev)
+  target_link_libraries(unittest_blkdev global ${BLKID_LIBRARIES})
 endif()
 
 # unittest_lockdep