diff options
| author | Felix Fietkau | 2024-12-17 18:49:19 +0000 |
|---|---|---|
| committer | Felix Fietkau | 2024-12-17 18:49:21 +0000 |
| commit | 2e206dbe77ecdbc715a5aa22f19397162a912e7e (patch) | |
| tree | e75786740f1dc49f927857014c7cd059e3a1da63 | |
| parent | e2f05deb93949f447d397e8cd3a341bc8e53cd38 (diff) | |
| download | procd-2e206dbe77ecdbc715a5aa22f19397162a912e7e.tar.gz | |
service: add support for triggers on service/instance data changes
To keep things simple, they report changes to all present data types if
any of the data fields changed. This can be refined if more fine grained
checks are needed.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
| -rw-r--r-- | service/instance.c | 6 | ||||
| -rw-r--r-- | service/service.c | 43 | ||||
| -rw-r--r-- | service/service.h | 1 |
3 files changed, 41 insertions, 9 deletions
diff --git a/service/instance.c b/service/instance.c index ed5d0a4..1c363fc 100644 --- a/service/instance.c +++ b/service/instance.c @@ -1580,6 +1580,10 @@ instance_update(struct service_instance *in, struct service_instance *in_new) } else { if (changed) instance_restart(in); + else if (!blobmsg_list_equal(&in->data, &in_new->data)) { + service_data_trigger(&in->data); + service_data_trigger(&in_new->data); + } instance_config_move(in, in_new); /* restart happens in the child callback handler */ } @@ -1588,6 +1592,7 @@ instance_update(struct service_instance *in, struct service_instance *in_new) void instance_free(struct service_instance *in) { + service_data_trigger(&in->data); instance_free_stdio(in); uloop_process_delete(&in->proc); uloop_timeout_cancel(&in->timeout); @@ -1654,6 +1659,7 @@ instance_init(struct service_instance *in, struct service *s, struct blob_attr * in->watchdog.timeout.cb = instance_watchdog; in->valid = instance_config_parse(in); + service_data_trigger(&in->data); } void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose) diff --git a/service/service.c b/service/service.c index bd0e290..f64b634 100644 --- a/service/service.c +++ b/service/service.c @@ -53,6 +53,17 @@ service_instance_add(struct service *s, struct blob_attr *attr) vlist_add(&s->instances, &in->node, (void *) in->name); } +void service_data_trigger(struct blobmsg_list *list) +{ + struct blobmsg_list_node *node; + + avl_for_each_element(&list->avl, node, avl) { + blob_buf_init(&b, 0); + blobmsg_add_string(&b, "name", blobmsg_name(node->data)); + trigger_event("service.data.update", b.head); + } +} + static void service_instance_update(struct vlist_tree *tree, struct vlist_node *node_new, struct vlist_node *node_old) @@ -121,6 +132,26 @@ static const struct blobmsg_policy service_set_attrs[__SERVICE_SET_MAX] = { }; static int +service_update_data(struct service *s, struct blob_attr *data) +{ + if (blob_attr_equal(s->data, data)) + return 0; + + free(s->data); + s->data = blob_memdup(data); + if (!s->data) + return -1; + + service_data_trigger(&s->data_blob); + blobmsg_list_free(&s->data_blob); + blobmsg_list_fill(&s->data_blob, blobmsg_data(s->data), + blobmsg_data_len(s->data), false); + service_data_trigger(&s->data_blob); + + return 0; +} + +static int service_update(struct service *s, struct blob_attr **tb, bool add) { struct blob_attr *cur; @@ -133,8 +164,6 @@ service_update(struct service *s, struct blob_attr **tb, bool add) } if (s->data) { - blobmsg_list_free(&s->data_blob); - free(s->data); s->data = NULL; } @@ -167,13 +196,9 @@ service_update(struct service *s, struct blob_attr **tb, bool add) vlist_flush(&s->instances); } - if (tb[SERVICE_SET_DATA] && blobmsg_data_len(tb[SERVICE_SET_DATA])) { - s->data = blob_memdup(tb[SERVICE_SET_DATA]); - if (!s->data) - return -1; - blobmsg_list_fill(&s->data_blob, blobmsg_data(s->data), - blobmsg_data_len(s->data), false); - } + if (tb[SERVICE_SET_DATA] && + service_update_data(s, tb[SERVICE_SET_DATA]) < 0) + return -1; s->deleted = false; diff --git a/service/service.h b/service/service.h index 6ddc04e..4858e91 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_data_trigger(struct blobmsg_list *list); void service_stop_all(void); |