X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=system.c;h=2dbed51322d1e54576ec1882f9310cb56332010b;hp=c96cb632fec3bd6f5902608f9d28a59a9505d309;hb=9c9c71a4e476be1e93f4d4c2c0527b5df0ff3c90;hpb=3283d681f9da65b500ad0cb3d4550cb840ed481a diff --git a/system.c b/system.c index c96cb63..2dbed51 100644 --- a/system.c +++ b/system.c @@ -18,18 +18,19 @@ #include #include #include - +#include #include #include #include "procd.h" #include "watchdog.h" -#include "hotplug.h" - -#define HOSTNAME_PATH "/proc/sys/kernel/hostname" static struct blob_buf b; +static int notify; +static struct ubus_context *_ctx; + +int upgrade_running = 0; static int system_board(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, @@ -189,10 +190,7 @@ static int system_upgrade(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { - procd_reconnect_ubus(0); - log_shutdown(); - hotplug_shutdown(); - + upgrade_running = 1; return 0; } @@ -259,11 +257,94 @@ static int watchdog_set(struct ubus_context *ctx, struct ubus_object *obj, return 0; } +enum { + SIGNAL_PID, + SIGNAL_NUM, + __SIGNAL_MAX +}; + +static const struct blobmsg_policy signal_policy[__SIGNAL_MAX] = { + [SIGNAL_PID] = { .name = "pid", .type = BLOBMSG_TYPE_INT32 }, + [SIGNAL_NUM] = { .name = "signum", .type = BLOBMSG_TYPE_INT32 }, +}; + +static int proc_signal(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__SIGNAL_MAX]; + + if (!msg) + return UBUS_STATUS_INVALID_ARGUMENT; + + blobmsg_parse(signal_policy, __SIGNAL_MAX, tb, blob_data(msg), blob_len(msg)); + if (!tb[SIGNAL_PID || !tb[SIGNAL_NUM]]) + return UBUS_STATUS_INVALID_ARGUMENT; + + kill(blobmsg_get_u32(tb[SIGNAL_PID]), blobmsg_get_u32(tb[SIGNAL_NUM])); + + return 0; +} + +enum { + NAND_PATH, + __NAND_MAX +}; + +static const struct blobmsg_policy nand_policy[__NAND_MAX] = { + [NAND_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, +}; + +static void +procd_spawn_upgraded(char *path) +{ + char *wdt_fd = watchdog_fd(); + char *argv[] = { "/tmp/upgraded", NULL, NULL}; + + argv[1] = path; + + DEBUG(2, "Exec to upgraded now\n"); + if (wdt_fd) { + watchdog_no_cloexec(); + setenv("WDTFD", wdt_fd, 1); + } + execvp(argv[0], argv); +} + +static int nand_set(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__NAND_MAX]; + + if (!msg) + return UBUS_STATUS_INVALID_ARGUMENT; + + blobmsg_parse(nand_policy, __NAND_MAX, tb, blob_data(msg), blob_len(msg)); + if (!tb[NAND_PATH]) + return UBUS_STATUS_INVALID_ARGUMENT; + + procd_spawn_upgraded(blobmsg_get_string(tb[NAND_PATH])); + fprintf(stderr, "Yikees, something went wrong. no /sbin/upgraded ?\n"); + return 0; +} + +static void +procd_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj) +{ + notify = obj->has_subscribers; +} + + 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("watchdog", watchdog_set, watchdog_policy), + UBUS_METHOD("signal", proc_signal, signal_policy), + + /* must remain at the end as it ia not always loaded */ + UBUS_METHOD("nandupgrade", nand_set, nand_policy), }; static struct ubus_object_type system_object_type = @@ -274,12 +355,31 @@ static struct ubus_object system_object = { .type = &system_object_type, .methods = system_methods, .n_methods = ARRAY_SIZE(system_methods), + .subscribe_cb = procd_subscribe_cb, }; +void +procd_bcast_event(char *event, struct blob_attr *msg) +{ + int ret; + + if (!notify) + return; + + ret = ubus_notify(_ctx, &system_object, event, msg, -1); + if (ret) + fprintf(stderr, "Failed to notify log: %s\n", ubus_strerror(ret)); +} + void ubus_init_system(struct ubus_context *ctx) { + struct stat s; int ret; + if (stat("/sbin/upgraded", &s)) + system_object.n_methods -= 1; + + _ctx = ctx; ret = ubus_add_object(ctx, &system_object); if (ret) ERROR("Failed to add object: %s\n", ubus_strerror(ret));