Skip to content

Commit

Permalink
mctpd: Add toml-based configuration interface
Browse files Browse the repository at this point in the history
This change adds a basic configuration interface, using a simple toml
syntax.

This allows configuration of the existing mctpd parameters: bus-owner
mode, the mctp timeout, and the UUID.

We ship a small example configuration under conf/.

Signed-off-by: Jeremy Kerr <[email protected]>
  • Loading branch information
jk-ozlabs committed Feb 6, 2024
1 parent a833b71 commit 41dd75d
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
2. mctpd: Allow recovery of devices reporting a nil UUID for development
3. mctpd: Allow configuring .Connectivity as writable for development
4. mctpd: Add AssignEndpointStatic for static EID allocations
5. mctpd: Add a configuration file facility

### Changed

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ configured (ie., interfaces are enabled, and local addresses have been
assigned). There are two sample systemd unit files under the conf/ directory, to
coordinate the local setup and the supervision of the mctpd process.

`mctpd` can read some basic configuration from a file, if the `-c FILE` argument
is given. An example configuration is in [`conf/mctpd.conf`](conf/mctpd.conf).

The `mctpd` daemon will expose a dbus interface, claiming the bus name
`xyz.openbmc_project.MCTP` and object path `/xyz/openbmc_project/mctp`. This
provides a few functions for configuring remote endpoints:
Expand Down
10 changes: 10 additions & 0 deletions conf/mctpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Mode: either bus-owner or endpoint
mode = "bus-owner"

# MCTP protocol configuration. Used for both endpoint and bus-owner modes.
[mctp]
message_timeout_ms = 30

# Specify a UUID: not generally required - mctpd will query the system UUID
# where available.
# uuid = "21f0f554-7f7c-4211-9ca1-6d0f000ea9e7"
9 changes: 7 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ util_sources = ['src/mctp-util.c']
netlink_sources = ['src/mctp-netlink.c']
ops_sources = ['src/mctp-ops.c']

toml_dep = declare_dependency(
sources: ['lib/tomlc99/toml.c'],
include_directories: include_directories('lib/tomlc99'),
)

executable('mctp',
sources: ['src/mctp.c'] + netlink_sources + util_sources + ops_sources,
install: true,
Expand All @@ -56,7 +61,7 @@ if libsystemd.found()
sources: [
'src/mctpd.c',
] + netlink_sources + util_sources + ops_sources,
dependencies: libsystemd,
dependencies: [libsystemd, toml_dep],
install: true,
install_dir: get_option('sbindir'),
)
Expand All @@ -67,7 +72,7 @@ if libsystemd.found()
'tests/mctp-ops-test.c',
] + netlink_sources + util_sources,
include_directories: include_directories('src'),
dependencies: libsystemd,
dependencies: [libsystemd, toml_dep],
)
endif

Expand Down
124 changes: 115 additions & 9 deletions src/mctpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include <systemd/sd-bus.h>
#include <systemd/sd-id128.h>

#include "toml.h"

#include "mctp.h"
#include "mctp-util.h"
#include "mctp-netlink.h"
Expand Down Expand Up @@ -136,6 +138,10 @@ typedef struct peer peer;
struct ctx {
sd_event *event;
sd_bus *bus;

// Configuration
const char *config_filename;

// Main instance for link/address state and listening for updates
mctp_nl *nl;

Expand Down Expand Up @@ -3534,9 +3540,10 @@ static int setup_testing(ctx *ctx) {

static void print_usage(ctx *ctx)
{
fprintf(stderr, "mctpd [-v] [-N]\n");
fprintf(stderr, "mctpd [-v] [-N] [-c FILE]\n");
fprintf(stderr, " -v verbose\n");
fprintf(stderr, " -N testing mode. Not safe for production\n");
fprintf(stderr, " -c FILE read config from FILE\n");
}

static int parse_args(ctx *ctx, int argc, char **argv)
Expand All @@ -3545,12 +3552,13 @@ static int parse_args(ctx *ctx, int argc, char **argv)
{ .name = "help", .has_arg = no_argument, .val = 'h' },
{ .name = "verbose", .has_arg = no_argument, .val = 'v' },
{ .name = "testing", .has_arg = no_argument, .val = 'N' },
{ .name = "config", .has_arg = required_argument, .val = 'c' },
{ 0 },
};
int c;

for (;;) {
c = getopt_long(argc, argv, "+hvN", options, NULL);
c = getopt_long(argc, argv, "+hvNc:", options, NULL);
if (c == -1)
break;

Expand All @@ -3561,6 +3569,9 @@ static int parse_args(ctx *ctx, int argc, char **argv)
case 'v':
ctx->verbose = true;
break;
case 'c':
ctx->config_filename = strdup(optarg);
break;
case 'h':
default:
print_usage(ctx);
Expand All @@ -3570,6 +3581,20 @@ static int parse_args(ctx *ctx, int argc, char **argv)
return 0;
}

static int parse_config_mode(ctx *ctx, const char *mode)
{
if (!strcmp(mode, "bus-owner")) {
ctx->bus_owner = true;
} else if (!strcmp(mode, "endpoint")) {
ctx->bus_owner = false;
} else {
warnx("invalid value '%s' for mode configuration", mode);
return -1;
}

return 0;
}

static int fill_uuid(ctx *ctx)
{
int rc;
Expand All @@ -3594,16 +3619,91 @@ static int fill_uuid(ctx *ctx)
return rc;
}

static int setup_config(ctx *ctx)
static int parse_config_mctp(ctx *ctx, toml_table_t *mctp_tab)
{
toml_datum_t val;
int rc;

val = toml_int_in(mctp_tab, "message_timeout_ms");
if (val.ok) {
int64_t i = val.u.i;
if (i <= 0 || i > 100 * 1000) {
warnx("invalid message_timeout_ms value");
return -1;
}
ctx->mctp_timeout = i * 1000;
}

val = toml_string_in(mctp_tab, "uuid");
if (val.ok) {
rc = sd_id128_from_string(val.u.s, (void *)&ctx->uuid);
free(val.u.s);
if (rc) {
warnx("invalid UUID value");
return rc;
}
} else {
rc = fill_uuid(ctx);
if (rc)
return rc;
}

return 0;
}

static int parse_config(ctx *ctx)
{
toml_table_t *conf_root, *mctp_tab;
char errbuf[256] = { 0 };
toml_datum_t val;
FILE *fp;
int rc;
// TODO: this will go in a config file or arguments.

if (!ctx->config_filename)
return 0;

rc = -1;
fp = fopen(ctx->config_filename, "r");
if (!fp) {
warn("can't open configuration file %s", ctx->config_filename);
return -1;
}

conf_root = toml_parse_file(fp, errbuf, sizeof(errbuf));
if (!conf_root) {
warnx("can't parse configuration file %s: %s",
ctx->config_filename, errbuf);
goto out_close;
}

val = toml_string_in(conf_root, "mode");
if (val.ok) {
rc = parse_config_mode(ctx, val.u.s);
free(val.u.s);
if (rc)
goto out_free;
}

mctp_tab = toml_table_in(conf_root, "mctp");
if (mctp_tab) {
rc = parse_config_mctp(ctx, mctp_tab);
if (rc)
goto out_free;
}

rc = 0;

out_free:
toml_free(conf_root);
out_close:
fclose(fp);
return rc;
}

static void setup_config_defaults(ctx *ctx)
{
ctx->mctp_timeout = 250000; // 250ms
ctx->bus_owner = true;
rc = fill_uuid(ctx);
if (rc < 0)
return rc;
return 0;
}

int main(int argc, char **argv)
Expand All @@ -3613,14 +3713,20 @@ int main(int argc, char **argv)

setlinebuf(stdout);

setup_config(ctx);
setup_config_defaults(ctx);
mctp_ops_init();

rc = parse_args(ctx, argc, argv);
if (rc != 0) {
return rc;
}

rc = parse_config(ctx);
if (rc) {
err(EXIT_FAILURE, "Can't load configuration file %s",
ctx->config_filename);
}

ctx->nl = mctp_nl_new(false);
if (!ctx->nl) {
warnx("Failed creating netlink object");
Expand Down

0 comments on commit 41dd75d

Please sign in to comment.