]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: implement 'smart [devid]' tell command
authorSage Weil <sage@redhat.com>
Tue, 18 Sep 2018 21:47:56 +0000 (16:47 -0500)
committerSage Weil <sage@redhat.com>
Mon, 15 Oct 2018 14:44:05 +0000 (09:44 -0500)
Just like the OSD!

Signed-off-by: Sage Weil <sage@redhat.com>
src/common/options.cc
src/mon/MonCommands.h
src/mon/Monitor.cc

index ffed4884eff31baeebb2d85a8150b548a4df7811..36c9c9769c1a18b04edc9d976ca7a934b91df07c 100644 (file)
@@ -1803,6 +1803,11 @@ std::vector<Option> get_global_options() {
     .set_default(true)
     .set_description(""),
 
+    Option("mon_smart_report_timeout", Option::TYPE_UINT, Option::LEVEL_ADVANCED)
+    .set_default(5)
+    .set_description("Timeout (in seconds) for smarctl to run, default is set to 5"),
+
+
     Option("paxos_stash_full_interval", Option::TYPE_INT, Option::LEVEL_ADVANCED)
     .set_default(25)
     .set_description(""),
@@ -2019,7 +2024,7 @@ std::vector<Option> get_global_options() {
     .set_min(2)
     .set_description("Number of striping periods to zero head of MDS journal write position"),
 
-     Option("osd_smart_report_timeout", Option::TYPE_UINT, Option::LEVEL_ADVANCED)
+    Option("osd_smart_report_timeout", Option::TYPE_UINT, Option::LEVEL_ADVANCED)
     .set_default(5)
     .set_description("Timeout (in seconds) for smarctl to run, default is set to 5"),
 
index d63b222555cf8ff7057a5852d64cc0cfe05cff55..67b40335a59ebe8bf85f122482c9b68e9abb9295 100644 (file)
@@ -1149,3 +1149,8 @@ COMMAND("config reset" \
        " name=num,type=CephInt",
        "Revert configuration to previous state",
        "config", "rw", "cli,rest")
+
+COMMAND_WITH_FLAG("smart name=devid,type=CephString,req=false",
+                 "Query health metrics for underlying device",
+                 "mon", "rw", "cli,rest",
+                 FLAG(HIDDEN))
index 29093442828c92546a33f90c9a54074537815769..fa484029920ef28381e8129671e6d3e77d66dbb1 100644 (file)
@@ -22,6 +22,9 @@
 #include <boost/scope_exit.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 
+#include "json_spirit/json_spirit_reader.h"
+#include "json_spirit/json_spirit_writer.h"
+
 #include "Monitor.h"
 #include "common/version.h"
 #include "common/blkdev.h"
@@ -3601,6 +3604,39 @@ void Monitor::handle_command(MonOpRequestRef op)
     f->flush(rdata);
     rs = "";
     r = 0;
+  } else if (prefix == "smart") {
+    string want_devid;
+    cmd_getval(cct, cmdmap, "devid", want_devid);
+
+    string dev = store->get_devname();
+    string devid = get_device_id(dev);
+    if (want_devid.size() && want_devid != devid) {
+      r = -ENOENT;
+    } else {
+      uint64_t smart_timeout = cct->_conf.get_val<uint64_t>(
+       "mon_smart_report_timeout");
+      json_spirit::mObject json_map;
+      json_spirit::mValue smart_json;
+      std::string result;
+      if (block_device_run_smartctl(("/dev/" + dev).c_str(), smart_timeout,
+                                   &result)) {
+       dout(10) << "probe_smart_device failed for /dev/" << dev << dendl;
+       result = "{\"error\": \"smartctl failed\", \"dev\": \"" + dev +
+         "\", \"smartctl_error\": \"" + result + "\"}";
+      }
+
+      if (!json_spirit::read(result, smart_json)) {
+       derr << "smartctl JSON output of /dev/" + dev + " is invalid"
+            << dendl;
+      } else {
+       json_map[devid] = smart_json;
+      }
+      ostringstream ss;
+      json_spirit::write(json_map, ss, json_spirit::pretty_print);
+      rdata.append(ss.str());
+      r = 0;
+      rs = "";
+    }
   }
 
  out: