sysupgrade needs to run as the only process on devices having their
rootfs on block and ubi. Introduce an exec call to be used by
sysupgrade for that purpose.

Signed-off-by: Daniel Golle <[email protected]>
---
 system.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/system.c b/system.c
index d5bf000..1350f1b 100644
--- a/system.c
+++ b/system.c
@@ -186,6 +186,19 @@ static int system_info(struct ubus_context *ctx, struct 
ubus_object *obj,
        return UBUS_STATUS_OK;
 }
 
+enum {
+       EXEC_PWD,
+       EXEC_COMMAND,
+       EXEC_ARGUMENTS,
+       __EXEC_MAX
+};
+
+static const struct blobmsg_policy exec_policy[__EXEC_MAX] = {
+       [EXEC_PWD] = { .name = "pwd", .type = BLOBMSG_TYPE_STRING },
+       [EXEC_COMMAND] = { .name = "command", .type = BLOBMSG_TYPE_STRING },
+       [EXEC_ARGUMENTS] = { .name = "arguments", .type = BLOBMSG_TYPE_ARRAY },
+};
+
 static int system_upgrade(struct ubus_context *ctx, struct ubus_object *obj,
                        struct ubus_request_data *req, const char *method,
                        struct blob_attr *msg)
@@ -194,6 +207,52 @@ static int system_upgrade(struct ubus_context *ctx, struct 
ubus_object *obj,
        return 0;
 }
 
+static int system_exec(struct ubus_context *ctx, struct ubus_object *obj,
+                       struct ubus_request_data *req, const char *method,
+                       struct blob_attr *msg)
+{
+       struct blob_attr *tb[__EXEC_MAX];
+       const char *pwd;
+       const char *cmd;
+       struct blob_attr *cur;
+       int i = 0, rem;
+       const char **argv;
+
+       if (!msg)
+               return UBUS_STATUS_INVALID_ARGUMENT;
+
+       blobmsg_parse(exec_policy, __EXEC_MAX, tb, blob_data(msg), 
blob_len(msg));
+       if (!tb[EXEC_PWD] || !tb[EXEC_COMMAND] ||!tb[EXEC_ARGUMENTS])
+               return UBUS_STATUS_INVALID_ARGUMENT;
+       pwd = strdup(blobmsg_get_string(tb[EXEC_PWD]));
+       cmd = strdup(blobmsg_get_string(tb[EXEC_COMMAND]));
+       rem = blob_len(tb[EXEC_ARGUMENTS]);
+       blobmsg_for_each_attr(cur, tb[EXEC_ARGUMENTS], rem) {
+               ++i;
+       }
+       argv = calloc(i + 2, sizeof(char*));
+       i = 0;
+       argv[0] = strdup(cmd);
+       rem = blob_len(tb[EXEC_ARGUMENTS]);
+       blobmsg_for_each_attr(cur, tb[EXEC_ARGUMENTS], rem) {
+               argv[++i] = blobmsg_get_string(cur);
+       }
+       argv[++i] = NULL;
+
+       if (!cmd || !strlen(cmd)) {
+               LOG("command should not be empty!");
+               return 0;
+       }
+
+       LOG("replacing init, pwd: '%s', cmd: '%s'\n", pwd, cmd);
+       procd_inittab_run("shutdown");
+       if (pwd && strlen(pwd)) {
+               chdir(pwd);
+       }
+       execv(cmd, (char * const*)argv);
+       return 0;
+}
+
 enum {
        WDT_FREQUENCY,
        WDT_TIMEOUT,
@@ -296,6 +355,7 @@ static const struct ubus_method system_methods[] = {
        UBUS_METHOD_NOARG("board", system_board),
        UBUS_METHOD_NOARG("info",  system_info),
        UBUS_METHOD_NOARG("upgrade", system_upgrade),
+       UBUS_METHOD("exec", system_exec, exec_policy),
        UBUS_METHOD("watchdog", watchdog_set, watchdog_policy),
        UBUS_METHOD("signal", proc_signal, signal_policy),
 };
-- 
1.9.3

Attachment: pgpeJgB70QQOf.pgp
Description: PGP signature

_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to