e5c483010340d0a62206604f7551bf44469498e4
[project/procd.git] / service / instance.c
1 /*
2  * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
3  * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License version 2.1
7  * as published by the Free Software Foundation
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #define _GNU_SOURCE
16 #include <sys/resource.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <sys/stat.h>
20 #include <net/if.h>
21 #include <unistd.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <fcntl.h>
25 #include <pwd.h>
26 #include <libgen.h>
27 #include <unistd.h>
28
29 #include <libubox/md5.h>
30
31 #include "../procd.h"
32
33 #include "service.h"
34 #include "instance.h"
35
36
37 enum {
38         INSTANCE_ATTR_COMMAND,
39         INSTANCE_ATTR_ENV,
40         INSTANCE_ATTR_DATA,
41         INSTANCE_ATTR_NETDEV,
42         INSTANCE_ATTR_FILE,
43         INSTANCE_ATTR_TRIGGER,
44         INSTANCE_ATTR_RESPAWN,
45         INSTANCE_ATTR_NICE,
46         INSTANCE_ATTR_LIMITS,
47         INSTANCE_ATTR_WATCH,
48         INSTANCE_ATTR_ERROR,
49         INSTANCE_ATTR_USER,
50         INSTANCE_ATTR_STDOUT,
51         INSTANCE_ATTR_STDERR,
52         INSTANCE_ATTR_NO_NEW_PRIVS,
53         INSTANCE_ATTR_JAIL,
54         INSTANCE_ATTR_TRACE,
55         INSTANCE_ATTR_SECCOMP,
56         INSTANCE_ATTR_PIDFILE,
57         INSTANCE_ATTR_RELOADSIG,
58         INSTANCE_ATTR_TERMTIMEOUT,
59         __INSTANCE_ATTR_MAX
60 };
61
62 static const struct blobmsg_policy instance_attr[__INSTANCE_ATTR_MAX] = {
63         [INSTANCE_ATTR_COMMAND] = { "command", BLOBMSG_TYPE_ARRAY },
64         [INSTANCE_ATTR_ENV] = { "env", BLOBMSG_TYPE_TABLE },
65         [INSTANCE_ATTR_DATA] = { "data", BLOBMSG_TYPE_TABLE },
66         [INSTANCE_ATTR_NETDEV] = { "netdev", BLOBMSG_TYPE_ARRAY },
67         [INSTANCE_ATTR_FILE] = { "file", BLOBMSG_TYPE_ARRAY },
68         [INSTANCE_ATTR_TRIGGER] = { "triggers", BLOBMSG_TYPE_ARRAY },
69         [INSTANCE_ATTR_RESPAWN] = { "respawn", BLOBMSG_TYPE_ARRAY },
70         [INSTANCE_ATTR_NICE] = { "nice", BLOBMSG_TYPE_INT32 },
71         [INSTANCE_ATTR_LIMITS] = { "limits", BLOBMSG_TYPE_TABLE },
72         [INSTANCE_ATTR_WATCH] = { "watch", BLOBMSG_TYPE_ARRAY },
73         [INSTANCE_ATTR_ERROR] = { "error", BLOBMSG_TYPE_ARRAY },
74         [INSTANCE_ATTR_USER] = { "user", BLOBMSG_TYPE_STRING },
75         [INSTANCE_ATTR_STDOUT] = { "stdout", BLOBMSG_TYPE_BOOL },
76         [INSTANCE_ATTR_STDERR] = { "stderr", BLOBMSG_TYPE_BOOL },
77         [INSTANCE_ATTR_NO_NEW_PRIVS] = { "no_new_privs", BLOBMSG_TYPE_BOOL },
78         [INSTANCE_ATTR_JAIL] = { "jail", BLOBMSG_TYPE_TABLE },
79         [INSTANCE_ATTR_TRACE] = { "trace", BLOBMSG_TYPE_BOOL },
80         [INSTANCE_ATTR_SECCOMP] = { "seccomp", BLOBMSG_TYPE_STRING },
81         [INSTANCE_ATTR_PIDFILE] = { "pidfile", BLOBMSG_TYPE_STRING },
82         [INSTANCE_ATTR_RELOADSIG] = { "reload_signal", BLOBMSG_TYPE_INT32 },
83         [INSTANCE_ATTR_TERMTIMEOUT] = { "term_timeout", BLOBMSG_TYPE_INT32 },
84 };
85
86 enum {
87         JAIL_ATTR_NAME,
88         JAIL_ATTR_HOSTNAME,
89         JAIL_ATTR_PROCFS,
90         JAIL_ATTR_SYSFS,
91         JAIL_ATTR_UBUS,
92         JAIL_ATTR_LOG,
93         JAIL_ATTR_RONLY,
94         JAIL_ATTR_MOUNT,
95         __JAIL_ATTR_MAX,
96 };
97
98 static const struct blobmsg_policy jail_attr[__JAIL_ATTR_MAX] = {
99         [JAIL_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING },
100         [JAIL_ATTR_HOSTNAME] = { "hostname", BLOBMSG_TYPE_STRING },
101         [JAIL_ATTR_PROCFS] = { "procfs", BLOBMSG_TYPE_BOOL },
102         [JAIL_ATTR_SYSFS] = { "sysfs", BLOBMSG_TYPE_BOOL },
103         [JAIL_ATTR_UBUS] = { "ubus", BLOBMSG_TYPE_BOOL },
104         [JAIL_ATTR_LOG] = { "log", BLOBMSG_TYPE_BOOL },
105         [JAIL_ATTR_RONLY] = { "ronly", BLOBMSG_TYPE_BOOL },
106         [JAIL_ATTR_MOUNT] = { "mount", BLOBMSG_TYPE_TABLE },
107 };
108
109 struct instance_netdev {
110         struct blobmsg_list_node node;
111         int ifindex;
112 };
113
114 struct instance_file {
115         struct blobmsg_list_node node;
116         uint32_t md5[4];
117 };
118
119 struct rlimit_name {
120         const char *name;
121         int resource;
122 };
123
124 static const struct rlimit_name rlimit_names[] = {
125         { "as", RLIMIT_AS },
126         { "core", RLIMIT_CORE },
127         { "cpu", RLIMIT_CPU },
128         { "data", RLIMIT_DATA },
129         { "fsize", RLIMIT_FSIZE },
130         { "memlock", RLIMIT_MEMLOCK },
131         { "nofile", RLIMIT_NOFILE },
132         { "nproc", RLIMIT_NPROC },
133         { "rss", RLIMIT_RSS },
134         { "stack", RLIMIT_STACK },
135 #ifdef linux
136         { "nice", RLIMIT_NICE },
137         { "rtprio", RLIMIT_RTPRIO },
138         { "msgqueue", RLIMIT_MSGQUEUE },
139         { "sigpending", RLIMIT_SIGPENDING },
140 #endif
141         { NULL, 0 }
142 };
143
144 static char trace[] = "/sbin/utrace";
145
146 static void closefd(int fd)
147 {
148         if (fd > STDERR_FILENO)
149                 close(fd);
150 }
151
152 static void
153 instance_limits(const char *limit, const char *value)
154 {
155         int i;
156         struct rlimit rlim;
157         unsigned long cur, max;
158
159         for (i = 0; rlimit_names[i].name != NULL; i++) {
160                 if (strcmp(rlimit_names[i].name, limit))
161                         continue;
162                 if (!strcmp(value, "unlimited")) {
163                         rlim.rlim_cur = RLIM_INFINITY;
164                         rlim.rlim_max = RLIM_INFINITY;
165                 } else {
166                         if (getrlimit(rlimit_names[i].resource, &rlim))
167                                 return;
168
169                         cur = rlim.rlim_cur;
170                         max = rlim.rlim_max;
171
172                         if (sscanf(value, "%lu %lu", &cur, &max) < 1)
173                                 return;
174
175                         rlim.rlim_cur = cur;
176                         rlim.rlim_max = max;
177                 }
178
179                 setrlimit(rlimit_names[i].resource, &rlim);
180                 return;
181         }
182 }
183
184 static inline int
185 jail_run(struct service_instance *in, char **argv)
186 {
187         struct blobmsg_list_node *var;
188         struct jail *jail = &in->jail;
189         int argc = 0;
190
191         argv[argc++] = "/sbin/ujail";
192
193         if (jail->name) {
194                 argv[argc++] = "-n";
195                 argv[argc++] = jail->name;
196         }
197
198         if (jail->hostname) {
199                 argv[argc++] = "-h";
200                 argv[argc++] = jail->hostname;
201         }
202
203         if (in->seccomp) {
204                 argv[argc++] = "-S";
205                 argv[argc++] = in->seccomp;
206         }
207
208         if (in->no_new_privs)
209                 argv[argc++] = "-c";
210
211         if (jail->procfs)
212                 argv[argc++] = "-p";
213
214         if (jail->sysfs)
215                 argv[argc++] = "-s";
216
217         if (jail->ubus)
218                 argv[argc++] = "-u";
219
220         if (jail->log)
221                 argv[argc++] = "-l";
222
223         if (jail->ronly)
224                 argv[argc++] = "-o";
225
226         blobmsg_list_for_each(&jail->mount, var) {
227                 const char *type = blobmsg_data(var->data);
228
229                 if (*type == '1')
230                         argv[argc++] = "-w";
231                 else
232                         argv[argc++] = "-r";
233                 argv[argc++] = (char *) blobmsg_name(var->data);
234         }
235
236         argv[argc++] = "--";
237
238         return argc;
239 }
240
241 static int
242 instance_removepid(struct service_instance *in) {
243         if (!in->pidfile)
244                 return 0;
245         if (unlink(in->pidfile)) {
246                 ERROR("Failed to removed pidfile: %s: %d - %s\n",
247                         in->pidfile, errno, strerror(errno));
248                 return 1;
249         }
250         return 0;
251 }
252
253 static int
254 instance_writepid(struct service_instance *in)
255 {
256         FILE *_pidfile;
257
258         if (!in->pidfile) {
259                 return 0;
260         }
261         _pidfile = fopen(in->pidfile, "w");
262         if (_pidfile == NULL) {
263                 ERROR("failed to open pidfile for writing: %s: %d (%s)",
264                         in->pidfile, errno, strerror(errno));
265                 return 1;
266         }
267         if (fprintf(_pidfile, "%d\n", in->proc.pid) < 0) {
268                 ERROR("failed to write pidfile: %s: %d (%s)",
269                         in->pidfile, errno, strerror(errno));
270                 fclose(_pidfile);
271                 return 2;
272         }
273         if (fclose(_pidfile)) {
274                 ERROR("failed to close pidfile: %s: %d (%s)",
275                         in->pidfile, errno, strerror(errno));
276                 return 3;
277         }
278
279         return 0;
280 }
281
282 static void
283 instance_run(struct service_instance *in, int _stdout, int _stderr)
284 {
285         struct blobmsg_list_node *var;
286         struct blob_attr *cur;
287         char **argv;
288         char *ld_preload;
289         int argc = 1; /* NULL terminated */
290         int rem, _stdin;
291         bool seccomp = !in->trace && !in->has_jail && in->seccomp;
292         bool setlbf = _stdout >= 0;
293
294         if (in->nice)
295                 setpriority(PRIO_PROCESS, 0, in->nice);
296
297         blobmsg_for_each_attr(cur, in->command, rem)
298                 argc++;
299
300         blobmsg_list_for_each(&in->env, var)
301                 setenv(blobmsg_name(var->data), blobmsg_data(var->data), 1);
302
303         if (seccomp)
304                 setenv("SECCOMP_FILE", in->seccomp, 1);
305
306         if ((seccomp || setlbf) && asprintf(&ld_preload, "LD_PRELOAD=%s%s%s",
307                         seccomp ? "/lib/libpreload-seccomp.so" : "",
308                         seccomp && setlbf ? ":" : "",
309                         setlbf ? "/lib/libsetlbf.so" : "") > 0)
310                 putenv(ld_preload);
311
312         blobmsg_list_for_each(&in->limits, var)
313                 instance_limits(blobmsg_name(var->data), blobmsg_data(var->data));
314
315         if (in->trace)
316                 argc += 1;
317
318         argv = alloca(sizeof(char *) * (argc + in->jail.argc));
319         argc = 0;
320
321         if (in->trace)
322                 argv[argc++] = trace;
323
324         if (in->has_jail)
325                 argc = jail_run(in, argv);
326
327         blobmsg_for_each_attr(cur, in->command, rem)
328                 argv[argc++] = blobmsg_data(cur);
329
330         argv[argc] = NULL;
331
332         _stdin = open("/dev/null", O_RDONLY);
333
334         if (_stdout == -1)
335                 _stdout = open("/dev/null", O_WRONLY);
336
337         if (_stderr == -1)
338                 _stderr = open("/dev/null", O_WRONLY);
339
340         if (_stdin > -1) {
341                 dup2(_stdin, STDIN_FILENO);
342                 closefd(_stdin);
343         }
344         if (_stdout > -1) {
345                 dup2(_stdout, STDOUT_FILENO);
346                 closefd(_stdout);
347         }
348         if (_stderr > -1) {
349                 dup2(_stderr, STDERR_FILENO);
350                 closefd(_stderr);
351         }
352
353         if (in->gid && setgid(in->gid)) {
354                 ERROR("failed to set group id %d: %d (%s)\n", in->gid, errno, strerror(errno));
355                 exit(127);
356         }
357         if (in->uid && setuid(in->uid)) {
358                 ERROR("failed to set user id %d: %d (%s)\n", in->uid, errno, strerror(errno));
359                 exit(127);
360         }
361
362         execvp(argv[0], argv);
363         exit(127);
364 }
365
366 static void
367 instance_free_stdio(struct service_instance *in)
368 {
369         if (in->_stdout.fd.fd > -1) {
370                 ustream_free(&in->_stdout.stream);
371                 close(in->_stdout.fd.fd);
372                 in->_stdout.fd.fd = -1;
373         }
374
375         if (in->_stderr.fd.fd > -1) {
376                 ustream_free(&in->_stderr.stream);
377                 close(in->_stderr.fd.fd);
378                 in->_stderr.fd.fd = -1;
379         }
380 }
381
382 void
383 instance_start(struct service_instance *in)
384 {
385         int pid;
386         int opipe[2] = { -1, -1 };
387         int epipe[2] = { -1, -1 };
388
389         if (!avl_is_empty(&in->errors.avl)) {
390                 LOG("Not starting instance %s::%s, an error was indicated\n", in->srv->name, in->name);
391                 return;
392         }
393
394         if (!in->command) {
395                 LOG("Not starting instance %s::%s, command not set\n", in->srv->name, in->name);
396                 return;
397         }
398
399         if (in->proc.pending) {
400                 if (in->halt)
401                         in->restart = true;
402                 return;
403         }
404
405         instance_free_stdio(in);
406         if (in->_stdout.fd.fd > -2) {
407                 if (pipe(opipe)) {
408                         ULOG_WARN("pipe() failed: %d (%s)\n", errno, strerror(errno));
409                         opipe[0] = opipe[1] = -1;
410                 }
411         }
412
413         if (in->_stderr.fd.fd > -2) {
414                 if (pipe(epipe)) {
415                         ULOG_WARN("pipe() failed: %d (%s)\n", errno, strerror(errno));
416                         epipe[0] = epipe[1] = -1;
417                 }
418         }
419
420         in->restart = false;
421         in->halt = false;
422
423         if (!in->valid)
424                 return;
425
426         pid = fork();
427         if (pid < 0)
428                 return;
429
430         if (!pid) {
431                 uloop_done();
432                 closefd(opipe[0]);
433                 closefd(epipe[0]);
434                 instance_run(in, opipe[1], epipe[1]);
435                 return;
436         }
437
438         DEBUG(2, "Started instance %s::%s[%d]\n", in->srv->name, in->name, pid);
439         in->proc.pid = pid;
440         instance_writepid(in);
441         clock_gettime(CLOCK_MONOTONIC, &in->start);
442         uloop_process_add(&in->proc);
443
444         if (opipe[0] > -1) {
445                 ustream_fd_init(&in->_stdout, opipe[0]);
446                 closefd(opipe[1]);
447         }
448
449         if (epipe[0] > -1) {
450                 ustream_fd_init(&in->_stderr, epipe[0]);
451                 closefd(epipe[1]);
452         }
453
454         service_event("instance.start", in->srv->name, in->name);
455 }
456
457 static void
458 instance_stdio(struct ustream *s, int prio, struct service_instance *in)
459 {
460         char *newline, *str, *arg0, ident[32];
461         int len;
462
463         arg0 = basename(blobmsg_data(blobmsg_data(in->command)));
464         snprintf(ident, sizeof(ident), "%s[%d]", arg0, in->proc.pid);
465         ulog_open(ULOG_SYSLOG, LOG_DAEMON, ident);
466
467         do {
468                 str = ustream_get_read_buf(s, NULL);
469                 if (!str)
470                         break;
471
472                 newline = strchr(str, '\n');
473                 if (!newline)
474                         break;
475
476                 *newline = 0;
477                 ulog(prio, "%s\n", str);
478
479                 len = newline + 1 - str;
480                 ustream_consume(s, len);
481         } while (1);
482
483         ulog_open(ULOG_SYSLOG, LOG_DAEMON, "procd");
484 }
485
486 static void
487 instance_stdout(struct ustream *s, int bytes)
488 {
489         instance_stdio(s, LOG_INFO,
490                        container_of(s, struct service_instance, _stdout.stream));
491 }
492
493 static void
494 instance_stderr(struct ustream *s, int bytes)
495 {
496         instance_stdio(s, LOG_ERR,
497                        container_of(s, struct service_instance, _stderr.stream));
498 }
499
500 static void
501 instance_timeout(struct uloop_timeout *t)
502 {
503         struct service_instance *in;
504
505         in = container_of(t, struct service_instance, timeout);
506
507         if (in->halt) {
508                 LOG("Instance %s::%s pid %d not stopped on SIGTERM, sending SIGKILL instead\n",
509                                 in->srv->name, in->name, in->proc.pid);
510                 kill(in->proc.pid, SIGKILL);
511         } else if (in->restart || in->respawn)
512                 instance_start(in);
513 }
514
515 static void
516 instance_exit(struct uloop_process *p, int ret)
517 {
518         struct service_instance *in;
519         struct timespec tp;
520         long runtime;
521
522         in = container_of(p, struct service_instance, proc);
523
524         clock_gettime(CLOCK_MONOTONIC, &tp);
525         runtime = tp.tv_sec - in->start.tv_sec;
526
527         DEBUG(2, "Instance %s::%s exit with error code %d after %ld seconds\n", in->srv->name, in->name, ret, runtime);
528
529         uloop_timeout_cancel(&in->timeout);
530         service_event("instance.stop", in->srv->name, in->name);
531
532         if (in->halt) {
533                 instance_removepid(in);
534                 if (in->restart)
535                         instance_start(in);
536                 else {
537                         struct service *s = in->srv;
538
539                         avl_delete(&s->instances.avl, &in->node.avl);
540                         instance_free(in);
541                         service_stopped(s);
542                 }
543         } else if (in->restart) {
544                 instance_start(in);
545         } else if (in->respawn) {
546                 if (runtime < in->respawn_threshold)
547                         in->respawn_count++;
548                 else
549                         in->respawn_count = 0;
550                 if (in->respawn_count > in->respawn_retry && in->respawn_retry > 0 ) {
551                         LOG("Instance %s::%s s in a crash loop %d crashes, %ld seconds since last crash\n",
552                                                                 in->srv->name, in->name, in->respawn_count, runtime);
553                         in->restart = in->respawn = 0;
554                         in->halt = 1;
555                         service_event("instance.fail", in->srv->name, in->name);
556                 } else {
557                         service_event("instance.respawn", in->srv->name, in->name);
558                         uloop_timeout_set(&in->timeout, in->respawn_timeout * 1000);
559                 }
560         }
561 }
562
563 void
564 instance_stop(struct service_instance *in, bool halt)
565 {
566         if (!in->proc.pending)
567                 return;
568         in->halt = halt;
569         in->restart = in->respawn = false;
570         kill(in->proc.pid, SIGTERM);
571         uloop_timeout_set(&in->timeout, in->term_timeout * 1000);
572 }
573
574 static void
575 instance_restart(struct service_instance *in)
576 {
577         if (!in->proc.pending)
578                 return;
579
580         if (in->reload_signal) {
581                 kill(in->proc.pid, in->reload_signal);
582                 return;
583         }
584
585         in->halt = true;
586         in->restart = true;
587         kill(in->proc.pid, SIGTERM);
588         uloop_timeout_set(&in->timeout, in->term_timeout * 1000);
589 }
590
591 static bool
592 instance_config_changed(struct service_instance *in, struct service_instance *in_new)
593 {
594         if (!in->valid)
595                 return true;
596
597         if (!blob_attr_equal(in->command, in_new->command))
598                 return true;
599
600         if (!blobmsg_list_equal(&in->env, &in_new->env))
601                 return true;
602
603         if (!blobmsg_list_equal(&in->netdev, &in_new->netdev))
604                 return true;
605
606         if (!blobmsg_list_equal(&in->file, &in_new->file))
607                 return true;
608
609         if (in->nice != in_new->nice)
610                 return true;
611
612         if (in->uid != in_new->uid)
613                 return true;
614
615         if (in->gid != in_new->gid)
616                 return true;
617
618         if (in->pidfile && in_new->pidfile)
619                 if (strcmp(in->pidfile, in_new->pidfile))
620                         return true;
621
622         if (in->pidfile && !in_new->pidfile)
623                 return true;
624
625         if (!in->pidfile && in_new->pidfile)
626                 return true;
627
628         if (!blobmsg_list_equal(&in->limits, &in_new->limits))
629                 return true;
630
631         if (!blobmsg_list_equal(&in->jail.mount, &in_new->jail.mount))
632                 return true;
633
634         if (!blobmsg_list_equal(&in->errors, &in_new->errors))
635                 return true;
636
637         return false;
638 }
639
640 static bool
641 instance_netdev_cmp(struct blobmsg_list_node *l1, struct blobmsg_list_node *l2)
642 {
643         struct instance_netdev *n1 = container_of(l1, struct instance_netdev, node);
644         struct instance_netdev *n2 = container_of(l2, struct instance_netdev, node);
645
646         return n1->ifindex == n2->ifindex;
647 }
648
649 static void
650 instance_netdev_update(struct blobmsg_list_node *l)
651 {
652         struct instance_netdev *n = container_of(l, struct instance_netdev, node);
653
654         n->ifindex = if_nametoindex(n->node.avl.key);
655 }
656
657 static bool
658 instance_file_cmp(struct blobmsg_list_node *l1, struct blobmsg_list_node *l2)
659 {
660         struct instance_file *f1 = container_of(l1, struct instance_file, node);
661         struct instance_file *f2 = container_of(l2, struct instance_file, node);
662
663         return !memcmp(f1->md5, f2->md5, sizeof(f1->md5));
664 }
665
666 static void
667 instance_file_update(struct blobmsg_list_node *l)
668 {
669         struct instance_file *f = container_of(l, struct instance_file, node);
670         md5_ctx_t md5;
671         char buf[256];
672         int len, fd;
673
674         memset(f->md5, 0, sizeof(f->md5));
675
676         fd = open(l->avl.key, O_RDONLY);
677         if (fd < 0)
678                 return;
679
680         md5_begin(&md5);
681         do {
682                 len = read(fd, buf, sizeof(buf));
683                 if (len < 0) {
684                         if (errno == EINTR)
685                                 continue;
686
687                         break;
688                 }
689                 if (!len)
690                         break;
691
692                 md5_hash(buf, len, &md5);
693         } while(1);
694
695         md5_end(f->md5, &md5);
696         close(fd);
697 }
698
699 static void
700 instance_fill_any(struct blobmsg_list *l, struct blob_attr *cur)
701 {
702         if (!cur)
703                 return;
704
705         blobmsg_list_fill(l, blobmsg_data(cur), blobmsg_data_len(cur), false);
706 }
707
708 static bool
709 instance_fill_array(struct blobmsg_list *l, struct blob_attr *cur, blobmsg_update_cb cb, bool array)
710 {
711         struct blobmsg_list_node *node;
712
713         if (!cur)
714                 return true;
715
716         if (!blobmsg_check_attr_list(cur, BLOBMSG_TYPE_STRING))
717                 return false;
718
719         blobmsg_list_fill(l, blobmsg_data(cur), blobmsg_data_len(cur), array);
720         if (cb) {
721                 blobmsg_list_for_each(l, node)
722                         cb(node);
723         }
724         return true;
725 }
726
727 static int
728 instance_jail_parse(struct service_instance *in, struct blob_attr *attr)
729 {
730         struct blob_attr *tb[__JAIL_ATTR_MAX];
731         struct jail *jail = &in->jail;
732         struct stat s;
733
734         if (stat("/sbin/ujail", &s))
735                 return 0;
736
737         blobmsg_parse(jail_attr, __JAIL_ATTR_MAX, tb,
738                 blobmsg_data(attr), blobmsg_data_len(attr));
739
740         jail->argc = 2;
741
742         if (tb[JAIL_ATTR_NAME]) {
743                 jail->name = blobmsg_get_string(tb[JAIL_ATTR_NAME]);
744                 jail->argc += 2;
745         }
746         if (tb[JAIL_ATTR_HOSTNAME]) {
747                 jail->hostname = blobmsg_get_string(tb[JAIL_ATTR_HOSTNAME]);
748                 jail->argc += 2;
749         }
750         if (tb[JAIL_ATTR_PROCFS]) {
751                 jail->procfs = blobmsg_get_bool(tb[JAIL_ATTR_PROCFS]);
752                 jail->argc++;
753         }
754         if (tb[JAIL_ATTR_SYSFS]) {
755                 jail->sysfs = blobmsg_get_bool(tb[JAIL_ATTR_SYSFS]);
756                 jail->argc++;
757         }
758         if (tb[JAIL_ATTR_UBUS]) {
759                 jail->ubus = blobmsg_get_bool(tb[JAIL_ATTR_UBUS]);
760                 jail->argc++;
761         }
762         if (tb[JAIL_ATTR_LOG]) {
763                 jail->log = blobmsg_get_bool(tb[JAIL_ATTR_LOG]);
764                 jail->argc++;
765         }
766         if (tb[JAIL_ATTR_RONLY]) {
767                 jail->ronly = blobmsg_get_bool(tb[JAIL_ATTR_RONLY]);
768                 jail->argc++;
769         }
770         if (tb[JAIL_ATTR_MOUNT]) {
771                 struct blob_attr *cur;
772                 int rem;
773
774                 blobmsg_for_each_attr(cur, tb[JAIL_ATTR_MOUNT], rem)
775                         jail->argc += 2;
776                 instance_fill_array(&jail->mount, tb[JAIL_ATTR_MOUNT], NULL, false);
777         }
778         if (in->seccomp)
779                 jail->argc += 2;
780
781         return 1;
782 }
783
784 static bool
785 instance_config_parse_command(struct service_instance *in, struct blob_attr **tb)
786 {
787         struct blob_attr *cur, *cur2;
788         bool ret = false;
789         int rem;
790
791         cur = tb[INSTANCE_ATTR_COMMAND];
792         if (!cur) {
793                 in->command = NULL;
794                 return true;
795         }
796
797         if (!blobmsg_check_attr_list(cur, BLOBMSG_TYPE_STRING))
798                 return false;
799
800         blobmsg_for_each_attr(cur2, cur, rem) {
801                 ret = true;
802                 break;
803         }
804
805         in->command = cur;
806         return ret;
807 }
808
809 static bool
810 instance_config_parse(struct service_instance *in)
811 {
812         struct blob_attr *tb[__INSTANCE_ATTR_MAX];
813         struct blob_attr *cur, *cur2;
814         int rem;
815
816         blobmsg_parse(instance_attr, __INSTANCE_ATTR_MAX, tb,
817                 blobmsg_data(in->config), blobmsg_data_len(in->config));
818
819         if (!instance_config_parse_command(in, tb))
820                 return false;
821
822         if (tb[INSTANCE_ATTR_TERMTIMEOUT])
823                 in->term_timeout = blobmsg_get_u32(tb[INSTANCE_ATTR_TERMTIMEOUT]);
824         if (tb[INSTANCE_ATTR_RESPAWN]) {
825                 int i = 0;
826                 uint32_t vals[3] = { 3600, 5, 5};
827
828                 blobmsg_for_each_attr(cur2, tb[INSTANCE_ATTR_RESPAWN], rem) {
829                         if ((i >= 3) && (blobmsg_type(cur2) == BLOBMSG_TYPE_STRING))
830                                 continue;
831                         vals[i] = atoi(blobmsg_get_string(cur2));
832                         i++;
833                 }
834                 in->respawn = true;
835                 in->respawn_count = 0;
836                 in->respawn_threshold = vals[0];
837                 in->respawn_timeout = vals[1];
838                 in->respawn_retry = vals[2];
839         }
840         if (tb[INSTANCE_ATTR_TRIGGER]) {
841                 in->trigger = tb[INSTANCE_ATTR_TRIGGER];
842                 trigger_add(in->trigger, in);
843         }
844
845         if (tb[INSTANCE_ATTR_WATCH]) {
846                 blobmsg_for_each_attr(cur2, tb[INSTANCE_ATTR_WATCH], rem) {
847                         if (blobmsg_type(cur2) != BLOBMSG_TYPE_STRING)
848                                 continue;
849                         DEBUG(3, "watch for %s\n", blobmsg_get_string(cur2));
850                         watch_add(blobmsg_get_string(cur2), in);
851                 }
852         }
853
854         if ((cur = tb[INSTANCE_ATTR_NICE])) {
855                 in->nice = (int8_t) blobmsg_get_u32(cur);
856                 if (in->nice < -20 || in->nice > 20)
857                         return false;
858         }
859
860         if (tb[INSTANCE_ATTR_USER]) {
861                 struct passwd *p = getpwnam(blobmsg_get_string(tb[INSTANCE_ATTR_USER]));
862                 if (p) {
863                         in->uid = p->pw_uid;
864                         in->gid = p->pw_gid;
865                 }
866         }
867
868         if (tb[INSTANCE_ATTR_TRACE])
869                 in->trace = blobmsg_get_bool(tb[INSTANCE_ATTR_TRACE]);
870
871         if (tb[INSTANCE_ATTR_NO_NEW_PRIVS])
872                 in->no_new_privs = blobmsg_get_bool(tb[INSTANCE_ATTR_NO_NEW_PRIVS]);
873
874         if (!in->trace && tb[INSTANCE_ATTR_SECCOMP]) {
875                 char *seccomp = blobmsg_get_string(tb[INSTANCE_ATTR_SECCOMP]);
876                 struct stat s;
877
878                 if (stat(seccomp, &s))
879                         ERROR("%s: not starting seccomp as %s is missing\n", in->name, seccomp);
880                 else
881                         in->seccomp = seccomp;
882         }
883
884         if (tb[INSTANCE_ATTR_PIDFILE]) {
885                 char *pidfile = blobmsg_get_string(tb[INSTANCE_ATTR_PIDFILE]);
886                 if (pidfile)
887                         in->pidfile = pidfile;
888         }
889
890         if (tb[INSTANCE_ATTR_RELOADSIG])
891                 in->reload_signal = blobmsg_get_u32(tb[INSTANCE_ATTR_RELOADSIG]);
892
893         if (!in->trace && tb[INSTANCE_ATTR_JAIL])
894                 in->has_jail = instance_jail_parse(in, tb[INSTANCE_ATTR_JAIL]);
895
896         if (tb[INSTANCE_ATTR_STDOUT] && blobmsg_get_bool(tb[INSTANCE_ATTR_STDOUT]))
897                 in->_stdout.fd.fd = -1;
898
899         if (tb[INSTANCE_ATTR_STDERR] && blobmsg_get_bool(tb[INSTANCE_ATTR_STDERR]))
900                 in->_stderr.fd.fd = -1;
901
902         instance_fill_any(&in->data, tb[INSTANCE_ATTR_DATA]);
903
904         if (!instance_fill_array(&in->env, tb[INSTANCE_ATTR_ENV], NULL, false))
905                 return false;
906
907         if (!instance_fill_array(&in->netdev, tb[INSTANCE_ATTR_NETDEV], instance_netdev_update, true))
908                 return false;
909
910         if (!instance_fill_array(&in->file, tb[INSTANCE_ATTR_FILE], instance_file_update, true))
911                 return false;
912
913         if (!instance_fill_array(&in->limits, tb[INSTANCE_ATTR_LIMITS], NULL, false))
914                 return false;
915
916         if (!instance_fill_array(&in->errors, tb[INSTANCE_ATTR_ERROR], NULL, true))
917                 return false;
918
919         return true;
920 }
921
922 static void
923 instance_config_cleanup(struct service_instance *in)
924 {
925         blobmsg_list_free(&in->env);
926         blobmsg_list_free(&in->data);
927         blobmsg_list_free(&in->netdev);
928         blobmsg_list_free(&in->file);
929         blobmsg_list_free(&in->limits);
930         blobmsg_list_free(&in->errors);
931         blobmsg_list_free(&in->jail.mount);
932 }
933
934 static void
935 instance_config_move(struct service_instance *in, struct service_instance *in_src)
936 {
937         instance_config_cleanup(in);
938         blobmsg_list_move(&in->env, &in_src->env);
939         blobmsg_list_move(&in->data, &in_src->data);
940         blobmsg_list_move(&in->netdev, &in_src->netdev);
941         blobmsg_list_move(&in->file, &in_src->file);
942         blobmsg_list_move(&in->limits, &in_src->limits);
943         blobmsg_list_move(&in->errors, &in_src->errors);
944         blobmsg_list_move(&in->jail.mount, &in_src->jail.mount);
945         in->trigger = in_src->trigger;
946         in->command = in_src->command;
947         in->pidfile = in_src->pidfile;
948         in->name = in_src->name;
949         in->node.avl.key = in_src->node.avl.key;
950
951         free(in->config);
952         in->config = in_src->config;
953         in_src->config = NULL;
954 }
955
956 void
957 instance_update(struct service_instance *in, struct service_instance *in_new)
958 {
959         bool changed = instance_config_changed(in, in_new);
960         bool running = in->proc.pending;
961         bool stopping = in->halt;
962
963         if (!running || stopping) {
964                 instance_config_move(in, in_new);
965                 instance_start(in);
966         } else {
967                 if (changed)
968                         instance_restart(in);
969                 instance_config_move(in, in_new);
970                 /* restart happens in the child callback handler */
971         }
972 }
973
974 void
975 instance_free(struct service_instance *in)
976 {
977         instance_free_stdio(in);
978         uloop_process_delete(&in->proc);
979         uloop_timeout_cancel(&in->timeout);
980         trigger_del(in);
981         watch_del(in);
982         instance_config_cleanup(in);
983         free(in->config);
984         free(in);
985 }
986
987 void
988 instance_init(struct service_instance *in, struct service *s, struct blob_attr *config)
989 {
990         config = blob_memdup(config);
991         in->srv = s;
992         in->name = blobmsg_name(config);
993         in->config = config;
994         in->timeout.cb = instance_timeout;
995         in->proc.cb = instance_exit;
996         in->term_timeout = 5;
997
998         in->_stdout.fd.fd = -2;
999         in->_stdout.stream.string_data = true;
1000         in->_stdout.stream.notify_read = instance_stdout;
1001
1002         in->_stderr.fd.fd = -2;
1003         in->_stderr.stream.string_data = true;
1004         in->_stderr.stream.notify_read = instance_stderr;
1005
1006         blobmsg_list_init(&in->netdev, struct instance_netdev, node, instance_netdev_cmp);
1007         blobmsg_list_init(&in->file, struct instance_file, node, instance_file_cmp);
1008         blobmsg_list_simple_init(&in->env);
1009         blobmsg_list_simple_init(&in->data);
1010         blobmsg_list_simple_init(&in->limits);
1011         blobmsg_list_simple_init(&in->errors);
1012         blobmsg_list_simple_init(&in->jail.mount);
1013         in->valid = instance_config_parse(in);
1014 }
1015
1016 void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose)
1017 {
1018         void *i;
1019
1020         if (!in->valid)
1021                 return;
1022
1023         i = blobmsg_open_table(b, in->name);
1024         blobmsg_add_u8(b, "running", in->proc.pending);
1025         if (in->proc.pending)
1026                 blobmsg_add_u32(b, "pid", in->proc.pid);
1027         if (in->command)
1028                 blobmsg_add_blob(b, in->command);
1029         blobmsg_add_u32(b, "term_timeout", in->term_timeout);
1030
1031         if (!avl_is_empty(&in->errors.avl)) {
1032                 struct blobmsg_list_node *var;
1033                 void *e = blobmsg_open_array(b, "errors");
1034                 blobmsg_list_for_each(&in->errors, var)
1035                         blobmsg_add_string(b, NULL, blobmsg_data(var->data));
1036                 blobmsg_close_table(b, e);
1037         }
1038
1039         if (!avl_is_empty(&in->env.avl)) {
1040                 struct blobmsg_list_node *var;
1041                 void *e = blobmsg_open_table(b, "env");
1042                 blobmsg_list_for_each(&in->env, var)
1043                         blobmsg_add_string(b, blobmsg_name(var->data), blobmsg_data(var->data));
1044                 blobmsg_close_table(b, e);
1045         }
1046
1047         if (!avl_is_empty(&in->data.avl)) {
1048                 struct blobmsg_list_node *var;
1049                 void *e = blobmsg_open_table(b, "data");
1050                 blobmsg_list_for_each(&in->data, var)
1051                         blobmsg_add_blob(b, var->data);
1052                 blobmsg_close_table(b, e);
1053         }
1054
1055         if (!avl_is_empty(&in->limits.avl)) {
1056                 struct blobmsg_list_node *var;
1057                 void *e = blobmsg_open_table(b, "limits");
1058                 blobmsg_list_for_each(&in->limits, var)
1059                         blobmsg_add_string(b, blobmsg_name(var->data), blobmsg_data(var->data));
1060                 blobmsg_close_table(b, e);
1061         }
1062
1063         if (in->reload_signal)
1064                 blobmsg_add_u32(b, "reload_signal", in->reload_signal);
1065
1066         if (in->respawn) {
1067                 void *r = blobmsg_open_table(b, "respawn");
1068                 blobmsg_add_u32(b, "threshold", in->respawn_threshold);
1069                 blobmsg_add_u32(b, "timeout", in->respawn_timeout);
1070                 blobmsg_add_u32(b, "retry", in->respawn_retry);
1071                 blobmsg_close_table(b, r);
1072         }
1073
1074         if (in->trace)
1075                 blobmsg_add_u8(b, "trace", true);
1076
1077         if (in->no_new_privs)
1078                 blobmsg_add_u8(b, "no_new_privs", true);
1079
1080         if (in->seccomp)
1081                 blobmsg_add_string(b, "seccomp", in->seccomp);
1082
1083         if (in->pidfile)
1084                 blobmsg_add_string(b, "pidfile", in->pidfile);
1085
1086         if (in->has_jail) {
1087                 void *r = blobmsg_open_table(b, "jail");
1088                 if (in->jail.name)
1089                         blobmsg_add_string(b, "name", in->jail.name);
1090                 if (in->jail.hostname)
1091                         blobmsg_add_string(b, "hostname", in->jail.hostname);
1092                 blobmsg_add_u8(b, "procfs", in->jail.procfs);
1093                 blobmsg_add_u8(b, "sysfs", in->jail.sysfs);
1094                 blobmsg_add_u8(b, "ubus", in->jail.ubus);
1095                 blobmsg_add_u8(b, "log", in->jail.log);
1096                 blobmsg_add_u8(b, "ronly", in->jail.ronly);
1097                 blobmsg_close_table(b, r);
1098                 if (!avl_is_empty(&in->jail.mount.avl)) {
1099                         struct blobmsg_list_node *var;
1100                         void *e = blobmsg_open_table(b, "mount");
1101                         blobmsg_list_for_each(&in->jail.mount, var)
1102                                 blobmsg_add_string(b, blobmsg_name(var->data), blobmsg_data(var->data));
1103                         blobmsg_close_table(b, e);
1104                 }
1105         }
1106
1107         if (verbose && in->trigger)
1108                 blobmsg_add_blob(b, in->trigger);
1109
1110         blobmsg_close_table(b, i);
1111 }