From 2fb6315db135830a08ac2e3987c7dcfdeb09ca1b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 18 Sep 2018 14:20:10 -0500 Subject: [PATCH] common/blkdev: migrate block_device_run_smartctl from OSD.cc Slight change in behavior here in that we return the error message in the result. Signed-off-by: Sage Weil --- src/common/blkdev.cc | 54 ++++++++++++++++++++++++++++++++++++++++++++ src/common/blkdev.h | 3 +++ src/osd/OSD.cc | 45 ++++-------------------------------- src/osd/OSD.h | 1 - 4 files changed, 61 insertions(+), 42 deletions(-) diff --git a/src/common/blkdev.cc b/src/common/blkdev.cc index 00fdcb3fbff..f7c476076d9 100644 --- a/src/common/blkdev.cc +++ b/src/common/blkdev.cc @@ -30,6 +30,9 @@ #include +#include "common/SubProcess.h" +#include "common/errno.h" + #define UUID_LEN 36 @@ -436,6 +439,45 @@ std::string get_block_device_string_property_wrap(const std::string &devname, return prop_val; } +int block_device_run_smartctl(const char *device, int timeout, + std::string *result) +{ + // when using --json, smartctl will report its errors in JSON format to stdout + SubProcessTimed smartctl( + "sudo", SubProcess::CLOSE, SubProcess::PIPE, SubProcess::CLOSE, + timeout); + smartctl.add_cmd_args( + "smartctl", + "-a", + //"-x", + "--json", + device, + NULL); + + int ret = smartctl.spawn(); + if (ret != 0) { + *result = std::string("error spawning smartctl: ") + smartctl.err(); + return ret; + } + + bufferlist output; + ret = output.read_fd(smartctl.get_stdout(), 100*1024); + if (ret < 0) { + *result = std::string("failed read smartctl output: ") + cpp_strerror(-ret); + } else { + ret = 0; + *result = output.to_str(); + } + + if (smartctl.join() != 0) { + *result = std::string("smartctl returned an error:") + smartctl.err(); + return -EINVAL; + } + + return ret; +} + + #elif defined(__APPLE__) #include @@ -544,6 +586,12 @@ std::string get_device_id(const std::string& devname) return std::string(); } +int block_device_run_smartctl(const char *device, int timeout, + std::string *result) +{ + return -EOPNOTSUPP; +} + #else int get_block_device_size(int fd, int64_t *psize) { @@ -594,4 +642,10 @@ std::string get_device_id(const std::string& devname) return std::string(); } +int block_device_run_smartctl(const char *device, int timeout, + std::string *result) +{ + return -EOPNOTSUPP; +} + #endif diff --git a/src/common/blkdev.h b/src/common/blkdev.h index d15439d28b9..6e29d0eb8fb 100644 --- a/src/common/blkdev.h +++ b/src/common/blkdev.h @@ -30,6 +30,9 @@ 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); +extern int block_device_run_smartctl(const char *device, int timeout, + std::string *result); + // for VDO /// return an op fd for the sysfs stats dir, if this is a VDO device diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 891431fbbda..a82fc5cd0a8 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -48,7 +48,6 @@ #include "common/ceph_time.h" #include "common/version.h" #include "common/pick_address.h" -#include "common/SubProcess.h" #include "common/blkdev.h" #include "os/ObjectStore.h" @@ -6575,10 +6574,12 @@ void OSD::probe_smart(const string& only_devid, ostream& ss) } std::string result; - if (probe_smart_device(("/dev/" + dev).c_str(), smart_timeout, &result)) { + if (block_device_run_smartctl(("/dev/" + dev).c_str(), smart_timeout, + &result)) { dout(10) << "probe_smart_device failed for /dev/" << dev << dendl; //continue; - result = "{\"error\": \"smartctl failed\", \"dev\": \"" + dev + "\"}"; + result = "{\"error\": \"smartctl failed\", \"dev\": \"" + dev + + "\", \"smartctl_error\": \"" + result + "\"}"; } // TODO: change to read_or_throw? @@ -6592,44 +6593,6 @@ void OSD::probe_smart(const string& only_devid, ostream& ss) json_spirit::write(json_map, ss, json_spirit::pretty_print); } -int OSD::probe_smart_device(const char *device, int timeout, std::string *result) -{ - // when using --json, smartctl will report its errors in JSON format to stdout - SubProcessTimed smartctl( - "sudo", SubProcess::CLOSE, SubProcess::PIPE, SubProcess::CLOSE, - timeout); - smartctl.add_cmd_args( - "smartctl", - "-a", - //"-x", - "--json", - device, - NULL); - - int ret = smartctl.spawn(); - if (ret != 0) { - derr << "failed run smartctl: " << smartctl.err() << dendl; - return ret; - } - - bufferlist output; - ret = output.read_fd(smartctl.get_stdout(), 100*1024); - if (ret < 0) { - derr << "failed read from smartctl: " << cpp_strerror(-ret) << dendl; - } else { - ret = 0; - *result = output.to_str(); - dout(10) << "smartctl output is: " << *result << dendl; - } - - if (smartctl.join() != 0) { - derr << smartctl.err() << dendl; - return -EINVAL; - } - - return ret; -} - bool OSD::heartbeat_dispatch(Message *m) { dout(30) << "heartbeat_dispatch " << m << dendl; diff --git a/src/osd/OSD.h b/src/osd/OSD.h index 9dfa3411c5b..66211edaa7e 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -2279,7 +2279,6 @@ private: float get_osd_recovery_sleep(); void probe_smart(const string& devid, ostream& ss); - int probe_smart_device(const char *device, int timeout, std::string *result); public: static int peek_meta(ObjectStore *store, string& magic, -- 2.39.5