From: Rafał Miłecki Date: Fri, 16 Aug 2019 14:14:27 +0000 (+0200) Subject: system: support passing "options" to the "sysupgrade" ubus method X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=95580316bc2d37d9261691ea99dae518bde46836;p=oweals%2Fprocd.git system: support passing "options" to the "sysupgrade" ubus method Object passed as "options" gets translated into environment variables UPGRADE_OPT_*. E.g. "options": { "foo": 5 } will result in setting UPGRADE_OPT_FOO=5. This allows stage2 sysupgrade to get options explicitly. So far it was guessing what to do by checking for existence of some files (e.g. sysupgrade.tgz). Signed-off-by: Rafał Miłecki --- diff --git a/initd/preinit.c b/initd/preinit.c index fbb36df..2b4df4b 100644 --- a/initd/preinit.c +++ b/initd/preinit.c @@ -75,7 +75,7 @@ check_sysupgrade(void) fclose(sysupgrade); - sysupgrade_exec_upgraded(prefix, path, command); + sysupgrade_exec_upgraded(prefix, path, command, NULL); while (true) sleep(1); diff --git a/system.c b/system.c index 8ed3f93..738f327 100644 --- a/system.c +++ b/system.c @@ -380,6 +380,7 @@ enum { SYSUPGRADE_PATH, SYSUPGRADE_PREFIX, SYSUPGRADE_COMMAND, + SYSUPGRADE_OPTIONS, __SYSUPGRADE_MAX }; @@ -387,6 +388,7 @@ static const struct blobmsg_policy sysupgrade_policy[__SYSUPGRADE_MAX] = { [SYSUPGRADE_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, [SYSUPGRADE_PREFIX] = { .name = "prefix", .type = BLOBMSG_TYPE_STRING }, [SYSUPGRADE_COMMAND] = { .name = "command", .type = BLOBMSG_TYPE_STRING }, + [SYSUPGRADE_OPTIONS] = { .name = "options", .type = BLOBMSG_TYPE_TABLE }, }; static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj, @@ -404,7 +406,8 @@ static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj, sysupgrade_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]), blobmsg_get_string(tb[SYSUPGRADE_PATH]), - tb[SYSUPGRADE_COMMAND] ? blobmsg_get_string(tb[SYSUPGRADE_COMMAND]) : NULL); + tb[SYSUPGRADE_COMMAND] ? blobmsg_get_string(tb[SYSUPGRADE_COMMAND]) : NULL, + tb[SYSUPGRADE_OPTIONS]); /* sysupgrade_exec_upgraded() will never return unless something has gone wrong */ return UBUS_STATUS_UNKNOWN_ERROR; diff --git a/sysupgrade.c b/sysupgrade.c index 07e33f7..a5bad9a 100644 --- a/sysupgrade.c +++ b/sysupgrade.c @@ -17,15 +17,20 @@ #include "watchdog.h" #include "sysupgrade.h" +#include #include #include #include +#include -void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command) +void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command, + struct blob_attr *options) { char *wdt_fd = watchdog_fd(); char *argv[] = { "/sbin/upgraded", NULL, NULL, NULL}; + struct blob_attr *option; + int rem; int ret; ret = chroot(prefix); @@ -41,6 +46,55 @@ void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command) watchdog_set_cloexec(false); setenv("WDTFD", wdt_fd, 1); } + + blobmsg_for_each_attr(option, options, rem) { + const char *prefix = "UPGRADE_OPT_"; + char value[11]; + char *name; + char *c; + int tmp; + + if (asprintf(&name, "%s%s", prefix, blobmsg_name(option)) <= 0) + continue; + for (c = name + strlen(prefix); *c; c++) { + if (isalnum(*c) || *c == '_') { + *c = toupper(*c); + } else { + c = NULL; + break; + } + } + + if (!c) { + fprintf(stderr, "Option \"%s\" contains invalid characters\n", + blobmsg_name(option)); + free(name); + continue; + } + + switch (blobmsg_type(option)) { + case BLOBMSG_TYPE_INT32: + tmp = blobmsg_get_u32(option); + break; + case BLOBMSG_TYPE_INT16: + tmp = blobmsg_get_u16(option); + break; + case BLOBMSG_TYPE_INT8: + tmp = blobmsg_get_u8(option); + break; + default: + fprintf(stderr, "Option \"%s\" has unsupported type: %d\n", + blobmsg_name(option), blobmsg_type(option)); + free(name); + continue; + } + snprintf(value, sizeof(value), "%u", tmp); + + setenv(name, value, 1); + + free(name); + } + execvp(argv[0], argv); /* Cleanup on failure */ diff --git a/sysupgrade.h b/sysupgrade.h index 8c09fc9..c84e494 100644 --- a/sysupgrade.h +++ b/sysupgrade.h @@ -14,8 +14,10 @@ #ifndef __PROCD_SYSUPGRADE_H #define __PROCD_SYSUPGRADE_H +struct blob_attr; -void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command); +void sysupgrade_exec_upgraded(const char *prefix, char *path, char *command, + struct blob_attr *options); #endif