]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
src/common/json: Modified JSON structures so they take advantage of ceph_json.h fully.
authorJonBailey1993 <jonathan.bailey1@ibm.com>
Mon, 25 Nov 2024 11:40:09 +0000 (11:40 +0000)
committerJon Bailey <jonathan.bailey1@ibm.com>
Tue, 7 Jan 2025 11:41:29 +0000 (11:41 +0000)
Also moved and renamed JSONStructures files so they structures are more easily identifiable and usable by others if desired.

Signed-off-by: Jon Bailey <jonathan.bailey1@ibm.com>
15 files changed:
src/common/CMakeLists.txt
src/common/io_exerciser/CMakeLists.txt
src/common/io_exerciser/JsonStructures.cc [deleted file]
src/common/io_exerciser/JsonStructures.h [deleted file]
src/common/io_exerciser/RadosIo.cc
src/common/json/BalancerStructures.cc [new file with mode: 0644]
src/common/json/BalancerStructures.h [new file with mode: 0644]
src/common/json/CMakeLists.txt [new file with mode: 0644]
src/common/json/ConfigStructures.cc [new file with mode: 0644]
src/common/json/ConfigStructures.h [new file with mode: 0644]
src/common/json/OSDStructures.cc [new file with mode: 0644]
src/common/json/OSDStructures.h [new file with mode: 0644]
src/test/osd/CMakeLists.txt
src/test/osd/ceph_test_rados_io_sequence.cc
src/test/osd/ceph_test_rados_io_sequence.h

index ea3cce166092a6a31604708840c28fe06a6f001d..c607839a8d2598020ad66ec2de21e481555ec9c3 100644 (file)
@@ -13,6 +13,7 @@ if(WIN32)
 endif()
 
 add_subdirectory(io_exerciser)
+add_subdirectory(json)
 add_subdirectory(options)
 
 set(common_srcs
index ccad61b57a215ad437787862d8a8c2f409f8b91d..ab2e64fc22230930be9e2ec819ae373819069706 100644 (file)
@@ -5,11 +5,11 @@ add_library(object_io_exerciser STATIC
   Model.cc
   ObjectModel.cc
   RadosIo.cc
-  JsonStructures.cc
   EcIoSequence.cc
 )
 
 target_link_libraries(object_io_exerciser
-  librados 
+  librados
   global
+  json_structures
 )
\ No newline at end of file
diff --git a/src/common/io_exerciser/JsonStructures.cc b/src/common/io_exerciser/JsonStructures.cc
deleted file mode 100644 (file)
index c330484..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-#include "JsonStructures.h"
-
-#include "OpType.h"
-#include "common/ceph_json.h"
-
-using namespace ceph::io_exerciser::json;
-
-JSONStructure::JSONStructure(std::shared_ptr<ceph::Formatter> formatter)
-    : formatter(formatter) {}
-
-std::string JSONStructure::encode_json() {
-  oss.clear();
-
-  dump();
-  formatter->flush(oss);
-  return oss.str();
-}
-
-OSDMapRequest::OSDMapRequest(const std::string& pool_name,
-                             const std::string& object,
-                             const std::string& nspace,
-                             std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter),
-      pool(pool_name),
-      object(object),
-      nspace(nspace) {}
-
-OSDMapRequest::OSDMapRequest(std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void OSDMapRequest::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-  JSONDecoder::decode_json("pool", pool, obj);
-  JSONDecoder::decode_json("object", object, obj);
-  JSONDecoder::decode_json("nspace", nspace, obj);
-  JSONDecoder::decode_json("format", format, obj);
-}
-
-void OSDMapRequest::dump() const {
-  formatter->open_object_section("OSDMapRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  ::encode_json("pool", pool, formatter.get());
-  ::encode_json("object", object, formatter.get());
-  ::encode_json("nspace", nspace, formatter.get());
-  ::encode_json("format", format, formatter.get());
-  formatter->close_section();
-}
-
-OSDMapReply::OSDMapReply(std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void OSDMapReply::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("epoch", epoch, obj);
-  JSONDecoder::decode_json("pool", pool, obj);
-  JSONDecoder::decode_json("pool_id", pool_id, obj);
-  JSONDecoder::decode_json("objname", objname, obj);
-  JSONDecoder::decode_json("raw_pgid", raw_pgid, obj);
-  JSONDecoder::decode_json("pgid", pgid, obj);
-  JSONDecoder::decode_json("up", up, obj);
-  JSONDecoder::decode_json("up_primary", up_primary, obj);
-  JSONDecoder::decode_json("acting", acting, obj);
-  JSONDecoder::decode_json("acting_primary", acting_primary, obj);
-}
-
-void OSDMapReply::dump() const {
-  formatter->open_object_section("OSDMapReply");
-  ::encode_json("epoch", epoch, formatter.get());
-  ::encode_json("pool", pool, formatter.get());
-  ::encode_json("pool_id", pool_id, formatter.get());
-  ::encode_json("objname", objname, formatter.get());
-  ::encode_json("raw_pgid", raw_pgid, formatter.get());
-  ::encode_json("pgid", pgid, formatter.get());
-  ::encode_json("up", up, formatter.get());
-  ::encode_json("up_primary", up_primary, formatter.get());
-  ::encode_json("acting", acting, formatter.get());
-  ::encode_json("acting_primary", acting_primary, formatter.get());
-  formatter->close_section();
-}
-
-ceph::io_exerciser::json::OSDPoolGetRequest ::OSDPoolGetRequest(
-    const std::string& pool_name, std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter), pool(pool_name) {}
-
-ceph::io_exerciser::json::OSDPoolGetRequest ::OSDPoolGetRequest(
-    JSONObj* obj, std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {
-  ceph::io_exerciser::json::OSDPoolGetRequest::decode_json(obj);
-}
-
-void ceph::io_exerciser::json::OSDPoolGetRequest::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-  JSONDecoder::decode_json("pool", pool, obj);
-  JSONDecoder::decode_json("var", var, obj);
-  JSONDecoder::decode_json("format", format, obj);
-}
-
-void ceph::io_exerciser::json::OSDPoolGetRequest::dump() const {
-  formatter->open_object_section("OSDPoolGetRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  ::encode_json("pool", pool, formatter.get());
-  ::encode_json("var", var, formatter.get());
-  ::encode_json("format", format, formatter.get());
-  formatter->close_section();
-}
-
-ceph::io_exerciser::json::OSDPoolGetReply ::OSDPoolGetReply(
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void ceph::io_exerciser::json::OSDPoolGetReply::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("erasure_code_profile", erasure_code_profile, obj);
-}
-
-void ceph::io_exerciser::json::OSDPoolGetReply::dump() const {
-  formatter->open_object_section("OSDPoolGetReply");
-  ::encode_json("erasure_code_profile", erasure_code_profile, formatter.get());
-  formatter->close_section();
-}
-
-ceph::io_exerciser::json::OSDECProfileGetRequest ::OSDECProfileGetRequest(
-    const std::string& profile_name, std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter), name(profile_name) {}
-
-ceph::io_exerciser::json::OSDECProfileGetRequest ::OSDECProfileGetRequest(
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void ceph::io_exerciser::json::OSDECProfileGetRequest::decode_json(
-    JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-  JSONDecoder::decode_json("name", name, obj);
-  JSONDecoder::decode_json("format", format, obj);
-}
-
-void ceph::io_exerciser::json::OSDECProfileGetRequest::dump() const {
-  formatter->open_object_section("OSDECProfileGetRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  ::encode_json("name", name, formatter.get());
-  ::encode_json("format", format, formatter.get());
-  formatter->close_section();
-}
-
-ceph::io_exerciser::json::OSDECProfileGetReply ::OSDECProfileGetReply(
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void ceph::io_exerciser::json::OSDECProfileGetReply::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("crush-device-class", crush_device_class, obj);
-  JSONDecoder::decode_json("crush-failure-domain", crush_failure_domain, obj);
-  JSONDecoder::decode_json("crush-num-failure-domains",
-                           crush_num_failure_domains, obj);
-  JSONDecoder::decode_json("crush-osds-per-failure-domain",
-                           crush_osds_per_failure_domain, obj);
-  JSONDecoder::decode_json("crush-root", crush_root, obj);
-  JSONDecoder::decode_json("jerasure-per-chunk-alignment",
-                           jerasure_per_chunk_alignment, obj);
-  JSONDecoder::decode_json("k", k, obj);
-  JSONDecoder::decode_json("m", m, obj);
-  JSONDecoder::decode_json("plugin", plugin, obj);
-  JSONDecoder::decode_json("technique", technique, obj);
-  JSONDecoder::decode_json("w", w, obj);
-}
-
-void ceph::io_exerciser::json::OSDECProfileGetReply::dump() const {
-  formatter->open_object_section("OSDECProfileGetReply");
-  ::encode_json("crush-device-class", crush_device_class, formatter.get());
-  ::encode_json("crush-failure-domain", crush_failure_domain, formatter.get());
-  ::encode_json("crush-num-failure-domains", crush_num_failure_domains,
-                formatter.get());
-  ::encode_json("crush-osds-per-failure-domain", crush_osds_per_failure_domain,
-                formatter.get());
-  ::encode_json("crush-root", crush_root, formatter.get());
-  ::encode_json("jerasure-per-chunk-alignment", jerasure_per_chunk_alignment,
-                formatter.get());
-  ::encode_json("k", k, formatter.get());
-  ::encode_json("m", m, formatter.get());
-  ::encode_json("plugin", plugin, formatter.get());
-  ::encode_json("technique", technique, formatter.get());
-  ::encode_json("w", w, formatter.get());
-  formatter->close_section();
-}
-
-ceph::io_exerciser::json::OSDECProfileSetRequest ::OSDECProfileSetRequest(
-    const std::string& name, const std::vector<std::string>& profile,
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter), name(name), profile(profile) {}
-
-OSDECProfileSetRequest ::OSDECProfileSetRequest(
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void OSDECProfileSetRequest::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-  JSONDecoder::decode_json("name", name, obj);
-  JSONDecoder::decode_json("profile", profile, obj);
-}
-
-void OSDECProfileSetRequest::dump() const {
-  formatter->open_object_section("OSDECProfileSetRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  ::encode_json("name", name, formatter.get());
-  ::encode_json("profile", profile, formatter.get());
-  formatter->close_section();
-}
-
-OSDECPoolCreateRequest::OSDECPoolCreateRequest(
-    const std::string& pool, const std::string& erasure_code_profile,
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter),
-      pool(pool),
-      erasure_code_profile(erasure_code_profile) {}
-
-OSDECPoolCreateRequest ::OSDECPoolCreateRequest(
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void OSDECPoolCreateRequest::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-  JSONDecoder::decode_json("pool", pool, obj);
-  JSONDecoder::decode_json("pool_type", pool_type, obj);
-  JSONDecoder::decode_json("pg_num", pg_num, obj);
-  JSONDecoder::decode_json("pgp_num", pgp_num, obj);
-  JSONDecoder::decode_json("erasure_code_profile", erasure_code_profile, obj);
-}
-
-void OSDECPoolCreateRequest::dump() const {
-  formatter->open_object_section("OSDECPoolCreateRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  ::encode_json("pool", pool, formatter.get());
-  ::encode_json("pool_type", pool_type, formatter.get());
-  ::encode_json("pg_num", pg_num, formatter.get());
-  ::encode_json("pgp_num", pgp_num, formatter.get());
-  ::encode_json("erasure_code_profile", erasure_code_profile, formatter.get());
-  formatter->close_section();
-}
-
-OSDSetRequest::OSDSetRequest(const std::string& key,
-                             const std::optional<bool>& yes_i_really_mean_it,
-                             std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter),
-      key(key),
-      yes_i_really_mean_it(yes_i_really_mean_it) {}
-
-OSDSetRequest::OSDSetRequest(std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void OSDSetRequest::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-  JSONDecoder::decode_json("key", key, obj);
-  JSONDecoder::decode_json("yes_i_really_mean_it", yes_i_really_mean_it, obj);
-}
-
-void OSDSetRequest::dump() const {
-  formatter->open_object_section("OSDSetRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  ::encode_json("key", key, formatter.get());
-  ::encode_json("yes_i_really_mean_it", yes_i_really_mean_it, formatter.get());
-  formatter->close_section();
-}
-
-BalancerOffRequest::BalancerOffRequest(
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void ceph::io_exerciser::json::BalancerOffRequest::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-}
-
-void BalancerOffRequest::dump() const {
-  formatter->open_object_section("BalancerOffRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  formatter->close_section();
-}
-
-BalancerStatusRequest ::BalancerStatusRequest(
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void ceph::io_exerciser::json::BalancerStatusRequest::decode_json(
-    JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-}
-
-void BalancerStatusRequest::dump() const {
-  formatter->open_object_section("BalancerStatusRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  formatter->close_section();
-}
-
-BalancerStatusReply::BalancerStatusReply(
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void BalancerStatusReply::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("active", active, obj);
-  JSONDecoder::decode_json("last_optimization_duration",
-                           last_optimization_duration, obj);
-  JSONDecoder::decode_json("last_optimization_started",
-                           last_optimization_started, obj);
-  JSONDecoder::decode_json("mode", mode, obj);
-  JSONDecoder::decode_json("no_optimization_needed", no_optimization_needed,
-                           obj);
-  JSONDecoder::decode_json("optimize_result", optimize_result, obj);
-}
-
-void BalancerStatusReply::dump() const {
-  formatter->open_object_section("BalancerStatusReply");
-  ::encode_json("active", active, formatter.get());
-  ::encode_json("last_optimization_duration", last_optimization_duration,
-                formatter.get());
-  ::encode_json("last_optimization_started", last_optimization_started,
-                formatter.get());
-  ::encode_json("mode", mode, formatter.get());
-  ::encode_json("no_optimization_needed", no_optimization_needed,
-                formatter.get());
-  ::encode_json("optimize_result", optimize_result, formatter.get());
-  formatter->close_section();
-}
-
-ConfigSetRequest::ConfigSetRequest(const std::string& who,
-                                   const std::string& name,
-                                   const std::string& value,
-                                   const std::optional<bool>& force,
-                                   std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter),
-      who(who),
-      name(name),
-      value(value),
-      force(force) {}
-
-ConfigSetRequest::ConfigSetRequest(std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void ConfigSetRequest::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-  JSONDecoder::decode_json("who", who, obj);
-  JSONDecoder::decode_json("name", name, obj);
-  JSONDecoder::decode_json("value", value, obj);
-  JSONDecoder::decode_json("force", force, obj);
-}
-
-void ConfigSetRequest::dump() const {
-  formatter->open_object_section("ConfigSetRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  ::encode_json("who", who, formatter.get());
-  ::encode_json("name", name, formatter.get());
-  ::encode_json("value", value, formatter.get());
-  ::encode_json("force", force, formatter.get());
-  formatter->close_section();
-}
-
-InjectECErrorRequest::InjectECErrorRequest(
-    InjectOpType injectOpType, const std::string& pool,
-    const std::string& objname, int shardid,
-    const std::optional<uint64_t>& type, const std::optional<uint64_t>& when,
-    const std::optional<uint64_t>& duration,
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter),
-      pool(pool),
-      objname(objname),
-      shardid(shardid),
-      type(type),
-      when(when),
-      duration(duration) {
-  switch (injectOpType) {
-    case InjectOpType::ReadEIO:
-      [[fallthrough]];
-    case InjectOpType::ReadMissingShard:
-      prefix = "injectecreaderr";
-      break;
-    case InjectOpType::WriteFailAndRollback:
-      [[fallthrough]];
-    case InjectOpType::WriteOSDAbort:
-      prefix = "injectecwriteerr";
-      break;
-    default:
-      ceph_abort_msg("Invalid OP type to inject");
-  }
-}
-
-InjectECErrorRequest ::InjectECErrorRequest(
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void InjectECErrorRequest::dump() const {
-  formatter->open_object_section("InjectECErrorRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  ::encode_json("pool", pool, formatter.get());
-  ::encode_json("objname", objname, formatter.get());
-  ::encode_json("shardid", shardid, formatter.get());
-  ::encode_json("type", type, formatter.get());
-  ::encode_json("when", when, formatter.get());
-  ::encode_json("duration", duration, formatter.get());
-  formatter->close_section();
-}
-
-void InjectECErrorRequest::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-  JSONDecoder::decode_json("pool", pool, obj);
-  JSONDecoder::decode_json("objname", objname, obj);
-  JSONDecoder::decode_json("shardid", shardid, obj);
-  JSONDecoder::decode_json("type", type, obj);
-  JSONDecoder::decode_json("when", when, obj);
-  JSONDecoder::decode_json("duration", duration, obj);
-}
-
-InjectECClearErrorRequest::InjectECClearErrorRequest(
-    InjectOpType injectOpType, const std::string& pool,
-    const std::string& objname, int shardid,
-    const std::optional<uint64_t>& type,
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter),
-      pool(pool),
-      objname(objname),
-      shardid(shardid),
-      type(type) {
-  switch (injectOpType) {
-    case InjectOpType::ReadEIO:
-      [[fallthrough]];
-    case InjectOpType::ReadMissingShard:
-      prefix = "injectecclearreaderr";
-      break;
-    case InjectOpType::WriteFailAndRollback:
-      [[fallthrough]];
-    case InjectOpType::WriteOSDAbort:
-      prefix = "injectecclearwriteerr";
-      break;
-    default:
-      ceph_abort_msg("Invalid OP type to inject");
-  }
-}
-
-InjectECClearErrorRequest ::InjectECClearErrorRequest(
-    std::shared_ptr<ceph::Formatter> formatter)
-    : JSONStructure(formatter) {}
-
-void InjectECClearErrorRequest::dump() const {
-  formatter->open_object_section("InjectECErrorRequest");
-  ::encode_json("prefix", prefix, formatter.get());
-  ::encode_json("pool", pool, formatter.get());
-  ::encode_json("objname", objname, formatter.get());
-  ::encode_json("shardid", shardid, formatter.get());
-  ::encode_json("type", type, formatter.get());
-  formatter->close_section();
-}
-
-void InjectECClearErrorRequest::decode_json(JSONObj* obj) {
-  JSONDecoder::decode_json("prefix", prefix, obj);
-  JSONDecoder::decode_json("pool", pool, obj);
-  JSONDecoder::decode_json("objname", objname, obj);
-  JSONDecoder::decode_json("shardid", shardid, obj);
-  JSONDecoder::decode_json("type", type, obj);
-}
\ No newline at end of file
diff --git a/src/common/io_exerciser/JsonStructures.h b/src/common/io_exerciser/JsonStructures.h
deleted file mode 100644 (file)
index 995b980..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "OpType.h"
-#include "include/types.h"
-
-/* Overview
- *
- * class JSONStructure
- *   Stores elements of a JSONStructure in C++ friendly format so they do not
- *   have to be parsed from strings. Includes encode and decode functions to
- *   provide easy ways to convert from c++ structures to json structures.
- *
- */
-
-class JSONObj;
-
-namespace ceph {
-namespace io_exerciser {
-namespace json {
-class JSONStructure {
- public:
-  JSONStructure(std::shared_ptr<Formatter> formatter =
-                    std::make_shared<JSONFormatter>(false));
-
-  virtual ~JSONStructure() = default;
-
-  std::string encode_json();
-  virtual void decode_json(JSONObj* obj) = 0;
-  virtual void dump() const = 0;
-
- protected:
-  std::shared_ptr<Formatter> formatter;
-
- private:
-  std::ostringstream oss;
-};
-
-class OSDMapRequest : public JSONStructure {
- public:
-  OSDMapRequest(const std::string& pool_name, const std::string& object,
-                const std::string& nspace,
-                std::shared_ptr<Formatter> formatter =
-                    std::make_shared<JSONFormatter>(false));
-  OSDMapRequest(std::shared_ptr<Formatter> formatter =
-                    std::make_shared<JSONFormatter>(false));
-
-  std::string prefix = "osd map";
-  std::string pool;
-  std::string object;
-  std::string nspace;
-  std::string format = "json";
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class OSDMapReply : public JSONStructure {
- public:
-  OSDMapReply(std::shared_ptr<Formatter> formatter =
-                  std::make_shared<JSONFormatter>(false));
-
-  epoch_t epoch;
-  std::string pool;
-  uint64_t pool_id;
-  std::string objname;
-  std::string raw_pgid;
-  std::string pgid;
-  std::vector<int> up;
-  int up_primary;
-  std::vector<int> acting;
-  int acting_primary;
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class OSDPoolGetRequest : public JSONStructure {
- public:
-  OSDPoolGetRequest(const std::string& pool_name,
-                    std::shared_ptr<ceph::Formatter> formatter =
-                        std::make_shared<JSONFormatter>(false));
-  OSDPoolGetRequest(JSONObj* obj, std::shared_ptr<ceph::Formatter> formatter =
-                                      std::make_shared<JSONFormatter>(false));
-
-  std::string prefix = "osd pool get";
-  std::string pool;
-  std::string var = "erasure_code_profile";
-  std::string format = "json";
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class OSDPoolGetReply : public JSONStructure {
- public:
-  OSDPoolGetReply(std::shared_ptr<ceph::Formatter> formatter =
-                      std::make_shared<JSONFormatter>(false));
-
-  std::string erasure_code_profile;
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class OSDECProfileGetRequest : public JSONStructure {
- public:
-  OSDECProfileGetRequest(const std::string& profile_name,
-                         std::shared_ptr<ceph::Formatter> formatter =
-                             std::make_shared<JSONFormatter>(false));
-  OSDECProfileGetRequest(std::shared_ptr<ceph::Formatter> formatter =
-                             std::make_shared<JSONFormatter>(false));
-
-  std::string prefix = "osd pool get";
-  std::string name;
-  std::string format = "json";
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class OSDECProfileGetReply : public JSONStructure {
- public:
-  OSDECProfileGetReply(std::shared_ptr<ceph::Formatter> formatter =
-                           std::make_shared<JSONFormatter>(false));
-
-  std::string crush_device_class;
-  std::string crush_failure_domain;
-  int crush_num_failure_domains;
-  int crush_osds_per_failure_domain;
-  std::string crush_root;
-  bool jerasure_per_chunk_alignment;
-  int k;
-  int m;
-  std::string plugin;
-  std::string technique;
-  std::string w;
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class OSDECProfileSetRequest : public JSONStructure {
- public:
-  OSDECProfileSetRequest(const std::string& name,
-                         const std::vector<std::string>& profile,
-                         std::shared_ptr<Formatter> formatter =
-                             std::make_shared<JSONFormatter>(false));
-  OSDECProfileSetRequest(std::shared_ptr<Formatter> formatter =
-                             std::make_shared<JSONFormatter>(false));
-
-  std::string prefix = "osd erasure-code-profile set";
-  std::string name;
-  std::vector<std::string> profile;
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class OSDECPoolCreateRequest : public JSONStructure {
- public:
-  OSDECPoolCreateRequest(const std::string& pool,
-                         const std::string& erasure_code_profile,
-                         std::shared_ptr<Formatter> formatter =
-                             std::make_shared<JSONFormatter>(false));
-  OSDECPoolCreateRequest(std::shared_ptr<Formatter> formatter =
-                             std::make_shared<JSONFormatter>(false));
-
-  std::string prefix = "osd pool create";
-  std::string pool;
-  std::string pool_type = "erasure";
-  int pg_num = 8;
-  int pgp_num = 8;
-  std::string erasure_code_profile;
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class OSDSetRequest : public JSONStructure {
- public:
-  OSDSetRequest(const std::string& key,
-                const std::optional<bool>& yes_i_really_mean_it = std::nullopt,
-                std::shared_ptr<Formatter> formatter =
-                    std::make_shared<JSONFormatter>(false));
-  OSDSetRequest(std::shared_ptr<Formatter> formatter =
-                    std::make_shared<JSONFormatter>(false));
-
-  std::string prefix = "osd set";
-  std::string key;
-  std::optional<bool> yes_i_really_mean_it = std::nullopt;
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class BalancerOffRequest : public JSONStructure {
- public:
-  BalancerOffRequest(std::shared_ptr<Formatter> formatter =
-                         std::make_shared<JSONFormatter>(false));
-
-  std::string prefix = "balancer off";
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class BalancerStatusRequest : public JSONStructure {
- public:
-  BalancerStatusRequest(std::shared_ptr<Formatter> formatter =
-                            std::make_shared<JSONFormatter>(false));
-
-  std::string prefix = "balancer status";
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class BalancerStatusReply : public JSONStructure {
- public:
-  BalancerStatusReply(std::shared_ptr<Formatter> formatter =
-                          std::make_shared<JSONFormatter>(false));
-
-  bool active;
-  std::string last_optimization_duration;
-  std::string last_optimization_started;
-  std::string mode;
-  bool no_optimization_needed;
-  std::string optimize_result;
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class ConfigSetRequest : public JSONStructure {
- public:
-  ConfigSetRequest(const std::string& who, const std::string& name,
-                   const std::string& value,
-                   const std::optional<bool>& force = std::nullopt,
-                   std::shared_ptr<Formatter> formatter =
-                       std::make_shared<JSONFormatter>(false));
-  ConfigSetRequest(std::shared_ptr<Formatter> formatter =
-                       std::make_shared<JSONFormatter>(false));
-
-  std::string prefix = "config set";
-  std::string who;
-  std::string name;
-  std::string value;
-  std::optional<bool> force;
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class InjectECErrorRequest : public JSONStructure {
- public:
-  InjectECErrorRequest(InjectOpType injectOpType, const std::string& pool,
-                       const std::string& objname, int shardid,
-                       const std::optional<uint64_t>& type,
-                       const std::optional<uint64_t>& when,
-                       const std::optional<uint64_t>& duration,
-                       std::shared_ptr<Formatter> formatter =
-                           std::make_shared<JSONFormatter>(false));
-  InjectECErrorRequest(std::shared_ptr<Formatter> formatter =
-                           std::make_shared<JSONFormatter>(false));
-
-  std::string prefix;
-  std::string pool;
-  std::string objname;
-  int shardid;
-  std::optional<uint64_t> type;
-  std::optional<uint64_t> when;
-  std::optional<uint64_t> duration;
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-
-class InjectECClearErrorRequest : public JSONStructure {
- public:
-  InjectECClearErrorRequest(InjectOpType injectOpType, const std::string& pool,
-                            const std::string& objname, int shardid,
-                            const std::optional<uint64_t>& type,
-                            std::shared_ptr<Formatter> formatter =
-                                std::make_shared<JSONFormatter>(false));
-
-  InjectECClearErrorRequest(std::shared_ptr<Formatter> formatter =
-                                std::make_shared<JSONFormatter>(false));
-
-  std::string prefix;
-  std::string pool;
-  std::string objname;
-  int shardid;
-  std::optional<uint64_t> type;
-
-  void decode_json(JSONObj* obj) override;
-  void dump() const override;
-};
-}  // namespace json
-}  // namespace io_exerciser
-}  // namespace ceph
\ No newline at end of file
index 048622ccde09889d4bad425d2f3fc48d64d17734..4451900b7bb47462f08d2710bbf6ac90b789ed07 100644 (file)
@@ -6,8 +6,8 @@
 #include <ranges>
 
 #include "DataGenerator.h"
-#include "JsonStructures.h"
 #include "common/ceph_json.h"
+#include "common/json/OSDStructures.h"
 
 using RadosIo = ceph::io_exerciser::RadosIo;
 
@@ -292,47 +292,51 @@ void RadosIo::applyReadWriteOp(IoOp& op) {
 
 void RadosIo::applyInjectOp(IoOp& op) {
   bufferlist osdmap_inbl, inject_inbl, osdmap_outbl, inject_outbl;
-  auto formatter = std::make_shared<JSONFormatter>(false);
+  auto formatter = std::make_unique<JSONFormatter>(false);
+  std::ostringstream oss;
 
   int osd = -1;
   std::vector<int> shard_order;
 
-  ceph::io_exerciser::json::OSDMapRequest osdMapRequest(pool, get_oid(), "",
-                                                        formatter);
-  int rc = rados.mon_command(osdMapRequest.encode_json(), osdmap_inbl,
-                             &osdmap_outbl, nullptr);
+  ceph::messaging::osd::OSDMapRequest osdMapRequest{pool, get_oid(), ""};
+  encode_json("OSDMapRequest", osdMapRequest, formatter.get());
+  formatter->flush(oss);
+  int rc = rados.mon_command(oss.str(), osdmap_inbl, &osdmap_outbl, nullptr);
   ceph_assert(rc == 0);
 
   JSONParser p;
   bool success = p.parse(osdmap_outbl.c_str(), osdmap_outbl.length());
   ceph_assert(success);
 
-  ceph::io_exerciser::json::OSDMapReply reply{formatter};
+  ceph::messaging::osd::OSDMapReply reply;
   reply.decode_json(&p);
 
   osd = reply.acting_primary;
   shard_order = reply.acting;
 
-  InjectOpType injectOpType;
-
   switch (op.getOpType()) {
     case OpType::InjectReadError: {
       InjectReadErrorOp& errorOp = static_cast<InjectReadErrorOp&>(op);
 
       if (errorOp.type == 0) {
-        injectOpType = InjectOpType::ReadEIO;
+        ceph::messaging::osd::InjectECErrorRequest<InjectOpType::ReadEIO>
+            injectErrorRequest{pool,         oid,          errorOp.shard,
+                               errorOp.type, errorOp.when, errorOp.duration};
+        encode_json("InjectECErrorRequest", injectErrorRequest,
+                    formatter.get());
       } else if (errorOp.type == 1) {
-        injectOpType = InjectOpType::ReadMissingShard;
+        ceph::messaging::osd::InjectECErrorRequest<
+            InjectOpType::ReadMissingShard>
+            injectErrorRequest{pool,         oid,          errorOp.shard,
+                               errorOp.type, errorOp.when, errorOp.duration};
+        encode_json("InjectECErrorRequest", injectErrorRequest,
+                    formatter.get());
       } else {
         ceph_abort_msg("Unsupported inject type");
       }
-
-      ceph::io_exerciser::json::InjectECErrorRequest injectErrorRequest(
-          injectOpType, pool, oid, errorOp.shard, errorOp.type, errorOp.when,
-          errorOp.duration, formatter);
-
-      int rc = rados.osd_command(osd, injectErrorRequest.encode_json(),
-                                 inject_inbl, &inject_outbl, nullptr);
+      formatter->flush(oss);
+      int rc = rados.osd_command(osd, oss.str(), inject_inbl, &inject_outbl,
+                                 nullptr);
       ceph_assert(rc == 0);
       break;
     }
@@ -340,9 +344,18 @@ void RadosIo::applyInjectOp(IoOp& op) {
       InjectWriteErrorOp& errorOp = static_cast<InjectWriteErrorOp&>(op);
 
       if (errorOp.type == 0) {
-        injectOpType = InjectOpType::WriteFailAndRollback;
+        ceph::messaging::osd::InjectECErrorRequest<
+            InjectOpType::WriteFailAndRollback>
+            injectErrorRequest{pool,         oid,          errorOp.shard,
+                               errorOp.type, errorOp.when, errorOp.duration};
+        encode_json("InjectECErrorRequest", injectErrorRequest,
+                    formatter.get());
       } else if (errorOp.type == 3) {
-        injectOpType = InjectOpType::WriteOSDAbort;
+        ceph::messaging::osd::InjectECErrorRequest<InjectOpType::WriteOSDAbort>
+            injectErrorRequest{pool,         oid,          errorOp.shard,
+                               errorOp.type, errorOp.when, errorOp.duration};
+        encode_json("InjectECErrorRequest", injectErrorRequest,
+                    formatter.get());
 
         // This inject is sent directly to the shard we want to inject the error
         // on
@@ -351,12 +364,9 @@ void RadosIo::applyInjectOp(IoOp& op) {
         ceph_abort("Unsupported inject type");
       }
 
-      ceph::io_exerciser::json::InjectECErrorRequest injectErrorRequest(
-          injectOpType, pool, oid, errorOp.shard, errorOp.type, errorOp.when,
-          errorOp.duration, formatter);
-
-      int rc = rados.osd_command(osd, injectErrorRequest.encode_json(),
-                                 inject_inbl, &inject_outbl, nullptr);
+      formatter->flush(oss);
+      int rc = rados.osd_command(osd, oss.str(), inject_inbl, &inject_outbl,
+                                 nullptr);
       ceph_assert(rc == 0);
       break;
     }
@@ -365,18 +375,23 @@ void RadosIo::applyInjectOp(IoOp& op) {
           static_cast<ClearReadErrorInjectOp&>(op);
 
       if (errorOp.type == 0) {
-        injectOpType = InjectOpType::ReadEIO;
+        ceph::messaging::osd::InjectECClearErrorRequest<InjectOpType::ReadEIO>
+            clearErrorInject{pool, oid, errorOp.shard, errorOp.type};
+        encode_json("InjectECClearErrorRequest", clearErrorInject,
+                    formatter.get());
       } else if (errorOp.type == 1) {
-        injectOpType = InjectOpType::ReadMissingShard;
+        ceph::messaging::osd::InjectECClearErrorRequest<
+            InjectOpType::ReadMissingShard>
+            clearErrorInject{pool, oid, errorOp.shard, errorOp.type};
+        encode_json("InjectECClearErrorRequest", clearErrorInject,
+                    formatter.get());
       } else {
         ceph_abort("Unsupported inject type");
       }
 
-      ceph::io_exerciser::json::InjectECClearErrorRequest clearErrorInject(
-          injectOpType, pool, oid, errorOp.shard, errorOp.type);
-
-      int rc = rados.osd_command(osd, clearErrorInject.encode_json(),
-                                 inject_inbl, &inject_outbl, nullptr);
+      formatter->flush(oss);
+      int rc = rados.osd_command(osd, oss.str(), inject_inbl, &inject_outbl,
+                                 nullptr);
       ceph_assert(rc == 0);
       break;
     }
@@ -385,18 +400,24 @@ void RadosIo::applyInjectOp(IoOp& op) {
           static_cast<ClearReadErrorInjectOp&>(op);
 
       if (errorOp.type == 0) {
-        injectOpType = InjectOpType::WriteFailAndRollback;
+        ceph::messaging::osd::InjectECClearErrorRequest<
+            InjectOpType::WriteFailAndRollback>
+            clearErrorInject{pool, oid, errorOp.shard, errorOp.type};
+        encode_json("InjectECClearErrorRequest", clearErrorInject,
+                    formatter.get());
       } else if (errorOp.type == 3) {
-        injectOpType = InjectOpType::WriteOSDAbort;
+        ceph::messaging::osd::InjectECClearErrorRequest<
+            InjectOpType::WriteOSDAbort>
+            clearErrorInject{pool, oid, errorOp.shard, errorOp.type};
+        encode_json("InjectECClearErrorRequest", clearErrorInject,
+                    formatter.get());
       } else {
         ceph_abort("Unsupported inject type");
       }
 
-      ceph::io_exerciser::json::InjectECClearErrorRequest clearErrorInject(
-          injectOpType, pool, oid, errorOp.shard, errorOp.type);
-
-      int rc = rados.osd_command(osd, clearErrorInject.encode_json(),
-                                 inject_inbl, &inject_outbl, nullptr);
+      formatter->flush(oss);
+      int rc = rados.osd_command(osd, oss.str(), inject_inbl, &inject_outbl,
+                                 nullptr);
       ceph_assert(rc == 0);
       break;
     }
diff --git a/src/common/json/BalancerStructures.cc b/src/common/json/BalancerStructures.cc
new file mode 100644 (file)
index 0000000..48dfb84
--- /dev/null
@@ -0,0 +1,38 @@
+#include "BalancerStructures.h"
+
+#include "common/ceph_json.h"
+
+using namespace ceph::messaging::balancer;
+
+void BalancerOffRequest::dump(Formatter* f) const {
+  encode_json("prefix", "balancer off", f);
+}
+
+void BalancerOffRequest::decode_json(JSONObj* obj) {}
+
+void BalancerStatusRequest::dump(Formatter* f) const {
+  encode_json("prefix", "balancer status", f);
+}
+
+void BalancerStatusRequest::decode_json(JSONObj* obj) {}
+
+void BalancerStatusReply::dump(Formatter* f) const {
+  encode_json("active", active, f);
+  encode_json("last_optimization_duration", last_optimization_duration, f);
+  encode_json("last_optimization_started", last_optimization_started, f);
+  encode_json("mode", mode, f);
+  encode_json("no_optimization_needed", no_optimization_needed, f);
+  encode_json("optimize_result", optimize_result, f);
+}
+
+void BalancerStatusReply::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("active", active, obj);
+  JSONDecoder::decode_json("last_optimization_duration",
+                           last_optimization_duration, obj);
+  JSONDecoder::decode_json("last_optimization_started",
+                           last_optimization_started, obj);
+  JSONDecoder::decode_json("mode", mode, obj);
+  JSONDecoder::decode_json("no_optimization_needed", no_optimization_needed,
+                           obj);
+  JSONDecoder::decode_json("optimize_result", optimize_result, obj);
+}
\ No newline at end of file
diff --git a/src/common/json/BalancerStructures.h b/src/common/json/BalancerStructures.h
new file mode 100644 (file)
index 0000000..bbf5c74
--- /dev/null
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <string>
+
+#include "include/types.h"
+
+class JSONObj;
+
+namespace ceph {
+namespace messaging {
+namespace balancer {
+struct BalancerOffRequest {
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+struct BalancerStatusRequest {
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+struct BalancerStatusReply {
+  bool active;
+  std::string last_optimization_duration;
+  std::string last_optimization_started;
+  std::string mode;
+  bool no_optimization_needed;
+  std::string optimize_result;
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+}  // namespace balancer
+}  // namespace messaging
+}  // namespace ceph
\ No newline at end of file
diff --git a/src/common/json/CMakeLists.txt b/src/common/json/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1497daf
--- /dev/null
@@ -0,0 +1,4 @@
+add_library(json_structures STATIC
+                BalancerStructures.cc ConfigStructures.cc OSDStructures.cc)
+
+    target_link_libraries(json_structures global)
\ No newline at end of file
diff --git a/src/common/json/ConfigStructures.cc b/src/common/json/ConfigStructures.cc
new file mode 100644 (file)
index 0000000..651278d
--- /dev/null
@@ -0,0 +1,20 @@
+#include "ConfigStructures.h"
+
+#include "common/ceph_json.h"
+
+using namespace ceph::messaging::config;
+
+void ConfigSetRequest::dump(Formatter* f) const {
+  encode_json("prefix", "config set", f);
+  encode_json("who", who, f);
+  encode_json("name", name, f);
+  encode_json("value", value, f);
+  encode_json("force", force, f);
+}
+
+void ConfigSetRequest::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("who", who, obj);
+  JSONDecoder::decode_json("name", name, obj);
+  JSONDecoder::decode_json("value", value, obj);
+  JSONDecoder::decode_json("force", force, obj);
+}
\ No newline at end of file
diff --git a/src/common/json/ConfigStructures.h b/src/common/json/ConfigStructures.h
new file mode 100644 (file)
index 0000000..554229d
--- /dev/null
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <optional>
+#include <string>
+
+#include "include/types.h"
+
+class JSONObj;
+
+namespace ceph {
+namespace messaging {
+namespace config {
+struct ConfigSetRequest {
+  std::string who;
+  std::string name;
+  std::string value;
+  std::optional<bool> force;
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+}  // namespace config
+}  // namespace messaging
+}  // namespace ceph
\ No newline at end of file
diff --git a/src/common/json/OSDStructures.cc b/src/common/json/OSDStructures.cc
new file mode 100644 (file)
index 0000000..aaac5f6
--- /dev/null
@@ -0,0 +1,150 @@
+#include "OSDStructures.h"
+
+#include "common/ceph_json.h"
+#include "common/io_exerciser/OpType.h"
+
+using namespace ceph::messaging::osd;
+
+void OSDMapRequest::dump(Formatter* f) const {
+  encode_json("prefix", "osd map", f);
+  encode_json("pool", pool, f);
+  encode_json("object", object, f);
+  encode_json("nspace", nspace, f);
+  encode_json("format", format, f);
+}
+
+void OSDMapRequest::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("pool", pool, obj);
+  JSONDecoder::decode_json("object", object, obj);
+  JSONDecoder::decode_json("nspace", nspace, obj);
+  JSONDecoder::decode_json("format", format, obj);
+}
+
+void OSDMapReply::dump(Formatter* f) const {
+  encode_json("epoch", epoch, f);
+  encode_json("pool", pool, f);
+  encode_json("pool_id", pool_id, f);
+  encode_json("objname", objname, f);
+  encode_json("raw_pgid", raw_pgid, f);
+  encode_json("pgid", pgid, f);
+  encode_json("up", up, f);
+  encode_json("up_primary", up_primary, f);
+  encode_json("acting", acting, f);
+  encode_json("acting_primary", acting_primary, f);
+}
+
+void OSDMapReply::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("epoch", epoch, obj);
+  JSONDecoder::decode_json("pool", pool, obj);
+  JSONDecoder::decode_json("pool_id", pool_id, obj);
+  JSONDecoder::decode_json("objname", objname, obj);
+  JSONDecoder::decode_json("raw_pgid", raw_pgid, obj);
+  JSONDecoder::decode_json("pgid", pgid, obj);
+  JSONDecoder::decode_json("up", up, obj);
+  JSONDecoder::decode_json("up_primary", up_primary, obj);
+  JSONDecoder::decode_json("acting", acting, obj);
+  JSONDecoder::decode_json("acting_primary", acting_primary, obj);
+}
+
+void OSDPoolGetRequest::dump(Formatter* f) const {
+  encode_json("prefix", "osd pool get", f);
+  encode_json("pool", pool, f);
+  encode_json("var", var, f);
+  encode_json("format", format, f);
+}
+
+void OSDPoolGetRequest::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("pool", pool, obj);
+  JSONDecoder::decode_json("var", var, obj);
+  JSONDecoder::decode_json("format", format, obj);
+}
+
+void OSDPoolGetReply::dump(Formatter* f) const {
+  encode_json("erasure_code_profile", erasure_code_profile, f);
+}
+
+void OSDPoolGetReply::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("erasure_code_profile", erasure_code_profile, obj);
+}
+
+void OSDECProfileGetRequest::dump(Formatter* f) const {
+  encode_json("prefix", "osd pool get", f);
+  encode_json("name", name, f);
+  encode_json("format", format, f);
+}
+
+void OSDECProfileGetRequest::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("name", name, obj);
+  JSONDecoder::decode_json("format", format, obj);
+}
+
+void OSDECProfileGetReply::dump(Formatter* f) const {
+  encode_json("crush-device-class", crush_device_class, f);
+  encode_json("crush-failure-domain", crush_failure_domain, f);
+  encode_json("crush-num-failure-domains", crush_num_failure_domains, f);
+  encode_json("crush-osds-per-failure-domain", crush_osds_per_failure_domain,
+              f);
+  encode_json("crush-root", crush_root, f);
+  encode_json("jerasure-per-chunk-alignment", jerasure_per_chunk_alignment, f);
+  encode_json("k", k, f);
+  encode_json("m", m, f);
+  encode_json("plugin", plugin, f);
+  encode_json("technique", technique, f);
+  encode_json("w", w, f);
+}
+
+void OSDECProfileGetReply::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("crush-device-class", crush_device_class, obj);
+  JSONDecoder::decode_json("crush-failure-domain", crush_failure_domain, obj);
+  JSONDecoder::decode_json("crush-num-failure-domains",
+                           crush_num_failure_domains, obj);
+  JSONDecoder::decode_json("crush-osds-per-failure-domain",
+                           crush_osds_per_failure_domain, obj);
+  JSONDecoder::decode_json("crush-root", crush_root, obj);
+  JSONDecoder::decode_json("jerasure-per-chunk-alignment",
+                           jerasure_per_chunk_alignment, obj);
+  JSONDecoder::decode_json("k", k, obj);
+  JSONDecoder::decode_json("m", m, obj);
+  JSONDecoder::decode_json("plugin", plugin, obj);
+  JSONDecoder::decode_json("technique", technique, obj);
+  JSONDecoder::decode_json("w", w, obj);
+}
+
+void OSDECProfileSetRequest::dump(Formatter* f) const {
+  encode_json("prefix", "osd erasure-code-profile set", f);
+  encode_json("name", name, f);
+  encode_json("profile", profile, f);
+}
+
+void OSDECProfileSetRequest::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("name", name, obj);
+  JSONDecoder::decode_json("profile", profile, obj);
+}
+
+void OSDECPoolCreateRequest::dump(Formatter* f) const {
+  encode_json("prefix", "osd pool create", f);
+  encode_json("pool", pool, f);
+  encode_json("pool_type", pool_type, f);
+  encode_json("pg_num", pg_num, f);
+  encode_json("pgp_num", pgp_num, f);
+  encode_json("erasure_code_profile", erasure_code_profile, f);
+}
+
+void OSDECPoolCreateRequest::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("pool", pool, obj);
+  JSONDecoder::decode_json("pool_type", pool_type, obj);
+  JSONDecoder::decode_json("pg_num", pg_num, obj);
+  JSONDecoder::decode_json("pgp_num", pgp_num, obj);
+  JSONDecoder::decode_json("erasure_code_profile", erasure_code_profile, obj);
+}
+
+void OSDSetRequest::dump(Formatter* f) const {
+  encode_json("prefix", "osd set", f);
+  encode_json("key", key, f);
+  encode_json("yes_i_really_mean_it", yes_i_really_mean_it, f);
+}
+
+void OSDSetRequest::decode_json(JSONObj* obj) {
+  JSONDecoder::decode_json("key", key, obj);
+  JSONDecoder::decode_json("yes_i_really_mean_it", yes_i_really_mean_it, obj);
+}
\ No newline at end of file
diff --git a/src/common/json/OSDStructures.h b/src/common/json/OSDStructures.h
new file mode 100644 (file)
index 0000000..3e4528a
--- /dev/null
@@ -0,0 +1,189 @@
+#pragma once
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "common/ceph_json.h"
+#include "common/io_exerciser/OpType.h"
+#include "include/types.h"
+
+class JSONObj;
+
+namespace ceph {
+namespace messaging {
+namespace osd {
+struct OSDMapRequest {
+  std::string pool;
+  std::string object;
+  std::string nspace;
+  std::string format = "json";
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+struct OSDMapReply {
+  epoch_t epoch;
+  std::string pool;
+  uint64_t pool_id;
+  std::string objname;
+  std::string raw_pgid;
+  std::string pgid;
+  std::vector<int> up;
+  int up_primary;
+  std::vector<int> acting;
+  int acting_primary;
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+struct OSDPoolGetRequest {
+  std::string pool;
+  std::string var = "erasure_code_profile";
+  std::string format = "json";
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+struct OSDPoolGetReply {
+  std::string erasure_code_profile;
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+struct OSDECProfileGetRequest {
+  std::string name;
+  std::string format = "json";
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+struct OSDECProfileGetReply {
+  std::string crush_device_class;
+  std::string crush_failure_domain;
+  int crush_num_failure_domains;
+  int crush_osds_per_failure_domain;
+  std::string crush_root;
+  bool jerasure_per_chunk_alignment;
+  int k;
+  int m;
+  std::string plugin;
+  std::string technique;
+  std::string w;
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+struct OSDECProfileSetRequest {
+  std::string name;
+  std::vector<std::string> profile;
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+struct OSDECPoolCreateRequest {
+  std::string pool;
+  std::string pool_type;
+  int pg_num;
+  int pgp_num;
+  std::string erasure_code_profile;
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+struct OSDSetRequest {
+  std::string key;
+  std::optional<bool> yes_i_really_mean_it = std::nullopt;
+
+  void dump(Formatter* f) const;
+  void decode_json(JSONObj* obj);
+};
+
+// These structures are sent directly to the relevant OSD
+// rather than the monitor
+template <io_exerciser::InjectOpType op_type>
+struct InjectECErrorRequest {
+  std::string pool;
+  std::string objname;
+  int shardid;
+  std::optional<uint64_t> type;
+  std::optional<uint64_t> when;
+  std::optional<uint64_t> duration;
+
+  void dump(Formatter* f) const {
+    switch (op_type) {
+      case io_exerciser::InjectOpType::ReadEIO:
+        [[fallthrough]];
+      case io_exerciser::InjectOpType::ReadMissingShard:
+        ::encode_json("prefix", "injectecreaderr", f);
+        break;
+      case io_exerciser::InjectOpType::WriteFailAndRollback:
+        [[fallthrough]];
+      case io_exerciser::InjectOpType::WriteOSDAbort:
+        ::encode_json("prefix", "injectecwriteerr", f);
+        break;
+      default:
+        ceph_abort_msg("Unsupported Inject Type");
+    }
+    ::encode_json("pool", pool, f);
+    ::encode_json("objname", objname, f);
+    ::encode_json("shardid", shardid, f);
+    ::encode_json("type", type, f);
+    ::encode_json("when", when, f);
+    ::encode_json("duration", duration, f);
+  }
+  void decode_json(JSONObj* obj) {
+    JSONDecoder::decode_json("pool", pool, obj);
+    JSONDecoder::decode_json("objname", objname, obj);
+    JSONDecoder::decode_json("shardid", shardid, obj);
+    JSONDecoder::decode_json("type", type, obj);
+    JSONDecoder::decode_json("when", when, obj);
+    JSONDecoder::decode_json("duration", duration, obj);
+  }
+};
+
+template <io_exerciser::InjectOpType op_type>
+struct InjectECClearErrorRequest {
+  std::string pool;
+  std::string objname;
+  int shardid;
+  std::optional<uint64_t> type;
+
+  void dump(Formatter* f) const {
+    switch (op_type) {
+      case io_exerciser::InjectOpType::ReadEIO:
+        [[fallthrough]];
+      case io_exerciser::InjectOpType::ReadMissingShard:
+        ::encode_json("prefix", "injectecclearreaderr", f);
+        break;
+      case io_exerciser::InjectOpType::WriteFailAndRollback:
+        [[fallthrough]];
+      case io_exerciser::InjectOpType::WriteOSDAbort:
+        ::encode_json("prefix", "injectecclearwriteerr", f);
+        break;
+      default:
+        ceph_abort_msg("Unsupported Inject Type");
+    }
+    ::encode_json("pool", pool, f);
+    ::encode_json("objname", objname, f);
+    ::encode_json("shardid", shardid, f);
+    ::encode_json("type", type, f);
+  }
+  void decode_json(JSONObj* obj) {
+    JSONDecoder::decode_json("pool", pool, obj);
+    JSONDecoder::decode_json("objname", objname, obj);
+    JSONDecoder::decode_json("shardid", shardid, obj);
+    JSONDecoder::decode_json("type", type, obj);
+  }
+};
+}  // namespace osd
+}  // namespace messaging
+}  // namespace ceph
\ No newline at end of file
index f2d1471e22e3f4f296b1e911ae4583ecea5f4d84..798558ebbe06a7840bc4405bba75da02c86b92c5 100644 (file)
@@ -22,7 +22,7 @@ install(TARGETS
 add_executable(ceph_test_rados_io_sequence
   ${CMAKE_CURRENT_SOURCE_DIR}/ceph_test_rados_io_sequence.cc)
 target_link_libraries(ceph_test_rados_io_sequence
-  librados global object_io_exerciser)
+  librados global object_io_exerciser json_structures)
 install(TARGETS
   ceph_test_rados_io_sequence
   DESTINATION ${CMAKE_INSTALL_BINDIR})
index da2218a47c2501d77d39b27cd213dd72b27d03c3..1dd1e61643dbc746b70e5e9d45d1cc97165c21af 100644 (file)
 #include "common/io_exerciser/EcIoSequence.h"
 #include "common/io_exerciser/IoOp.h"
 #include "common/io_exerciser/IoSequence.h"
-#include "common/io_exerciser/JsonStructures.h"
 #include "common/io_exerciser/Model.h"
 #include "common/io_exerciser/ObjectModel.h"
 #include "common/io_exerciser/RadosIo.h"
+#include "common/json/BalancerStructures.h"
+#include "common/json/ConfigStructures.h"
+#include "common/json/OSDStructures.h"
 #include "fmt/format.h"
 #include "global/global_context.h"
 #include "global/global_init.h"
@@ -212,6 +214,17 @@ int parse_io_seq_options(po::variables_map& vm, int argc, char** argv) {
 
   return 0;
 }
+
+template <typename S>
+int send_mon_command(S& s, librados::Rados& rados, const char* name,
+                     ceph::buffer::list& inbl, ceph::buffer::list* outbl, Formatter* f) {
+  std::ostringstream oss;
+  encode_json(name, s, f);
+  f->flush(oss);
+  int rc = rados.mon_command(oss.str(), inbl, outbl, nullptr);
+  return rc;
+}
+
 }  // namespace
 
 template <typename T, int N, const std::array<T, N>& Ts>
@@ -301,7 +314,7 @@ ceph::io_sequence::tester::SelectECPool::SelectECPool(
     ceph::util::random_number_generator<int>& rng, po::variables_map vm,
     librados::Rados& rados, bool dry_run, bool allow_pool_autoscaling,
     bool allow_pool_balancer, bool allow_pool_deep_scrubbing,
-    bool allow_pool_scrubbing)
+    bool allow_pool_scrubbing, bool test_recovery)
     : ProgramOptionSelector(rng, vm, "pool", false, false),
       rados(rados),
       dry_run(dry_run),
@@ -309,6 +322,7 @@ ceph::io_sequence::tester::SelectECPool::SelectECPool(
       allow_pool_balancer(allow_pool_balancer),
       allow_pool_deep_scrubbing(allow_pool_deep_scrubbing),
       allow_pool_scrubbing(allow_pool_scrubbing),
+      test_recovery(test_recovery),
       skm(SelectErasureKM(rng, vm)),
       spl(SelectErasurePlugin(rng, vm)),
       scs(SelectErasureChunkSize(rng, vm)) {
@@ -324,31 +338,31 @@ const std::string ceph::io_sequence::tester::SelectECPool::choose() {
   if (!skm.isForced() && force_value.has_value()) {
     int rc;
     bufferlist inbl, outbl;
-    auto formatter = std::make_shared<JSONFormatter>(false);
+    auto formatter = std::make_unique<JSONFormatter>(false);
 
-    ceph::io_exerciser::json::OSDPoolGetRequest osdPoolGetRequest(*force_value,
-                                                                  formatter);
-    rc = rados.mon_command(osdPoolGetRequest.encode_json(), inbl, &outbl,
-                           nullptr);
+    ceph::messaging::osd::OSDPoolGetRequest osdPoolGetRequest{*force_value};
+    rc = send_mon_command(osdPoolGetRequest, rados, "OSDPoolGetRequest", inbl,
+                          &outbl, formatter.get());
     ceph_assert(rc == 0);
 
     JSONParser p;
     bool success = p.parse(outbl.c_str(), outbl.length());
     ceph_assert(success);
 
-    ceph::io_exerciser::json::OSDPoolGetReply osdPoolGetReply(formatter);
+    ceph::messaging::osd::OSDPoolGetReply osdPoolGetReply;
     osdPoolGetReply.decode_json(&p);
 
-    ceph::io_exerciser::json::OSDECProfileGetRequest osdECProfileGetRequest(
-        osdPoolGetReply.erasure_code_profile, formatter);
-    rc = rados.mon_command(osdECProfileGetRequest.encode_json(), inbl, &outbl,
-                           nullptr);
+    ceph::messaging::osd::OSDECProfileGetRequest osdECProfileGetRequest{
+        osdPoolGetReply.erasure_code_profile};
+    rc = send_mon_command(osdECProfileGetRequest, rados,
+                          "OSDECProfileGetRequest", inbl, &outbl,
+                          formatter.get());
     ceph_assert(rc == 0);
 
     success = p.parse(outbl.c_str(), outbl.length());
     ceph_assert(success);
 
-    ceph::io_exerciser::json::OSDECProfileGetReply reply(formatter);
+    ceph::messaging::osd::OSDECProfileGetReply reply;
     reply.decode_json(&p);
     k = reply.k;
     m = reply.m;
@@ -375,81 +389,82 @@ void ceph::io_sequence::tester::SelectECPool::create_pool(
     const std::string& plugin, uint64_t chunk_size, int k, int m) {
   int rc;
   bufferlist inbl, outbl;
-  auto formatter = std::make_shared<JSONFormatter>(false);
+  auto formatter = std::make_unique<JSONFormatter>(false);
 
-  ceph::io_exerciser::json::OSDECProfileSetRequest ecProfileSetRequest(
+  ceph::messaging::osd::OSDECProfileSetRequest ecProfileSetRequest{
       fmt::format("testprofile-{}", pool_name),
       {fmt::format("plugin={}", plugin), fmt::format("k={}", k),
        fmt::format("m={}", m), fmt::format("stripe_unit={}", chunk_size),
-       fmt::format("crush-failure-domain=osd")},
-      formatter);
-  rc = rados.mon_command(ecProfileSetRequest.encode_json(), inbl, &outbl,
-                         nullptr);
+       fmt::format("crush-failure-domain=osd")}};
+  rc = send_mon_command(ecProfileSetRequest, rados, "OSDECProfileSetRequest",
+                        inbl, &outbl, formatter.get());
   ceph_assert(rc == 0);
 
-  ceph::io_exerciser::json::OSDECPoolCreateRequest poolCreateRequest(
-      pool_name, fmt::format("testprofile-{}", pool_name), formatter);
-  rc =
-      rados.mon_command(poolCreateRequest.encode_json(), inbl, &outbl, nullptr);
+  ceph::messaging::osd::OSDECPoolCreateRequest poolCreateRequest{
+      pool_name, "erasure", 8, 8, fmt::format("testprofile-{}", pool_name)};
+  rc = send_mon_command(poolCreateRequest, rados, "OSDECPoolCreateRequest",
+                        inbl, &outbl, formatter.get());
   ceph_assert(rc == 0);
 
   if (allow_pool_autoscaling) {
-    ceph::io_exerciser::json::OSDSetRequest setNoAutoscaleRequest(
-        "noautoscale", std::nullopt, formatter);
-    rc = rados.mon_command(setNoAutoscaleRequest.encode_json(), inbl, &outbl,
-                           nullptr);
+    ceph::messaging::osd::OSDSetRequest setNoAutoscaleRequest{"noautoscale",
+                                                              std::nullopt};
+    rc = send_mon_command(setNoAutoscaleRequest, rados, "OSDSetRequest", inbl,
+                          &outbl, formatter.get());
     ceph_assert(rc == 0);
   }
 
   if (allow_pool_balancer) {
-    ceph::io_exerciser::json::BalancerOffRequest balancerOffRequest(formatter);
-    rc = rados.mon_command(balancerOffRequest.encode_json(), inbl, &outbl,
-                           nullptr);
+    ceph::messaging::balancer::BalancerOffRequest balancerOffRequest{};
+    rc = send_mon_command(balancerOffRequest, rados, "BalancerOffRequest", inbl,
+                          &outbl, formatter.get());
     ceph_assert(rc == 0);
 
-    ceph::io_exerciser::json::BalancerStatusRequest balancerStatusRequest(
-        formatter);
-    rc = rados.mon_command(balancerStatusRequest.encode_json(), inbl, &outbl,
-                           nullptr);
+    ceph::messaging::balancer::BalancerStatusRequest balancerStatusRequest{};
+    rc = send_mon_command(balancerStatusRequest, rados, "BalancerStatusRequest",
+                          inbl, &outbl, formatter.get());
     ceph_assert(rc == 0);
 
     JSONParser p;
     bool success = p.parse(outbl.c_str(), outbl.length());
     ceph_assert(success);
 
-    ceph::io_exerciser::json::BalancerStatusReply reply{formatter};
+    ceph::messaging::balancer::BalancerStatusReply reply;
     reply.decode_json(&p);
     ceph_assert(!reply.active);
   }
 
   if (allow_pool_deep_scrubbing) {
-    ceph::io_exerciser::json::OSDSetRequest setNoDeepScrubRequest(
-        "nodeep-scrub", std::nullopt, formatter);
-    rc = rados.mon_command(setNoDeepScrubRequest.encode_json(), inbl, &outbl,
-                           nullptr);
+    ceph::messaging::osd::OSDSetRequest setNoDeepScrubRequest{"nodeep-scrub",
+                                                              std::nullopt};
+    rc = send_mon_command(setNoDeepScrubRequest, rados, "setNoDeepScrubRequest",
+                          inbl, &outbl, formatter.get());
     ceph_assert(rc == 0);
   }
 
   if (allow_pool_scrubbing) {
-    ceph::io_exerciser::json::OSDSetRequest setNoScrubRequest(
-        "noscrub", std::nullopt, formatter);
-    rc = rados.mon_command(setNoScrubRequest.encode_json(), inbl, &outbl,
-                           nullptr);
+    ceph::messaging::osd::OSDSetRequest setNoScrubRequest{"noscrub",
+                                                          std::nullopt};
+    rc = send_mon_command(setNoScrubRequest, rados, "OSDSetRequest", inbl,
+                          &outbl, formatter.get());
     ceph_assert(rc == 0);
   }
 
-  ceph::io_exerciser::json ::ConfigSetRequest configSetBluestoreDebugRequest(
-      "global", "bluestore_debug_inject_read_err", "true", std::nullopt,
-      formatter);
-  rc = rados.mon_command(configSetBluestoreDebugRequest.encode_json(), inbl,
-                         &outbl, nullptr);
-  ceph_assert(rc == 0);
+  if (test_recovery) {
+    ceph::messaging::config::ConfigSetRequest configSetBluestoreDebugRequest{
+        "global", "bluestore_debug_inject_read_err", "true", std::nullopt};
+    rc = send_mon_command(configSetBluestoreDebugRequest, rados,
+                          "ConfigSetRequest", inbl, &outbl,
+                          formatter.get());
+    ceph_assert(rc == 0);
 
-  ceph::io_exerciser::json ::ConfigSetRequest configSetMaxMarkdownRequest(
-      "global", "osd_max_markdown_count", "99999999", std::nullopt, formatter);
-  rc = rados.mon_command(configSetMaxMarkdownRequest.encode_json(), inbl,
-                         &outbl, nullptr);
-  ceph_assert(rc == 0);
+    ceph::messaging::config::ConfigSetRequest configSetMaxMarkdownRequest{
+        "global", "osd_max_markdown_count", "99999999", std::nullopt};
+    rc =
+        send_mon_command(configSetMaxMarkdownRequest, rados, "ConfigSetRequest",
+                         inbl, &outbl, formatter.get());
+    ceph_assert(rc == 0);
+  }
 }
 
 ceph::io_sequence::tester::TestObject::TestObject(
@@ -471,22 +486,23 @@ ceph::io_sequence::tester::TestObject::TestObject(
     int threads = snt.choose();
 
     bufferlist inbl, outbl;
+    auto formatter = std::make_unique<JSONFormatter>(false);
 
     std::optional<std::vector<int>> cached_shard_order = std::nullopt;
 
     if (!spo.get_allow_pool_autoscaling() && !spo.get_allow_pool_balancer() &&
         !spo.get_allow_pool_deep_scrubbing() &&
         !spo.get_allow_pool_scrubbing()) {
-      ceph::io_exerciser::json::OSDMapRequest osdMapRequest(pool, oid, "");
-      int rc =
-          rados.mon_command(osdMapRequest.encode_json(), inbl, &outbl, nullptr);
+      ceph::messaging::osd::OSDMapRequest osdMapRequest{pool, oid, ""};
+      int rc = send_mon_command(osdMapRequest, rados, "OSDMapRequest", inbl,
+                                &outbl, formatter.get());
       ceph_assert(rc == 0);
 
       JSONParser p;
       bool success = p.parse(outbl.c_str(), outbl.length());
       ceph_assert(success);
 
-      ceph::io_exerciser::json::OSDMapReply reply{};
+      ceph::messaging::osd::OSDMapReply reply{};
       reply.decode_json(&p);
       cached_shard_order = reply.acting;
     }
@@ -579,7 +595,8 @@ ceph::io_sequence::tester::TestRunner::TestRunner(po::variables_map& vm,
           vm.contains("allow_pool_autoscaling"),
           vm.contains("allow_pool_balancer"),
           vm.contains("allow_pool_deep_scrubbing"),
-          vm.contains("allow_pool_scrubbing")},
+          vm.contains("allow_pool_scrubbing"),
+          vm.contains("test_recovery")},
       snt{rng, vm},
       ssr{rng, vm} {
   dout(0) << "Test using seed " << seed << dendl;
@@ -721,18 +738,18 @@ bool ceph::io_sequence::tester::TestRunner::run_interactive_test() {
     const std::string pool = spo.choose();
 
     bufferlist inbl, outbl;
+    auto formatter = std::make_unique<JSONFormatter>(false);
 
-    ceph::io_exerciser::json::OSDMapRequest osdMapRequest(pool, object_name,
-                                                          "");
-    int rc =
-        rados.mon_command(osdMapRequest.encode_json(), inbl, &outbl, nullptr);
+    ceph::messaging::osd::OSDMapRequest osdMapRequest{pool, object_name, ""};
+    int rc = send_mon_command(osdMapRequest, rados, "OSDMapRequest", inbl,
+                              &outbl, formatter.get());
     ceph_assert(rc == 0);
 
     JSONParser p;
     bool success = p.parse(outbl.c_str(), outbl.length());
     ceph_assert(success);
 
-    ceph::io_exerciser::json::OSDMapReply reply{};
+    ceph::messaging::osd::OSDMapReply reply{};
     reply.decode_json(&p);
 
     model = std::make_unique<ceph::io_exerciser::RadosIo>(
index c06c597f7840e7e7fce9f3257a7e0b8da4c63413..9af5f706b2fdf92d584d746449feb6b8d423060d 100644 (file)
@@ -204,7 +204,8 @@ class SelectECPool
   SelectECPool(ceph::util::random_number_generator<int>& rng,
                po::variables_map vm, librados::Rados& rados, bool dry_run,
                bool allow_pool_autoscaling, bool allow_pool_balancer,
-               bool allow_pool_deep_scrubbing, bool allow_pool_scrubbing);
+               bool allow_pool_deep_scrubbing, bool allow_pool_scrubbing,
+               bool test_recovery);
   const std::string choose() override;
 
   bool get_allow_pool_autoscaling() { return allow_pool_autoscaling; }
@@ -226,6 +227,7 @@ class SelectECPool
   bool allow_pool_balancer;
   bool allow_pool_deep_scrubbing;
   bool allow_pool_scrubbing;
+  bool test_recovery;
   int k;
   int m;