From dfe6dd96c22c3a2b0c9a54441da980f2c0fee9fa Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Sun, 6 Sep 2020 14:53:22 +0800 Subject: [PATCH] crimson/osd: add "ceph tell " support * add an abstract class of `PGCommand` for `ceph tell ` * add two sample implementations for the pg tell commands. - "query" - "mark_unfound_lost" Signed-off-by: Kefu Chai --- src/crimson/CMakeLists.txt | 1 + src/crimson/admin/pg_commands.cc | 159 +++++++++++++++++++++++++++++++ src/crimson/admin/pg_commands.h | 10 ++ src/crimson/osd/osd.cc | 6 +- 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/crimson/admin/pg_commands.cc create mode 100644 src/crimson/admin/pg_commands.h diff --git a/src/crimson/CMakeLists.txt b/src/crimson/CMakeLists.txt index 4a32540a12f79..35ff74498a5f6 100644 --- a/src/crimson/CMakeLists.txt +++ b/src/crimson/CMakeLists.txt @@ -14,6 +14,7 @@ set_target_properties(crimson::cflags PROPERTIES set(crimson_common_srcs admin/admin_socket.cc admin/osd_admin.cc + admin/pg_commands.cc common/assert.cc common/buffer_io.cc common/config_proxy.cc diff --git a/src/crimson/admin/pg_commands.cc b/src/crimson/admin/pg_commands.cc new file mode 100644 index 0000000000000..dacfd515db481 --- /dev/null +++ b/src/crimson/admin/pg_commands.cc @@ -0,0 +1,159 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "crimson/admin/pg_commands.h" + +#include +#include +#include + +#include +#include + +#include "crimson/admin/admin_socket.h" +#include "crimson/osd/osd.h" +#include "crimson/osd/pg.h" + + +using crimson::osd::OSD; +using crimson::osd::PG; +using namespace crimson::common; + + +namespace crimson::admin::pg { + +class PGCommand : public AdminSocketHook { +public: + // TODO: const correctness of osd + PGCommand(crimson::osd::OSD& osd, + std::string_view prefix, + std::string_view desc, + std::string_view help) + : AdminSocketHook{prefix, desc, help}, osd {osd} + {} + seastar::future call(const cmdmap_t& cmdmap, + std::string_view format, + ceph::bufferlist&& input) const final + { + // we have "ceph tell ". and it is the ceph cli's responsibility + // to add "pgid" to the cmd dict. as rados_pg_command() does not set it for + // us. moreover, and "pgid" is not listed in the command description, as user + // command format does not follow the convention of " [,...]" + // so we have to verify it on the server side. + std::string pgid_str; + pg_t pgid; + if (!cmd_getval(cmdmap, "pgid", pgid_str)) { + return seastar::make_ready_future( + tell_result_t{-EINVAL, "no pgid specified"}); + } else if (!pgid.parse(pgid_str.c_str())) { + return seastar::make_ready_future( + tell_result_t{-EINVAL, fmt::format("couldn't parse pgid '{}'", pgid_str)}); + } + // am i the primary for this pg? + const auto osdmap = osd.get_shard_services().get_osdmap(); + spg_t spg_id; + if (!osdmap->get_primary_shard(pgid, &spg_id)) { + return seastar::make_ready_future(tell_result_t{ + -ENOENT, fmt::format("pgid '{}' does not exist", pgid_str)}); + } + Ref pg = osd.get_pg(spg_id); + if (!pg) { + return seastar::make_ready_future(tell_result_t{ + -ENOENT, fmt::format("i don't have pgid '{}'", spg_id)}); + } + if (!pg->is_primary()) { + return seastar::make_ready_future(tell_result_t{ + -EAGAIN, fmt::format("not primary for pgid '{}'", spg_id)}); + } + return this->do_command(pg, cmdmap, format, std::move(input)); + } + +private: + virtual seastar::future + do_command(Ref pg, + const cmdmap_t& cmdmap, + std::string_view format, + ceph::bufferlist&& input) const = 0; + + OSD& osd; +}; + +class QueryCommand final : public PGCommand { +public: + // TODO: const correctness of osd + explicit QueryCommand(crimson::osd::OSD& osd) : + PGCommand{osd, + "query", + "", + "show details of a specific pg"} + {} +private: + seastar::future + do_command(Ref pg, + const cmdmap_t&, + std::string_view format, + ceph::bufferlist&& input) const final + { + std::unique_ptr f{Formatter::create(format, + "json-pretty", + "json-pretty")}; + f->open_object_section("pg"); + pg->dump_primary(f.get()); + f->close_section(); + return seastar::make_ready_future(std::move(f)); + } +}; + +class MarkUnfoundLostCommand final : public PGCommand { +public: + explicit MarkUnfoundLostCommand(crimson::osd::OSD& osd) : + PGCommand{osd, + "mark_unfound_lost", + "name=pgid,type=CephPgid,req=false" + " name=mulcmd,type=CephChoices,strings=revert|delete", + "mark all unfound objects in this pg as lost, either" + " removing or reverting to a prior version if one is" + " available"} + {} + seastar::future + do_command(Ref pg, + const cmdmap_t& cmdmap, + std::string_view, + ceph::bufferlist&&) const final + { + // what to do with the unfound object specifically. + std::string cmd; + int op = -1; + cmd_getval(cmdmap, "mulcmd", cmd); + if (cmd == "revert") { + op = pg_log_entry_t::LOST_REVERT; + } else if (cmd == "delete") { + op = pg_log_entry_t::LOST_DELETE; + } else { + return seastar::make_ready_future(tell_result_t{ + -EINVAL, "mode must be 'revert' or 'delete'; mark not yet implemented"}); + } + return pg->mark_unfound_lost(op).then([] { + // TODO + return seastar::make_ready_future(); + }); + } +}; + +} // namespace crimson::admin::pg + +namespace crimson::admin { + +template +std::unique_ptr make_asok_hook(Args&&... args) +{ + return std::make_unique(std::forward(args)...); +} + +template std::unique_ptr +make_asok_hook(crimson::osd::OSD& osd); + +template std::unique_ptr +make_asok_hook(crimson::osd::OSD& osd); + +} // namespace crimson::admin diff --git a/src/crimson/admin/pg_commands.h b/src/crimson/admin/pg_commands.h new file mode 100644 index 0000000000000..873b3c923aaf2 --- /dev/null +++ b/src/crimson/admin/pg_commands.h @@ -0,0 +1,10 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +#pragma once + +namespace crimson::admin::pg { + +class QueryCommand; +class MarkUnfoundLostCommand; + +} // namespace crimson::admin::pg diff --git a/src/crimson/osd/osd.cc b/src/crimson/osd/osd.cc index 38fddaa987c89..a170d7ccf7799 100644 --- a/src/crimson/osd/osd.cc +++ b/src/crimson/osd/osd.cc @@ -38,6 +38,7 @@ #include "osd/PeeringState.h" #include "crimson/admin/osd_admin.h" +#include "crimson/admin/pg_commands.h" #include "crimson/common/exception.h" #include "crimson/mon/MonClient.h" #include "crimson/net/Connection.h" @@ -432,7 +433,10 @@ seastar::future<> OSD::start_asok_admin() asok->register_command(make_asok_hook(*this)), asok->register_command(make_asok_hook(*this)), asok->register_command(make_asok_hook(std::as_const(*this))), - asok->register_command(make_asok_hook())); + asok->register_command(make_asok_hook()), + // PG commands + asok->register_command(make_asok_hook(*this)), + asok->register_command(make_asok_hook(*this))); }).then_unpack([] { return seastar::now(); }); -- 2.39.5