From: Radoslaw Zarzynski Date: Wed, 19 May 2021 12:30:23 +0000 (+0000) Subject: crimson/osd: implement the injectdataerr admin command. X-Git-Tag: v17.1.0~1850^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=e4ec9c53421b42fccaca74c917ef4a52a6ec64ae;p=ceph-ci.git crimson/osd: implement the injectdataerr admin command. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/crimson/admin/osd_admin.cc b/src/crimson/admin/osd_admin.cc index 21132b2f2b8..cbca5fead7e 100644 --- a/src/crimson/admin/osd_admin.cc +++ b/src/crimson/admin/osd_admin.cc @@ -20,6 +20,13 @@ using crimson::osd::OSD; using namespace crimson::common; +namespace { +seastar::logger& logger() +{ + return crimson::get_logger(ceph_subsys_osd); +} +} // namespace + namespace crimson::admin { using crimson::common::local_conf; @@ -265,4 +272,105 @@ private: }; template std::unique_ptr make_asok_hook(); + +static ghobject_t test_ops_get_object_name( + const OSDMap& osdmap, + const cmdmap_t& cmdmap) +{ + auto pool = [&] { + auto pool_arg = cmd_getval(cmdmap, "pool"); + if (!pool_arg) { + throw std::invalid_argument{"No 'pool' specified"}; + } + int64_t pool = osdmap.lookup_pg_pool_name(*pool_arg); + if (pool < 0 && std::isdigit((*pool_arg)[0])) { + pool = std::atoll(pool_arg->c_str()); + } + if (pool < 0) { + // the return type of `fmt::format` is `std::string` + using namespace fmt::literals; + throw std::invalid_argument{ + "Invalid pool '{}'"_format(*pool_arg) + }; + } + return pool; + }(); + + auto [ objname, nspace, raw_pg ] = [&] { + auto obj_arg = cmd_getval(cmdmap, "objname"); + if (!obj_arg) { + throw std::invalid_argument{"No 'objname' specified"}; + } + std::string objname, nspace; + if (std::size_t sep_pos = obj_arg->find_first_of('/'); + sep_pos != obj_arg->npos) { + nspace = obj_arg->substr(0, sep_pos); + objname = obj_arg->substr(sep_pos+1); + } else { + objname = *obj_arg; + } + pg_t raw_pg; + if (object_locator_t oloc(pool, nspace); + osdmap.object_locator_to_pg(object_t(objname), oloc, raw_pg) < 0) { + throw std::invalid_argument{"Invalid namespace/objname"}; + } + return std::make_tuple(std::move(objname), + std::move(nspace), + std::move(raw_pg)); + }(); + + auto shard_id = cmd_getval_or(cmdmap, + "shardid", + shard_id_t::NO_SHARD); + + return ghobject_t{ + hobject_t{ + object_t{objname}, std::string{}, CEPH_NOSNAP, raw_pg.ps(), pool, nspace + }, + ghobject_t::NO_GEN, + shard_id_t{static_cast(shard_id)} + }; +} + +// Usage: +// injectdataerr [namespace/] [shardid] +class InjectDataErrorHook : public AdminSocketHook { +public: + InjectDataErrorHook(crimson::osd::ShardServices& shard_services) : + AdminSocketHook("injectdataerr", + "name=pool,type=CephString " \ + "name=objname,type=CephObjectname " \ + "name=shardid,type=CephInt,req=false,range=0|255", + "inject data error to an object"), + shard_services(shard_services) { + } + + seastar::future call(const cmdmap_t& cmdmap, + std::string_view format, + ceph::bufferlist&& input) const final + { + ghobject_t obj; + try { + obj = test_ops_get_object_name(*shard_services.get_osdmap(), cmdmap); + } catch (const std::invalid_argument& e) { + logger().info("error during data error injection: {}", e.what()); + return seastar::make_ready_future(-EINVAL, + e.what()); + } + return shard_services.get_store().inject_data_error(obj).then([=] { + logger().info("successfully injected data error for obj={}", obj); + ceph::bufferlist bl; + bl.append("ok"sv); + return seastar::make_ready_future(0, + std::string{}, // no err + std::move(bl)); + }); + } + +private: + crimson::osd::ShardServices& shard_services; +}; +template std::unique_ptr make_asok_hook( + crimson::osd::ShardServices&); + } // namespace crimson::admin diff --git a/src/crimson/admin/osd_admin.h b/src/crimson/admin/osd_admin.h index f68bcf9b738..dccbca38d25 100644 --- a/src/crimson/admin/osd_admin.h +++ b/src/crimson/admin/osd_admin.h @@ -15,6 +15,7 @@ class SendBeaconHook; class DumpPGStateHistory; class SeastarMetricsHook; class DumpPerfCountersHook; +class InjectDataErrorHook; template std::unique_ptr make_asok_hook(Args&&... args); diff --git a/src/crimson/osd/osd.cc b/src/crimson/osd/osd.cc index 4a653011396..9303c6bcf9e 100644 --- a/src/crimson/osd/osd.cc +++ b/src/crimson/osd/osd.cc @@ -443,6 +443,7 @@ seastar::future<> OSD::start_asok_admin() asok->register_command(make_asok_hook(std::as_const(*this))), asok->register_command(make_asok_hook()), asok->register_command(make_asok_hook()), + asok->register_command(make_asok_hook(get_shard_services())), // PG commands asok->register_command(make_asok_hook(*this)), asok->register_command(make_asok_hook(*this)));