Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bessctl: add init/cmd argument introspection #1012

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 67 additions & 6 deletions core/bessctl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,55 @@ class BESSControlImpl final : public BESSControl::Service {
return Status::OK;
}

Status DumpDescriptors(ServerContext*, const EmptyRequest*,
DumpDescriptorsResponse* response) override {
std::lock_guard<std::recursive_mutex> lock(mutex_);

auto& module_descs = *response->mutable_modules();
for (const auto & [ mclass, builder ] :
ModuleBuilder::all_module_builders()) {
if (const auto dp = builder.init_descriptor(); dp != nullptr) {
google::protobuf::DescriptorProto desc;
dp->CopyTo(&desc);
desc.set_name(dp->full_name());
module_descs[mclass] = desc;
}
}

auto& module_cmd_descs = *response->mutable_module_commands();
for (const auto & [ mclass, builder ] :
ModuleBuilder::all_module_builders()) {
auto& cmds = *module_cmd_descs[mclass].mutable_commands();
for (const auto & [ cmd, arg_type ] : builder.cmds()) {
if (std::holds_alternative<const google::protobuf::Descriptor*>(
arg_type)) {
const auto dp =
std::get<const google::protobuf::Descriptor*>(arg_type);
// to be safe
if (dp == nullptr) {
continue;
}
google::protobuf::DescriptorProto desc;
dp->CopyTo(&desc);
desc.set_name(dp->full_name());
cmds[cmd] = desc;
}
}
}

auto& port_descs = *response->mutable_ports();
for (const auto & [ driver, builder ] : PortBuilder::all_port_builders()) {
if (const auto dp = builder.init_descriptor(); dp != nullptr) {
google::protobuf::DescriptorProto desc;
dp->CopyTo(&desc);
desc.set_name(dp->full_name());
port_descs[driver] = desc;
}
}

return Status::OK;
}

Status ResetAll(ServerContext* context, const EmptyRequest* request,
EmptyResponse* response) override {
std::lock_guard<std::recursive_mutex> lock(mutex_);
Expand Down Expand Up @@ -1472,9 +1521,15 @@ class BESSControlImpl final : public BESSControl::Service {

response->set_name(cls->class_name());
response->set_help(cls->help_text());
for (const auto& cmd : cls->cmds()) {
response->add_cmds(cmd.first);
response->add_cmd_args(cmd.second);
for (const auto & [ cmd, arg_type ] : cls->cmds()) {
response->add_cmds(cmd);
if (std::holds_alternative<std::string>(arg_type)) {
response->add_cmd_args(std::get<std::string>(arg_type));
} else if (const auto dp =
std::get<const google::protobuf::Descriptor*>(arg_type);
dp != nullptr) {
response->add_cmd_args(dp->name());
}
}
return Status::OK;
}
Expand Down Expand Up @@ -1750,9 +1805,15 @@ class BESSControlImpl final : public BESSControl::Service {

response->set_name(cls->class_name());
response->set_help(cls->help_text());
for (const auto& cmd : cls->cmds()) {
response->add_cmds(cmd.first);
response->add_cmd_args(cmd.second);
for (const auto & [ cmd, arg_type ] : cls->cmds()) {
response->add_cmds(cmd);
if (std::holds_alternative<std::string>(arg_type)) {
response->add_cmd_args(std::get<std::string>(arg_type));
} else if (const auto dp =
std::get<const google::protobuf::Descriptor*>(arg_type);
dp != nullptr) {
response->add_cmd_args(dp->name());
}
}
return Status::OK;
}
Expand Down
7 changes: 6 additions & 1 deletion core/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@
#ifndef BESS_COMMANDS_H_
#define BESS_COMMANDS_H_

#include <variant>
#include <vector>

#include <google/protobuf/descriptor.pb.h>

#include "message.h"

// TODO(torek): refactor; instead of "module command" and "gate command"
Expand All @@ -50,6 +53,8 @@ using module_cmd_func_t =
pb_func_t<CommandResponse, Module, google::protobuf::Any>;
using gate_hook_cmd_func_t =
pb_func_t<CommandResponse, bess::GateHook, google::protobuf::Any>;
using CommandArgType =
std::variant<std::string, const google::protobuf::Descriptor *>;

// Describes a single command that can be issued to a module
// or gate hook (according to cmd_func_t).
Expand All @@ -58,7 +63,7 @@ struct GenericCommand {
enum ThreadSafety { THREAD_UNSAFE = 0, THREAD_SAFE = 1 };

std::string cmd;
std::string arg_type;
CommandArgType arg_type;
cmd_func_t func;

// If set to THREAD_SAFE, workers don't need to be paused in order to run
Expand Down
7 changes: 4 additions & 3 deletions core/gate.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,11 @@ class GateHookBuilder {
const std::string &name_template() const { return name_template_; }
const std::string &help_text() const { return help_text_; }

const std::vector<std::pair<std::string, std::string>> cmds() const {
std::vector<std::pair<std::string, std::string>> ret;
for (auto &cmd : cmds_)
const std::vector<std::pair<std::string, CommandArgType>> cmds() const {
std::vector<std::pair<std::string, CommandArgType>> ret;
for (auto &cmd : cmds_) {
ret.push_back(std::make_pair(cmd.cmd, cmd.arg_type));
}
return ret;
}

Expand Down
5 changes: 3 additions & 2 deletions core/module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ bool ModuleBuilder::RegisterModuleClass(
std::function<Module *()> module_generator, const std::string &class_name,
const std::string &name_template, const std::string &help_text,
const gate_idx_t igates, const gate_idx_t ogates, const Commands &cmds,
module_init_func_t init_func) {
module_init_func_t init_func, const Descriptor *init_descriptor) {
all_module_builders_holder().emplace(
std::piecewise_construct, std::forward_as_tuple(class_name),
std::forward_as_tuple(module_generator, class_name, name_template,
help_text, igates, ogates, cmds, init_func));
help_text, igates, ogates, cmds, init_func,
init_descriptor));
return true;
}

Expand Down
45 changes: 29 additions & 16 deletions core/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
#include <utility>
#include <vector>

#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/message.h>

#include "commands.h"
#include "event.h"
#include "gate.h"
Expand All @@ -50,6 +53,7 @@
#include "worker.h"

using bess::gate_idx_t;
using google::protobuf::Descriptor;

#define INVALID_TASK_ID ((task_id_t)-1)
#define MAX_NUMA_NODE 16
Expand All @@ -74,8 +78,6 @@ struct Context {
gate_idx_t gate_without_hook[bess::PacketBatch::kMaxBurst];
};

using module_cmd_func_t =
pb_func_t<CommandResponse, Module, google::protobuf::Any>;
using module_init_func_t =
pb_func_t<CommandResponse, Module, google::protobuf::Any>;

Expand All @@ -101,6 +103,12 @@ static inline module_init_func_t MODULE_INIT_FUNC(
};
}

template <typename T, typename M>
static inline const Descriptor *MODULE_INIT_DESC(
CommandResponse (M::*)(const T &)) {
return T::descriptor();
}

class Module;

// A class for managing modules of 'a particular type'.
Expand All @@ -112,23 +120,23 @@ class ModuleBuilder {
const std::string &name_template, const std::string &help_text,
const gate_idx_t igates, const gate_idx_t ogates, const Commands &cmds,
std::function<CommandResponse(Module *, const google::protobuf::Any &)>
init_func)
init_func,
const Descriptor *init_descriptor)
: module_generator_(module_generator),
num_igates_(igates),
num_ogates_(ogates),
class_name_(class_name),
name_template_(name_template),
help_text_(help_text),
cmds_(cmds),
init_func_(init_func) {}

static bool RegisterModuleClass(std::function<Module *()> module_generator,
const std::string &class_name,
const std::string &name_template,
const std::string &help_text,
const gate_idx_t igates,
const gate_idx_t ogates, const Commands &cmds,
module_init_func_t init_func);
init_func_(init_func),
init_descriptor_(init_descriptor) {}

static bool RegisterModuleClass(
std::function<Module *()> module_generator, const std::string &class_name,
const std::string &name_template, const std::string &help_text,
const gate_idx_t igates, const gate_idx_t ogates, const Commands &cmds,
module_init_func_t init_func, const Descriptor *init_descriptor);
static bool DeregisterModuleClass(const std::string &class_name);

static std::map<std::string, ModuleBuilder> &all_module_builders_holder(
Expand All @@ -146,10 +154,11 @@ class ModuleBuilder {
const std::string &name_template() const { return name_template_; }
const std::string &help_text() const { return help_text_; }

const std::vector<std::pair<std::string, std::string>> cmds() const {
std::vector<std::pair<std::string, std::string>> ret;
for (auto &cmd : cmds_)
const std::vector<std::pair<std::string, CommandArgType>> cmds() const {
std::vector<std::pair<std::string, CommandArgType>> ret;
for (auto &cmd : cmds_) {
ret.push_back(std::make_pair(cmd.cmd, cmd.arg_type));
}
return ret;
}

Expand All @@ -158,6 +167,8 @@ class ModuleBuilder {

CommandResponse RunInit(Module *m, const google::protobuf::Any &arg) const;

const Descriptor *init_descriptor() const { return init_descriptor_; }

private:
const std::function<Module *()> module_generator_;

Expand All @@ -169,6 +180,7 @@ class ModuleBuilder {
const std::string help_text_;
const Commands cmds_;
const module_init_func_t init_func_;
const Descriptor *init_descriptor_;
};

class Task;
Expand Down Expand Up @@ -723,7 +735,8 @@ static inline void set_attr(Module *m, int attr_id, bess::Packet *pkt, T val) {
ModuleBuilder::RegisterModuleClass( \
std::function<Module *()>([]() { return new _MOD(); }), #_MOD, \
_NAME_TEMPLATE, _HELP, _MOD::kNumIGates, _MOD::kNumOGates, \
_MOD::cmds, MODULE_INIT_FUNC(&_MOD::Init)); \
_MOD::cmds, MODULE_INIT_FUNC(&_MOD::Init), \
MODULE_INIT_DESC(&_MOD::Init)); \
} \
~_MOD##_class() { ModuleBuilder::DeregisterModuleClass(#_MOD); } \
};
Expand Down
6 changes: 3 additions & 3 deletions core/modules/acl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
#include "../utils/udp.h"

const Commands ACL::cmds = {
{"add", "ACLArg", MODULE_CMD_FUNC(&ACL::CommandAdd),
{"add", bess::pb::ACLArg::descriptor(), MODULE_CMD_FUNC(&ACL::CommandAdd),
Command::THREAD_UNSAFE},
{"clear", "EmptyArg", MODULE_CMD_FUNC(&ACL::CommandClear),
Command::THREAD_UNSAFE}};
{"clear", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&ACL::CommandClear), Command::THREAD_UNSAFE}};

CommandResponse ACL::Init(const bess::pb::ACLArg &arg) {
for (const auto &rule : arg.rules()) {
Expand Down
4 changes: 2 additions & 2 deletions core/modules/arp_responder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ using bess::utils::Arp;
using bess::utils::be16_t;

const Commands ArpResponder::cmds = {
{"add", "ArpResponderArg", MODULE_CMD_FUNC(&ArpResponder::CommandAdd),
Command::THREAD_UNSAFE}};
{"add", bess::pb::ArpResponderArg::descriptor(),
MODULE_CMD_FUNC(&ArpResponder::CommandAdd), Command::THREAD_UNSAFE}};

CommandResponse ArpResponder::CommandAdd(const bess::pb::ArpResponderArg &arg) {
be32_t ip_addr;
Expand Down
14 changes: 7 additions & 7 deletions core/modules/bpf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@
#define SNAPLEN 0xffff

const Commands BPF::cmds = {
{"add", "BPFArg", MODULE_CMD_FUNC(&BPF::CommandAdd),
{"add", bess::pb::BPFArg::descriptor(), MODULE_CMD_FUNC(&BPF::CommandAdd),
Command::THREAD_UNSAFE},
{"delete", "BPFArg", MODULE_CMD_FUNC(&BPF::CommandDelete),
Command::THREAD_UNSAFE},
{"clear", "EmptyArg", MODULE_CMD_FUNC(&BPF::CommandClear),
Command::THREAD_UNSAFE},
{"get_initial_arg", "EmptyArg", MODULE_CMD_FUNC(&BPF::GetInitialArg),
Command::THREAD_SAFE}};
{"delete", bess::pb::BPFArg::descriptor(),
MODULE_CMD_FUNC(&BPF::CommandDelete), Command::THREAD_UNSAFE},
{"clear", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&BPF::CommandClear), Command::THREAD_UNSAFE},
{"get_initial_arg", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&BPF::GetInitialArg), Command::THREAD_SAFE}};

CommandResponse BPF::Init(const bess::pb::BPFArg &arg) {
return CommandAdd(arg);
Expand Down
8 changes: 5 additions & 3 deletions core/modules/drr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ uint32_t RoundToPowerTwo(uint32_t v) {
}

const Commands DRR::cmds = {
{"set_quantum_size", "DRRQuantumArg",
{"set_quantum_size", bess::pb::DRRQuantumArg::descriptor(),
MODULE_CMD_FUNC(&DRR::CommandQuantumSize), Command::THREAD_UNSAFE},
{"set_max_flow_queue_size", "DRRMaxFlowQueueSizeArg",
{"set_max_flow_queue_size", bess::pb::DRRMaxFlowQueueSizeArg::descriptor(),
MODULE_CMD_FUNC(&DRR::CommandMaxFlowQueueSize), Command::THREAD_UNSAFE}};

DRR::DRR()
Expand Down Expand Up @@ -152,7 +152,9 @@ struct task_result DRR::RunTask(Context *ctx, bess::PacketBatch *batch,
void *) {
if (children_overload_ > 0) {
return {
.block = true, .packets = 0, .bits = 0,
.block = true,
.packets = 0,
.bits = 0,
};
}

Expand Down
4 changes: 2 additions & 2 deletions core/modules/dump.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
static const uint64_t DEFAULT_INTERVAL_NS = 1 * NS_PER_SEC; /* 1 sec */

const Commands Dump::cmds = {
{"set_interval", "DumpArg", MODULE_CMD_FUNC(&Dump::CommandSetInterval),
Command::THREAD_UNSAFE},
{"set_interval", bess::pb::DumpArg::descriptor(),
MODULE_CMD_FUNC(&Dump::CommandSetInterval), Command::THREAD_UNSAFE},
};

CommandResponse Dump::Init(const bess::pb::DumpArg &arg) {
Expand Down
21 changes: 11 additions & 10 deletions core/modules/exact_match.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,20 @@ static inline int is_valid_gate(gate_idx_t gate) {
}

const Commands ExactMatch::cmds = {
{"get_initial_arg", "EmptyArg", MODULE_CMD_FUNC(&ExactMatch::GetInitialArg),
Command::THREAD_SAFE},
{"get_runtime_config", "EmptyArg",
{"get_initial_arg", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::GetInitialArg), Command::THREAD_SAFE},
{"get_runtime_config", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::GetRuntimeConfig), Command::THREAD_SAFE},
{"set_runtime_config", "ExactMatchConfig",
{"set_runtime_config", bess::pb::ExactMatchConfig::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::SetRuntimeConfig), Command::THREAD_UNSAFE},
{"add", "ExactMatchCommandAddArg", MODULE_CMD_FUNC(&ExactMatch::CommandAdd),
Command::THREAD_UNSAFE},
{"delete", "ExactMatchCommandDeleteArg",
{"add", bess::pb::ExactMatchCommandAddArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::CommandAdd), Command::THREAD_UNSAFE},
{"delete", bess::pb::ExactMatchCommandDeleteArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::CommandDelete), Command::THREAD_UNSAFE},
{"clear", "EmptyArg", MODULE_CMD_FUNC(&ExactMatch::CommandClear),
Command::THREAD_UNSAFE},
{"set_default_gate", "ExactMatchCommandSetDefaultGateArg",
{"clear", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::CommandClear), Command::THREAD_UNSAFE},
{"set_default_gate",
bess::pb::ExactMatchCommandSetDefaultGateArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::CommandSetDefaultGate),
Command::THREAD_SAFE}};

Expand Down
Loading