X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=instance.c;h=df1ea5b22a1e164fb9144564d1002b18cd6b7a43;hp=e2c8b28839f449dd7facfab5af132f1144b3d786;hb=d4ff22c576eff5c362d43036b3788e61b7deef5c;hpb=84c2e44d4c1ae46418cc8f7891b31e9df4131d96 diff --git a/instance.c b/instance.c index e2c8b28..df1ea5b 100644 --- a/instance.c +++ b/instance.c @@ -2,10 +2,25 @@ #include "service.h" #include "instance.h" +enum { + INSTANCE_ATTR_COMMAND, + INSTANCE_ATTR_ENV, + INSTANCE_ATTR_DATA, + __INSTANCE_ATTR_MAX +}; + +static const struct blobmsg_policy instance_attr[__INSTANCE_ATTR_MAX] = { + [INSTANCE_ATTR_COMMAND] = { "command", BLOBMSG_TYPE_ARRAY }, + [INSTANCE_ATTR_ENV] = { "env", BLOBMSG_TYPE_TABLE }, + [INSTANCE_ATTR_DATA] = { "data", BLOBMSG_TYPE_TABLE }, +}; + void instance_start(struct service_instance *in) { in->restart = false; + if (!in->valid) + return; } static void @@ -42,17 +57,58 @@ instance_stop(struct service_instance *in, bool restart) static bool instance_config_changed(struct service_instance *in, struct service_instance *in_new) { - int len = blob_pad_len(in->config); + if (!in->valid) + return true; - if (len != blob_pad_len(in_new->config)) + if (!blob_attr_equal(in->command, in_new->command)) return true; - if (memcmp(in->config, in_new->config, blob_pad_len(in->config)) != 0) + if (!blobmsg_list_equal(&in->env, &in_new->env)) + return true; + + if (!blobmsg_list_equal(&in->data, &in_new->data)) return true; return false; } +static bool +instance_config_parse(struct service_instance *in) +{ + struct blob_attr *tb[__INSTANCE_ATTR_MAX]; + struct blob_attr *cur; + + blobmsg_parse(instance_attr, __INSTANCE_ATTR_MAX, tb, + blobmsg_data(in->config), blobmsg_data_len(in->config)); + + if (!tb[INSTANCE_ATTR_COMMAND]) + return false; + + if ((cur = tb[INSTANCE_ATTR_ENV])) + blobmsg_list_fill(&in->env, blobmsg_data(cur), blobmsg_data_len(cur)); + + if ((cur = tb[INSTANCE_ATTR_DATA])) + blobmsg_list_fill(&in->data, blobmsg_data(cur), blobmsg_data_len(cur)); + + return true; +} + +static void +instance_config_cleanup(struct service_instance *in) +{ + blobmsg_list_free(&in->env); + blobmsg_list_free(&in->data); +} + +static void +instance_config_move(struct service_instance *in, struct service_instance *in_src) +{ + instance_config_cleanup(in); + blobmsg_list_move(&in->env, &in_src->env); + blobmsg_list_move(&in->data, &in_src->data); + in->command = in_src->command; +} + bool instance_update(struct service_instance *in, struct service_instance *in_new) { @@ -62,7 +118,9 @@ instance_update(struct service_instance *in, struct service_instance *in_new) if (!changed) return false; + in->restart = true; instance_stop(in, true); + instance_config_move(in, in_new); return true; } @@ -71,6 +129,7 @@ instance_free(struct service_instance *in) { uloop_process_delete(&in->proc); uloop_timeout_cancel(&in->timeout); + instance_config_cleanup(in); free(in); } @@ -80,6 +139,8 @@ instance_init(struct service_instance *in, struct blob_attr *config) in->config = config; in->timeout.cb = instance_timeout; in->proc.cb = instance_exit; -} - + blobmsg_list_simple_init(&in->env); + blobmsg_list_simple_init(&in->data); + in->valid = instance_config_parse(in); +}