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/control_dbus.c b/control_dbus.c
index c8c6463..e22d736 100644
--- a/control_dbus.c
+++ b/control_dbus.c
@@ -2,12 +2,14 @@
// Copyright (C) 2018 IBM Corp.
#include <assert.h>
#include <errno.h>
+#include <stdlib.h>
#include <systemd/sd-bus.h>
#include "common.h"
#include "dbus.h"
#include "control_dbus.h"
#include "mboxd.h"
+#include "vpnor/mboxd_pnor_partition_table.h"
typedef int (*control_action)(struct mbox_context *context);
@@ -108,6 +110,90 @@
return sd_bus_send(NULL, n, NULL);
}
+static int control_dbus_set_backend(sd_bus_message *m, void *userdata,
+ sd_bus_error *ret_error)
+{
+ struct mbox_context *context;
+ struct backend backend;
+ sd_bus_message *n;
+ const char *name;
+ int rc;
+
+ context = (struct mbox_context *) userdata;
+ if (!context) {
+ MSG_ERR("DBUS Internal Error\n");
+ return -EINVAL;
+ }
+
+ rc = sd_bus_message_read_basic(m, 's', &name);
+ if (rc < 0) {
+ MSG_ERR("DBUS error reading message: %s\n", strerror(-rc));
+ return rc;
+ }
+
+ if (!strcmp(name, "vpnor")) {
+ struct vpnor_partition_paths paths;
+
+ vpnor_default_paths(&paths);
+ backend = backend_get_vpnor();
+ rc = control_set_backend(context, &backend, &paths);
+ if (rc < 0)
+ return rc;
+ } else if (!strcmp(name, "mtd")) {
+ char **paths = NULL;
+ char *path = NULL;
+
+ rc = sd_bus_message_read_strv(m, &paths);
+ if (rc < 0)
+ return rc;
+
+ if (paths && *paths)
+ path = *paths;
+ else
+ path = get_dev_mtd();
+
+ backend = backend_get_mtd();
+
+ rc = control_set_backend(context, &backend, path);
+ if (rc < 0)
+ return rc;
+
+ free(path);
+ free(paths);
+ } else if (!strcmp(name, "file")) {
+ char **paths = NULL;
+ char *path = NULL;
+
+ rc = sd_bus_message_read_strv(m, &paths);
+ if (rc < 0)
+ return rc;
+
+ if (!(paths && *paths))
+ return -EINVAL;
+
+ path = *paths;
+
+ backend = backend_get_file();
+
+ rc = control_set_backend(context, &backend, path);
+ if (rc < 0)
+ return rc;
+
+ free(path);
+ free(paths);
+ } else {
+ return -EINVAL;
+ }
+
+ rc = sd_bus_message_new_method_return(m, &n);
+ if (rc < 0) {
+ MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc);
+ return rc;
+ }
+
+ return sd_bus_send(NULL, n, NULL);
+}
+
static int control_dbus_get_u8(sd_bus *bus, const char *path,
const char *interface, const char *property,
sd_bus_message *reply, void *userdata,
@@ -144,6 +230,8 @@
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Resume", "b", NULL, &control_dbus_resume,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("SetBackend", "sas", NULL, &control_dbus_set_backend,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_PROPERTY("DaemonState", "y", &control_dbus_get_u8, 0,
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("LpcState", "y", &control_dbus_get_u8, 0,