X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=instance.c;h=d61bb332e2c7047b99f5d3d069576df63e224557;hp=b2cdfa1dd57397d4e36d7886d8f5bafa5e710f23;hb=1c01a5137402cfd1bc7557118401f3b90c305b78;hpb=8158e9052afbf2ee47de645167b90b6e7fc7d86d diff --git a/instance.c b/instance.c index b2cdfa1..d61bb33 100644 --- a/instance.c +++ b/instance.c @@ -31,6 +31,7 @@ enum { INSTANCE_ATTR_DATA, INSTANCE_ATTR_NETDEV, INSTANCE_ATTR_FILE, + INSTANCE_ATTR_TRIGGER, INSTANCE_ATTR_NICE, __INSTANCE_ATTR_MAX }; @@ -41,6 +42,7 @@ static const struct blobmsg_policy instance_attr[__INSTANCE_ATTR_MAX] = { [INSTANCE_ATTR_DATA] = { "data", BLOBMSG_TYPE_TABLE }, [INSTANCE_ATTR_NETDEV] = { "netdev", BLOBMSG_TYPE_ARRAY }, [INSTANCE_ATTR_FILE] = { "file", BLOBMSG_TYPE_ARRAY }, + [INSTANCE_ATTR_TRIGGER] = { "triggers", BLOBMSG_TYPE_ARRAY }, [INSTANCE_ATTR_NICE] = { "nice", BLOBMSG_TYPE_INT32 }, }; @@ -61,7 +63,7 @@ instance_run(struct service_instance *in) struct blob_attr *cur; char **argv; int argc = 1; /* NULL terminated */ - int rem; + int rem, fd; if (in->nice) setpriority(PRIO_PROCESS, 0, in->nice); @@ -79,6 +81,14 @@ instance_run(struct service_instance *in) argv[argc++] = blobmsg_data(cur); argv[argc] = NULL; + fd = open("/dev/null", O_RDWR); + if (fd > -1) { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + if (fd > STDERR_FILENO) + close(fd); + } execvp(argv[0], argv); exit(127); } @@ -100,6 +110,7 @@ instance_start(struct service_instance *in) return; if (!pid) { + uloop_done(); instance_run(in); return; } @@ -126,7 +137,7 @@ instance_exit(struct uloop_process *p, int ret) struct service_instance *in; in = container_of(p, struct service_instance, proc); - LOG("Instance %s::%s exit with error code %d\n", in->srv->name, in->name, ret); + DEBUG(1, "Instance %s::%s exit with error code %d\n", in->srv->name, in->name, ret); uloop_timeout_cancel(&in->timeout); if (in->restart) instance_start(in); @@ -272,7 +283,11 @@ instance_config_parse(struct service_instance *in) return false; in->command = cur; + in->trigger = tb[INSTANCE_ATTR_TRIGGER]; + if (in->trigger) { + trigger_add(in->trigger, in); + } if ((cur = tb[INSTANCE_ATTR_NICE])) { in->nice = (int8_t) blobmsg_get_u32(cur); if (in->nice < -20 || in->nice > 20) @@ -309,6 +324,7 @@ instance_config_move(struct service_instance *in, struct service_instance *in_sr blobmsg_list_move(&in->env, &in_src->env); blobmsg_list_move(&in->data, &in_src->data); blobmsg_list_move(&in->netdev, &in_src->netdev); + in->trigger = in_src->trigger; in->command = in_src->command; in->name = in_src->name; in->node.avl.key = in_src->node.avl.key; @@ -322,13 +338,20 @@ bool instance_update(struct service_instance *in, struct service_instance *in_new) { bool changed = instance_config_changed(in, in_new); + bool running = in->proc.pending; - if (!changed) + if (!changed && running) return false; - in->restart = true; - instance_stop(in, true); - instance_config_move(in, in_new); + if (!running) { + if (changed) + instance_config_move(in, in_new); + instance_start(in); + } else { + in->restart = true; + instance_stop(in, true); + instance_config_move(in, in_new); + } return true; } @@ -337,6 +360,7 @@ instance_free(struct service_instance *in) { uloop_process_delete(&in->proc); uloop_timeout_cancel(&in->timeout); + trigger_del(in); instance_config_cleanup(in); free(in->config); free(in); @@ -359,7 +383,7 @@ instance_init(struct service_instance *in, struct service *s, struct blob_attr * in->valid = instance_config_parse(in); } -void instance_dump(struct blob_buf *b, struct service_instance *in) +void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose) { void *i; @@ -368,5 +392,7 @@ void instance_dump(struct blob_buf *b, struct service_instance *in) if (in->proc.pending) blobmsg_add_u32(b, "pid", in->proc.pid); blobmsg_add_blob(b, in->command); + if (verbose && in->trigger) + blobmsg_add_blob(b, in->trigger); blobmsg_close_table(b, i); }