Sometimes stage2 is unable to kill all processes which results in a failed upgrade.
Rather than fully relying on stage2, let procd gracefully terminate the services in the services AVL tree before handing control to upgraded. Signed-off-by: Daniel Bailey <[email protected]> --- service/service.c | 22 ++++++++++++++++++++++ service/service.h | 1 + system.c | 6 ++++++ 3 files changed, 29 insertions(+) diff --git a/service/service.c b/service/service.c index fcf0215..7191cec 100644 --- a/service/service.c +++ b/service/service.c @@ -837,6 +837,28 @@ service_start_early(char *name, char *cmdline) return service_handle_set(NULL, NULL, NULL, "add", b.head); } +int +service_delete_all(void) +{ + struct service *s, *safe; + const struct avl_tree *tree = &services; + int ret; + + avl_for_each_element_safe(tree, s, avl, safe) { + blob_buf_init(&b, 0); + blobmsg_add_string(&b, "name", s->name); + + ret = service_handle_delete(NULL, NULL, NULL, NULL, b.head); + + if (ret) { + ERROR("failed to delete service '%s'", s->name); + return ret; + } + } + + return 0; +} + void service_stopped(struct service *s) { _service_stopped(s, false); diff --git a/service/service.h b/service/service.h index fac5da9..09ed409 100644 --- a/service/service.h +++ b/service/service.h @@ -56,6 +56,7 @@ void service_validate_add(struct service *s, struct blob_attr *attr); void service_validate_dump(struct blob_buf *b, struct service *s); void service_validate_dump_all(struct blob_buf *b, char *p, char *s); int service_start_early(char *name, char *cmdline); +int service_delete_all(void); void service_stopped(struct service *s); void service_validate_del(struct service *s); void service_event(const char *type, const char *service, const char *instance); diff --git a/system.c b/system.c index 0fb98f1..38a0539 100644 --- a/system.c +++ b/system.c @@ -30,6 +30,7 @@ #include <libubox/uloop.h> #include "procd.h" +#include "service/service.h" #include "sysupgrade.h" #include "watchdog.h" @@ -695,6 +696,11 @@ static int sysupgrade(struct ubus_context *ctx, struct ubus_object *obj, return UBUS_STATUS_NOT_SUPPORTED; } + if (service_delete_all()) { + sysupgrade_error(ctx, req, "Failed to delete all services"); + return UBUS_STATUS_UNKNOWN_ERROR; + } + sysupgrade_exec_upgraded(blobmsg_get_string(tb[SYSUPGRADE_PREFIX]), blobmsg_get_string(tb[SYSUPGRADE_PATH]), tb[SYSUPGRADE_BACKUP] ? blobmsg_get_string(tb[SYSUPGRADE_BACKUP]) : NULL, -- 2.25.1 _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
