mboxd: Add backend DBus interface and commandline options
Also implement a backend commandline option to mboxctl: `mboxctl
--backend ...`, to allow easy run-time switching of the backend from the
commandline.
Switching between VPNOR and file backends via mboxctl was tested on
Witherspoon, and MTD and file backends on Romulus.
Change-Id: Iaf0e27ecf1d5cdd9e3a31729fb179096bbc37408
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/mboxctl.c b/mboxctl.c
index 9dbc149..b001fb9 100644
--- a/mboxctl.c
+++ b/mboxctl.c
@@ -4,6 +4,7 @@
#include <errno.h>
#include <getopt.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -25,7 +26,8 @@
"\t\t--suspend\t\t- suspend the daemon to inhibit flash accesses (0)\n" \
"\t\t--resume\t\t- resume the daemon (1)\n" \
"\t\t\targ[0]: < \"clean\" | \"modified\" >\n" \
-"\t\t--clear-cache\t- tell the daemon to discard any caches (0)\n"
+"\t\t--clear-cache\t- tell the daemon to discard any caches (0)\n" \
+"\t\t--backend <vpnor|mtd[:PATH]|file:PATH>\n"
#define NAME "Mailbox Control"
@@ -269,6 +271,95 @@
return rc;
}
+static int handle_cmd_backend(struct mboxctl_context *context, char *sarg)
+{
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus_message *m = NULL, *n = NULL;
+ char *delim = NULL;
+ char *strv[2];
+ int rc;
+
+ if (!sarg) {
+ MSG_ERR("Backend command takes an argument\n");
+ return -EINVAL;
+ }
+
+ rc = sd_bus_message_new_method_call(context->bus, &m,
+ MBOX_DBUS_NAME,
+ MBOX_DBUS_OBJECT,
+ MBOX_DBUS_CONTROL_IFACE,
+ "SetBackend");
+ if (rc < 0) {
+ MSG_ERR("Failed to init method call: %s\n",
+ strerror(-rc));
+ goto out;
+ }
+
+ if (!strncmp(sarg, "vpnor", strlen("vpnor"))) {
+ if (strchr(sarg, ':')) {
+ MSG_ERR("Path parameter not supported for vpnor\n");
+ rc = -EINVAL;
+ goto out;
+ }
+
+ rc = sd_bus_message_append(m, "s", "vpnor");
+ if (rc < 0)
+ goto out;
+ } else if (!strncmp(sarg, "mtd", strlen("mtd"))) {
+ rc = sd_bus_message_append(m, "s", "mtd");
+ if (rc < 0)
+ goto out;
+ } else if (!strncmp(sarg, "file", strlen("file"))) {
+ rc = sd_bus_message_append(m, "s", "file");
+ if (rc < 0)
+ goto out;
+ } else {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ delim = strchr(sarg, ':');
+ if (delim) {
+ char *path;
+
+ path = realpath(delim + 1, NULL);
+ if (!path) {
+ MSG_ERR("Failed to resolve path: %s\n",
+ strerror(errno));
+ rc = -errno;
+ goto out;
+ }
+
+ strv[0] = path;
+ strv[1] = NULL;
+
+ rc = sd_bus_message_append_strv(m, &strv[0]);
+ free(path);
+ if (rc < 0)
+ goto out;
+ } else {
+ strv[0] = NULL;
+ strv[1] = NULL;
+ rc = sd_bus_message_append_strv(m, &strv[0]);
+ if (rc < 0)
+ goto out;
+ }
+
+ rc = sd_bus_call(context->bus, m, 0, &error, &n);
+ if (rc < 0) {
+ MSG_ERR("Failed to post message: %s\n", strerror(-rc));
+ goto out;
+ }
+
+ MSG_OUT("SetBackend: %s\n", rc < 0 ? strerror(-rc) : "Success");
+
+out:
+ sd_bus_error_free(&error);
+ sd_bus_message_unref(m);
+
+ return rc < 0 ? rc : 0;
+}
+
static int parse_cmdline(struct mboxctl_context *context, int argc, char **argv)
{
int opt, rc = -1;
@@ -284,6 +375,7 @@
{ "suspend", no_argument, 0, 'u' },
{ "resume", required_argument, 0, 'e' },
{ "clear-cache", no_argument, 0, 'c' },
+ { "backend", required_argument, 0, 'b' },
{ "version", no_argument, 0, 'v' },
{ "help", no_argument, 0, 'h' },
{ 0, 0, 0, 0 }
@@ -325,6 +417,9 @@
case 'c':
rc = handle_cmd_modified(context);
break;
+ case 'b':
+ rc = handle_cmd_backend(context, optarg);
+ break;
case 'v':
MSG_OUT("%s V%s\n", NAME, PACKAGE_VERSION);
rc = 0;