summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorJohn Crispin <john@phrozen.org>2021-11-12 19:59:29 +0100
committerDaniel Golle <daniel@makrotopia.org>2021-11-23 13:56:47 +0000
commit87b583635475c56ae5b8ec89233f6f292ba09765 (patch)
treee6eca305ab9a8533104c1332339e282529b04a0d /service
parentbf3fe0e8c02ff13171ea9f2a79703abc099105bf (diff)
downloadprocd-87b583635475c56ae5b8ec89233f6f292ba09765.tar.gz
procd: add full service shutdown prior to sysupgrade
Currently OpenWrt will use the kill loop in stage2 to stop tasks. This can fail as seen with wpa_supplicant not properly shutting down with certain mesh configurations. Trigger the existing service_stop() code path for all services just before exec'ing to upgraded. Signed-off-by: John Crispin <john@phrozen.org> [make use of *_safe function now introduced for that purpose, also stop container instances] Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Diffstat (limited to 'service')
-rw-r--r--service/service.c28
-rw-r--r--service/service.h1
2 files changed, 29 insertions, 0 deletions
diff --git a/service/service.c b/service/service.c
index 48825c3..5c66fb2 100644
--- a/service/service.c
+++ b/service/service.c
@@ -653,6 +653,34 @@ service_handle_state(struct ubus_context *ctx, struct ubus_object *obj,
return UBUS_STATUS_OK;
}
+static void
+service_avl_stop_all(struct avl_tree *sctree, unsigned int *term_timeout)
+{
+ struct service *s;
+
+ avl_for_each_element(sctree, s, avl) {
+ struct service_instance *in, *ptr;
+
+ vlist_for_each_element_safe(&s->instances, in, node, ptr) {
+ if (in->term_timeout > *term_timeout)
+ *term_timeout = in->term_timeout;
+ instance_stop(in, true);
+ }
+ }
+}
+
+void
+service_stop_all(void)
+{
+ unsigned int term_timeout = 0;
+
+ service_avl_stop_all(&containers, &term_timeout);
+ service_avl_stop_all(&services, &term_timeout);
+ /* ToDo: inittab */
+
+ sleep(term_timeout);
+}
+
static int
service_handle_update(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
diff --git a/service/service.h b/service/service.h
index e148369..6ddc04e 100644
--- a/service/service.h
+++ b/service/service.h
@@ -60,6 +60,7 @@ int service_start_early(char *name, char *cmdline, char *user, char *group);
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);
+void service_stop_all(void);