-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rbd: show info about mirror instance in image mirror status output
It is particularly useful when running multiple rbd-mirror instances in Active-Passive or Active-Active mode. Signed-off-by: Mykola Golub <mgolub@suse.com>
- Loading branch information
Showing
7 changed files
with
303 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | ||
// vim: ts=8 sw=2 smarttab | ||
|
||
#include "common/ceph_json.h" | ||
#include "common/errno.h" | ||
#include "include/rados/librados.hpp" | ||
#include "include/stringify.h" | ||
#include "tools/rbd/MirrorDaemonServiceInfo.h" | ||
|
||
#include <boost/scope_exit.hpp> | ||
#include <iostream> | ||
|
||
namespace rbd { | ||
|
||
int MirrorDaemonServiceInfo::init() { | ||
|
||
std::string cmd = "{\"prefix\": \"service dump\"}"; | ||
|
||
bufferlist in_bl; | ||
bufferlist out_bl; | ||
int r = librados::Rados(m_io_ctx).mgr_command(cmd, in_bl, &out_bl, nullptr); | ||
if (r < 0) { | ||
std::cerr << "rbd: failed to get service dump: " << cpp_strerror(r) | ||
<< std::endl; | ||
return r; | ||
} | ||
|
||
bool json_valid = false; | ||
json_spirit::mValue json_root; | ||
if (json_spirit::read(out_bl.to_str(), json_root)) { | ||
try { | ||
auto& json_obj = json_root.get_obj(); | ||
if (json_obj.count("services")) { | ||
auto &services = json_obj["services"].get_obj(); | ||
if (services.count("rbd-mirror")) { | ||
auto &mirror_service = services["rbd-mirror"].get_obj(); | ||
if (mirror_service.count("daemons")) { | ||
for (auto &it : mirror_service["daemons"].get_obj()) { | ||
if (it.second.type() != json_spirit::obj_type || | ||
!it.second.get_obj().count("metadata")) { | ||
continue; | ||
} | ||
auto &service_id = it.first; | ||
auto &daemon_metadata = it.second.get_obj()["metadata"].get_obj(); | ||
for (auto &iter : daemon_metadata) { | ||
if (iter.second.type() != json_spirit::str_type) { | ||
continue; | ||
} | ||
m_daemons_metadata[service_id][iter.first] = iter.second.get_str(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
json_valid = true; | ||
} catch (std::runtime_error&) { | ||
} | ||
} | ||
|
||
if (!json_valid) { | ||
std::cerr << "rbd: failed to parse service status" << std::endl; | ||
return -EBADMSG; | ||
} | ||
|
||
cmd = "{\"prefix\": \"service status\"}"; | ||
|
||
out_bl.clear(); | ||
r = librados::Rados(m_io_ctx).mgr_command(cmd, in_bl, &out_bl, nullptr); | ||
if (r < 0) { | ||
std::cerr << "rbd: failed to get service status: " << cpp_strerror(r) | ||
<< std::endl; | ||
return r; | ||
} | ||
|
||
json_valid = false; | ||
if (json_spirit::read(out_bl.to_str(), json_root)) { | ||
try { | ||
auto& json_obj = json_root.get_obj(); | ||
if (json_obj.count("rbd-mirror")) { | ||
auto &mirror_service = json_obj["rbd-mirror"].get_obj(); | ||
for (auto &it : mirror_service) { | ||
auto &service_id = it.first; | ||
auto &daemon = it.second.get_obj(); | ||
if (daemon.count("status") && | ||
daemon["status"].get_obj().count("json")) { | ||
auto& status_json_str = | ||
daemon["status"].get_obj()["json"].get_str(); | ||
json_spirit::mValue status_json_root; | ||
if (json_spirit::read(status_json_str, status_json_root)) { | ||
auto& status = status_json_root.get_obj(); | ||
auto iter = status.find(stringify(m_io_ctx.get_id())); | ||
if (iter != status.end() && | ||
iter->second.get_obj().count("instance_id")) { | ||
auto &instance_id = | ||
iter->second.get_obj()["instance_id"].get_str(); | ||
m_instance_id_to_service_id[instance_id] = service_id; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
json_valid = true; | ||
} catch (std::runtime_error&) { | ||
} | ||
} | ||
|
||
if (!json_valid) { | ||
std::cerr << "rbd: failed to parse service status" << std::endl; | ||
return -EBADMSG; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
std::string MirrorDaemonServiceInfo::get_description( | ||
const std::string &instance_id) const { | ||
if (!m_instance_id_to_service_id.count(instance_id)) { | ||
return {}; | ||
} | ||
|
||
auto service_id = m_instance_id_to_service_id.find(instance_id)->second; | ||
|
||
auto it = m_daemons_metadata.find(service_id); | ||
if (it == m_daemons_metadata.end()) { | ||
return service_id; | ||
} | ||
|
||
auto &metadata = it->second; | ||
auto iter = metadata.find("id"); | ||
std::string description = (iter != metadata.end()) ? | ||
iter->second : service_id; | ||
iter = metadata.find("hostname"); | ||
if (iter != metadata.end()) { | ||
description += " on " + iter->second; | ||
} | ||
|
||
return description; | ||
} | ||
|
||
void MirrorDaemonServiceInfo::dump( | ||
const std::string &instance_id, | ||
argument_types::Format::Formatter formatter) const { | ||
formatter->open_object_section("daemon_service"); | ||
BOOST_SCOPE_EXIT(formatter) { | ||
formatter->close_section(); | ||
} BOOST_SCOPE_EXIT_END; | ||
|
||
if (instance_id.empty() || | ||
!m_instance_id_to_service_id.count(instance_id)) { | ||
return; | ||
} | ||
|
||
auto service_id = m_instance_id_to_service_id.find(instance_id)->second; | ||
formatter->dump_string("service_id", service_id); | ||
formatter->dump_string("instance_id", instance_id); | ||
|
||
auto it = m_daemons_metadata.find(service_id); | ||
if (it == m_daemons_metadata.end()) { | ||
return; | ||
} | ||
|
||
auto &metadata = it->second; | ||
auto iter = metadata.find("id"); | ||
if (iter != metadata.end()) { | ||
formatter->dump_string("daemon_id", iter->second); | ||
} | ||
iter = metadata.find("hostname"); | ||
if (iter != metadata.end()) { | ||
formatter->dump_string("hostname", iter->second); | ||
} | ||
} | ||
|
||
} // namespace rbd | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | ||
// vim: ts=8 sw=2 smarttab | ||
|
||
#ifndef CEPH_RBD_MIRROR_DAEMON_SERVICE_INFO_H | ||
#define CEPH_RBD_MIRROR_DAEMON_SERVICE_INFO_H | ||
|
||
#include "tools/rbd/ArgumentTypes.h" | ||
|
||
#include <string> | ||
#include <map> | ||
|
||
namespace librados { class IoCtx; } | ||
|
||
namespace rbd { | ||
|
||
class MirrorDaemonServiceInfo { | ||
public: | ||
MirrorDaemonServiceInfo(librados::IoCtx &io_ctx) : m_io_ctx(io_ctx) { | ||
} | ||
|
||
int init(); | ||
|
||
std::string get_description(const std::string &instance_id) const; | ||
void dump(const std::string &instance_id, | ||
argument_types::Format::Formatter formatter) const; | ||
|
||
private: | ||
librados::IoCtx &m_io_ctx; | ||
std::map<std::string, std::string> m_instance_id_to_service_id; | ||
std::map<std::string, std::map<std::string, std::string>> m_daemons_metadata; | ||
}; | ||
|
||
} // namespace rbd | ||
|
||
#endif // CEPH_RBD_MIRROR_DAEMON_SERVICE_INFO_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.