X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=service.c;h=fe605034d3b40717a42fe76f0e92c1f07feff60c;hp=360810ea8b20ce3cf06053db10310af17bc950c9;hb=43dec9ddfc926aaa884ecf939f8344e960805528;hpb=86009b5439a898fa00cc27e675bb7834576be70a diff --git a/service.c b/service.c index 360810e..fe60503 100644 --- a/service.c +++ b/service.c @@ -1,91 +1,12 @@ #include #include "procd.h" #include "service.h" +#include "instance.h" struct avl_tree services; static struct blob_buf b; static void -start_instance(struct service_instance *in) -{ - in->restart = false; -} - -static void -instance_timeout(struct uloop_timeout *t) -{ - struct service_instance *in; - - in = container_of(t, struct service_instance, timeout); - kill(in->proc.pid, SIGKILL); - uloop_process_delete(&in->proc); - in->proc.cb(&in->proc, -1); -} - -static void -instance_exit(struct uloop_process *p, int ret) -{ - struct service_instance *in; - - in = container_of(p, struct service_instance, proc); - uloop_timeout_cancel(&in->timeout); - if (in->restart) - start_instance(in); -} - -static void -stop_instance(struct service_instance *in, bool restart) -{ - if (!in->proc.pending) - return; - - kill(in->proc.pid, SIGTERM); -} - -static bool -instance_config_changed(struct service_instance *in, struct service_instance *in_new) -{ - int len = blob_pad_len(in->config); - - if (len != blob_pad_len(in_new->config)) - return true; - - if (memcmp(in->config, in_new->config, blob_pad_len(in->config)) != 0) - return true; - - return false; -} - -static bool -update_instance(struct service_instance *in, struct service_instance *in_new) -{ - bool changed = instance_config_changed(in, in_new); - - in->config = in_new->config; - if (!changed) - return false; - - stop_instance(in, true); - return true; -} - -static void -free_instance(struct service_instance *in) -{ - uloop_process_delete(&in->proc); - uloop_timeout_cancel(&in->timeout); - free(in); -} - -static void -init_instance(struct service_instance *in, struct blob_attr *config) -{ - in->config = config; - in->timeout.cb = instance_timeout; - in->proc.cb = instance_exit; -} - -static void service_instance_add(struct service *s, struct blob_attr *attr) { struct service_instance *in; @@ -98,7 +19,7 @@ service_instance_add(struct service *s, struct blob_attr *attr) if (!in) return; - init_instance(in, attr); + instance_init(in, s, attr); vlist_add(&s->instances, &in->node, (void *) name); } @@ -115,13 +36,16 @@ service_instance_update(struct vlist_tree *tree, struct vlist_node *node_new, in_n = container_of(node_new, struct service_instance, node); if (in_o && in_n) { - update_instance(in_o, in_n); - free_instance(in_n); + DPRINTF("Update instance %s::%s\n", in_o->srv->name, in_o->name); + instance_update(in_o, in_n); + instance_free(in_n); } else if (in_o) { - stop_instance(in_o, false); - free_instance(in_o); + DPRINTF("Free instance %s::%s\n", in_o->srv->name, in_o->name); + instance_stop(in_o, false); + instance_free(in_o); } else if (in_n) { - start_instance(in_n); + DPRINTF("Create instance %s::%s\n", in_n->srv->name, in_n->name); + instance_start(in_n); } } @@ -207,9 +131,12 @@ service_handle_set(struct ubus_context *ctx, struct ubus_object *obj, name = blobmsg_data(cur); s = avl_find_element(&services, name, s, avl); - if (s) + if (s) { + DPRINTF("Update service %s\n", name); return service_update(s, msg, tb); + } + DPRINTF("Create service %s\n", name); s = service_alloc(name); if (!s) return UBUS_STATUS_UNKNOWN_ERROR; @@ -227,6 +154,20 @@ free: return ret; } +static void +service_dump(struct service *s) +{ + struct service_instance *in; + void *c, *i; + + c = blobmsg_open_table(&b, s->name); + i = blobmsg_open_table(&b, "instances"); + vlist_for_each_element(&s->instances, in, node) + instance_dump(&b, in); + blobmsg_close_table(&b, i); + blobmsg_close_table(&b, c); +} + static int service_handle_list(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, @@ -235,12 +176,8 @@ service_handle_list(struct ubus_context *ctx, struct ubus_object *obj, struct service *s; blob_buf_init(&b, 0); - avl_for_each_element(&services, s, avl) { - void *c; - - c = blobmsg_open_table(&b, s->name); - blobmsg_close_table(&b, c); - } + avl_for_each_element(&services, s, avl) + service_dump(s); ubus_send_reply(ctx, req, b.head);