f->dump_string(var.c_str(), buf);
}
}
+ } else if (command == "config help") {
+ std::string var;
+ if (cmd_getval(this, cmdmap, "var", var)) {
+ // Output a single one
+ std::string key = ConfFile::normalize_key_name(var);
+ const auto &i = _conf->schema.find(key);
+ if (i == _conf->schema.end()) {
+ std::ostringstream msg;
+ msg << "Setting not found: '" << key << "'";
+ f->dump_string("error", msg.str());
+ } else {
+ i->second.dump(f);
+ }
+ } else {
+ // Output all
+ f->open_array_section("options");
+ for (const auto &option : ceph_options) {
+ option.dump(f);
+ }
+ f->close_section();
+ }
} else if (command == "config diff") {
md_config_t def_conf;
def_conf.set_val("cluster", _conf->cluster);
_admin_socket->register_command("perf histogram schema", "perf histogram schema", _admin_hook, "dump perf histogram schema");
_admin_socket->register_command("perf reset", "perf reset name=var,type=CephString", _admin_hook, "perf reset <name>: perf reset all or one perfcounter name");
_admin_socket->register_command("config show", "config show", _admin_hook, "dump current config settings");
+ _admin_socket->register_command("config help", "config help name=var,type=CephString,req=false", _admin_hook, "get config setting schema and descriptions");
_admin_socket->register_command("config set", "config set name=var,type=CephString name=val,type=CephString,n=N", _admin_hook, "config set <field> <val> [<val> ...]: set a config variable");
_admin_socket->register_command("config get", "config get name=var,type=CephString", _admin_hook, "config get <field>: get the config value");
_admin_socket->register_command("config diff",
_admin_socket->unregister_command("config show");
_admin_socket->unregister_command("config set");
_admin_socket->unregister_command("config get");
+ _admin_socket->unregister_command("config help");
_admin_socket->unregister_command("config diff");
_admin_socket->unregister_command("config diff get");
_admin_socket->unregister_command("log flush");
#include "acconfig.h"
#include "options.h"
+#include "common/Formatter.h"
// Helpers for validators
#include "include/stringify.h"
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
+
+void Option::dump_value(const char *field_name,
+ const Option::value_t &v, Formatter *f) const
+{
+ if (boost::get<boost::blank>(&v)) {
+ // This should be nil but Formatter doesn't allow it.
+ f->dump_string(field_name, "");
+ } else if (type == TYPE_UINT) {
+ f->dump_unsigned(field_name, boost::get<uint64_t>(v));
+ } else if (type == TYPE_INT) {
+ f->dump_int(field_name, boost::get<int64_t>(v));
+ } else if (type == TYPE_STR) {
+ f->dump_string(field_name, boost::get<std::string>(v));
+ } else if (type == TYPE_FLOAT) {
+ f->dump_float(field_name, boost::get<double>(v));
+ } else if (type == TYPE_BOOL) {
+ f->dump_bool(field_name, boost::get<bool>(v));
+ } else {
+ f->dump_stream(field_name) << v;
+ }
+}
+
+void Option::dump(Formatter *f) const
+{
+ f->open_object_section("option");
+ f->dump_string("name", name);
+
+ f->dump_string("type", type_to_str(type));
+ std::string level_str;
+
+ f->dump_string("level", level_to_str(level));
+
+ f->dump_string("desc", desc);
+ f->dump_string("long_desc", long_desc);
+
+ dump_value("default", value, f);
+ dump_value("daemon_default", daemon_value, f);
+
+ f->open_array_section("tags");
+ for (const auto t : tags) {
+ f->dump_string("tag", t);
+ }
+ f->close_section();
+
+ f->open_array_section("see_also");
+ for (const auto sa : see_also) {
+ f->dump_string("see_also", sa);
+ }
+ f->close_section();
+
+ if (type == TYPE_STR) {
+ f->open_array_section("enum_values");
+ for (const auto &ea : enum_allowed) {
+ f->dump_string("enum_value", ea);
+ }
+ f->close_section();
+ }
+
+ dump_value("min", min, f);
+ dump_value("max", max, f);
+
+ f->close_section();
+}
+
const std::vector<Option> ceph_options = {
// ** global basics **
TYPE_UUID,
};
- const char *type_to_str(type_t t) {
+ const char *type_to_str(type_t t) const {
switch (t) {
case TYPE_UINT: return "uint64_t";
case TYPE_INT: return "int64_t";
LEVEL_DEV,
};
+ const char *level_to_str(level_t l) const {
+ switch(l) {
+ case LEVEL_BASIC: return "basic";
+ case LEVEL_ADVANCED: return "advanced";
+ case LEVEL_DEV: return "developer";
+ default: return "unknown";
+ }
+ }
+
using value_t = boost::variant<
boost::blank,
std::string,
}
}
+ void dump_value(const char *field_name, const value_t &v, Formatter *f) const;
+
// const char * must be explicit to avoid it being treated as an int
Option& set_value(value_t& v, const char *new_value) {
v = std::string(new_value);
return *this;
}
+ void dump(Formatter *f) const;
+
/**
* A crude indicator of whether the value may be
* modified safely at runtime -- should be replaced