[OpenWrt-Devel] [PATCH] sysupgrade: kill services before upgraded/stage2

Daniel Bailey danielb at meshplusplus.com
Thu Jun 4 20:32:27 EDT 2020


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 <danielb at meshplusplus.com>
---
 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
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list