Refactor block_device_run_smartctl into a helper that returns JSON.
Signed-off-by: Sage Weil <sage@redhat.com>
//#include "common/debug.h"
#include "include/scope_guard.h"
#include "include/uuid.h"
+#include "include/stringify.h"
#include "blkdev.h"
+#include "json_spirit/json_spirit_reader.h"
+
int get_device_by_path(const char *path, char* partition, char* device,
size_t max)
{
return device_id;
}
+int block_device_get_metrics(const char *device, int timeout,
+ json_spirit::mValue *result)
+{
+ std::string s;
+ if (int r = block_device_run_smartctl(device, timeout, &s); r != 0) {
+ s = "{\"error\": \"smartctl failed\", \"dev\": \"";
+ s += device;
+ s += "\", \"smartctl_error_code\": " + stringify(r);
+ s += "\", \"smartctl_output\": \"" + s;
+ s += + "\"}";
+ }
+ if (json_spirit::read(s, *result)) {
+ return 0;
+ }
+ s = "{\"error\": \"smartctl returned invalid JSON\", \"dev\": \"";
+ s += device;
+ s += "\"}";
+ if (json_spirit::read(s, *result)) {
+ return 0;
+ }
+ return -EINVAL;
+}
+
int block_device_run_smartctl(const char *device, int timeout,
std::string *result)
{
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
#ifndef __CEPH_COMMON_BLKDEV_H
#define __CEPH_COMMON_BLKDEV_H
#include <set>
#include <string>
+#include "json_spirit/json_spirit_value.h"
enum blkdev_prop_t {
BLKDEV_PROP_DEV,
extern void get_dm_parents(const std::string& dev, std::set<std::string> *ls);
extern int block_device_run_smartctl(const char *device, int timeout,
std::string *result);
+extern int block_device_get_metrics(const char *device, int timeout,
+ json_spirit::mValue *result);
// for VDO
/// return an op fd for the sysfs stats dir, if this is a VDO device
"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;
+ if (block_device_get_metrics(("/dev/" + dev).c_str(), smart_timeout,
+ &smart_json)) {
+ dout(10) << "block_device_get_metrics failed for /dev/" << dev << dendl;
} else {
json_map[devid] = smart_json;
}
// == typedef std::map<std::string, mValue> mObject;
json_spirit::mObject json_map;
- json_spirit::mValue smart_json;
for (auto dev : devnames) {
// smartctl works only on physical devices; filter out any logical device
continue;
}
- 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;
- //continue;
- result = "{\"error\": \"smartctl failed\", \"dev\": \"" + dev +
- "\", \"smartctl_error\": \"" + result + "\"}";
- }
-
- // TODO: change to read_or_throw?
- if (!json_spirit::read(result, smart_json)) {
- derr << "smartctl JSON output of /dev/" + dev + " is invalid" << dendl;
- } else { //json is valid, assigning
- json_map[devid] = smart_json;
+ json_spirit::mValue smart_json;
+ if (block_device_get_metrics(("/dev/" + dev).c_str(), smart_timeout,
+ &smart_json)) {
+ dout(10) << "block_device_get_metrics failed for /dev/" << dev << dendl;
+ continue;
}
- // no need to result.clear() or clear smart_json
+ json_map[devid] = smart_json;
}
json_spirit::write(json_map, ss, json_spirit::pretty_print);
}