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
pgpeJgB70QQOf.pgp
Description: PGP signature
_______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
