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 <grp.h> 21 #include <net/if.h> 22 #include <unistd.h> 23 #include <stdint.h> 24 #include <stdio.h> 25 #include <fcntl.h> 26 #include <pwd.h> 27 #include <libgen.h> 28 #include <unistd.h> 29 #define SYSLOG_NAMES 30 #include <syslog.h> 31 32 #include <libubox/md5.h> 33 34 #include "../procd.h" 35 36 #include "service.h" 37 #include "instance.h" 38 39 #define UJAIL_BIN_PATH "/sbin/ujail" 40 #define CGROUP_BASEDIR "/sys/fs/cgroup/services" 41 42 enum { 43 INSTANCE_ATTR_COMMAND, 44 INSTANCE_ATTR_ENV, 45 INSTANCE_ATTR_DATA, 46 INSTANCE_ATTR_NETDEV, 47 INSTANCE_ATTR_FILE, 48 INSTANCE_ATTR_TRIGGER, 49 INSTANCE_ATTR_RESPAWN, 50 INSTANCE_ATTR_NICE, 51 INSTANCE_ATTR_LIMITS, 52 INSTANCE_ATTR_WATCH, 53 INSTANCE_ATTR_ERROR, 54 INSTANCE_ATTR_USER, 55 INSTANCE_ATTR_GROUP, 56 INSTANCE_ATTR_STDOUT, 57 INSTANCE_ATTR_STDERR, 58 INSTANCE_ATTR_NO_NEW_PRIVS, 59 INSTANCE_ATTR_JAIL, 60 INSTANCE_ATTR_TRACE, 61 INSTANCE_ATTR_SECCOMP, 62 INSTANCE_ATTR_CAPABILITIES, 63 INSTANCE_ATTR_PIDFILE, 64 INSTANCE_ATTR_RELOADSIG, 65 INSTANCE_ATTR_TERMTIMEOUT, 66 INSTANCE_ATTR_FACILITY, 67 INSTANCE_ATTR_EXTROOT, 68 INSTANCE_ATTR_OVERLAYDIR, 69 INSTANCE_ATTR_TMPOVERLAYSIZE, 70 INSTANCE_ATTR_BUNDLE, 71 INSTANCE_ATTR_WATCHDOG, 72 __INSTANCE_ATTR_MAX 73 }; 74 75 static const struct blobmsg_policy instance_attr[__INSTANCE_ATTR_MAX] = { 76 [INSTANCE_ATTR_COMMAND] = { "command", BLOBMSG_TYPE_ARRAY }, 77 [INSTANCE_ATTR_ENV] = { "env", BLOBMSG_TYPE_TABLE }, 78 [INSTANCE_ATTR_DATA] = { "data", BLOBMSG_TYPE_TABLE }, 79 [INSTANCE_ATTR_NETDEV] = { "netdev", BLOBMSG_TYPE_ARRAY }, 80 [INSTANCE_ATTR_FILE] = { "file", BLOBMSG_TYPE_ARRAY }, 81 [INSTANCE_ATTR_TRIGGER] = { "triggers", BLOBMSG_TYPE_ARRAY }, 82 [INSTANCE_ATTR_RESPAWN] = { "respawn", BLOBMSG_TYPE_ARRAY }, 83 [INSTANCE_ATTR_NICE] = { "nice", BLOBMSG_TYPE_INT32 }, 84 [INSTANCE_ATTR_LIMITS] = { "limits", BLOBMSG_TYPE_TABLE }, 85 [INSTANCE_ATTR_WATCH] = { "watch", BLOBMSG_TYPE_ARRAY }, 86 [INSTANCE_ATTR_ERROR] = { "error", BLOBMSG_TYPE_ARRAY }, 87 [INSTANCE_ATTR_USER] = { "user", BLOBMSG_TYPE_STRING }, 88 [INSTANCE_ATTR_GROUP] = { "group", BLOBMSG_TYPE_STRING }, 89 [INSTANCE_ATTR_STDOUT] = { "stdout", BLOBMSG_TYPE_BOOL }, 90 [INSTANCE_ATTR_STDERR] = { "stderr", BLOBMSG_TYPE_BOOL }, 91 [INSTANCE_ATTR_NO_NEW_PRIVS] = { "no_new_privs", BLOBMSG_TYPE_BOOL }, 92 [INSTANCE_ATTR_JAIL] = { "jail", BLOBMSG_TYPE_TABLE }, 93 [INSTANCE_ATTR_TRACE] = { "trace", BLOBMSG_TYPE_BOOL }, 94 [INSTANCE_ATTR_SECCOMP] = { "seccomp", BLOBMSG_TYPE_STRING }, 95 [INSTANCE_ATTR_CAPABILITIES] = { "capabilities", BLOBMSG_TYPE_STRING }, 96 [INSTANCE_ATTR_PIDFILE] = { "pidfile", BLOBMSG_TYPE_STRING }, 97 [INSTANCE_ATTR_RELOADSIG] = { "reload_signal", BLOBMSG_TYPE_INT32 }, 98 [INSTANCE_ATTR_TERMTIMEOUT] = { "term_timeout", BLOBMSG_TYPE_INT32 }, 99 [INSTANCE_ATTR_FACILITY] = { "facility", BLOBMSG_TYPE_STRING }, 100 [INSTANCE_ATTR_EXTROOT] = { "extroot", BLOBMSG_TYPE_STRING }, 101 [INSTANCE_ATTR_OVERLAYDIR] = { "overlaydir", BLOBMSG_TYPE_STRING }, 102 [INSTANCE_ATTR_TMPOVERLAYSIZE] = { "tmpoverlaysize", BLOBMSG_TYPE_STRING }, 103 [INSTANCE_ATTR_BUNDLE] = { "bundle", BLOBMSG_TYPE_STRING }, 104 [INSTANCE_ATTR_WATCHDOG] = { "watchdog", BLOBMSG_TYPE_ARRAY }, 105 }; 106 107 enum { 108 JAIL_ATTR_NAME, 109 JAIL_ATTR_HOSTNAME, 110 JAIL_ATTR_PROCFS, 111 JAIL_ATTR_SYSFS, 112 JAIL_ATTR_UBUS, 113 JAIL_ATTR_LOG, 114 JAIL_ATTR_RONLY, 115 JAIL_ATTR_MOUNT, 116 JAIL_ATTR_NETNS, 117 JAIL_ATTR_USERNS, 118 JAIL_ATTR_CGROUPSNS, 119 JAIL_ATTR_CONSOLE, 120 JAIL_ATTR_REQUIREJAIL, 121 JAIL_ATTR_IMMEDIATELY, 122 JAIL_ATTR_PIDFILE, 123 JAIL_ATTR_SETNS, 124 __JAIL_ATTR_MAX, 125 }; 126 127 static const struct blobmsg_policy jail_attr[__JAIL_ATTR_MAX] = { 128 [JAIL_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING }, 129 [JAIL_ATTR_HOSTNAME] = { "hostname", BLOBMSG_TYPE_STRING }, 130 [JAIL_ATTR_PROCFS] = { "procfs", BLOBMSG_TYPE_BOOL }, 131 [JAIL_ATTR_SYSFS] = { "sysfs", BLOBMSG_TYPE_BOOL }, 132 [JAIL_ATTR_UBUS] = { "ubus", BLOBMSG_TYPE_BOOL }, 133 [JAIL_ATTR_LOG] = { "log", BLOBMSG_TYPE_BOOL }, 134 [JAIL_ATTR_RONLY] = { "ronly", BLOBMSG_TYPE_BOOL }, 135 [JAIL_ATTR_MOUNT] = { "mount", BLOBMSG_TYPE_TABLE }, 136 [JAIL_ATTR_NETNS] = { "netns", BLOBMSG_TYPE_BOOL }, 137 [JAIL_ATTR_USERNS] = { "userns", BLOBMSG_TYPE_BOOL }, 138 [JAIL_ATTR_CGROUPSNS] = { "cgroupsns", BLOBMSG_TYPE_BOOL }, 139 [JAIL_ATTR_CONSOLE] = { "console", BLOBMSG_TYPE_BOOL }, 140 [JAIL_ATTR_REQUIREJAIL] = { "requirejail", BLOBMSG_TYPE_BOOL }, 141 [JAIL_ATTR_IMMEDIATELY] = { "immediately", BLOBMSG_TYPE_BOOL }, 142 [JAIL_ATTR_PIDFILE] = { "pidfile", BLOBMSG_TYPE_STRING }, 143 [JAIL_ATTR_SETNS] = { "setns", BLOBMSG_TYPE_ARRAY }, 144 }; 145 146 enum { 147 JAIL_SETNS_ATTR_PID, 148 JAIL_SETNS_ATTR_NS, 149 __JAIL_SETNS_ATTR_MAX, 150 }; 151 152 static const struct blobmsg_policy jail_setns_attr[__JAIL_SETNS_ATTR_MAX] = { 153 [JAIL_SETNS_ATTR_PID] = { "pid", BLOBMSG_TYPE_INT32 }, 154 [JAIL_SETNS_ATTR_NS] = { "namespaces", BLOBMSG_TYPE_ARRAY }, 155 }; 156 157 struct instance_netdev { 158 struct blobmsg_list_node node; 159 int ifindex; 160 }; 161 162 struct instance_file { 163 struct blobmsg_list_node node; 164 uint32_t md5[4]; 165 }; 166 167 struct rlimit_name { 168 const char *name; 169 int resource; 170 }; 171 172 static const struct rlimit_name rlimit_names[] = { 173 { "as", RLIMIT_AS }, 174 { "core", RLIMIT_CORE }, 175 { "cpu", RLIMIT_CPU }, 176 { "data", RLIMIT_DATA }, 177 { "fsize", RLIMIT_FSIZE }, 178 { "memlock", RLIMIT_MEMLOCK }, 179 { "nofile", RLIMIT_NOFILE }, 180 { "nproc", RLIMIT_NPROC }, 181 { "rss", RLIMIT_RSS }, 182 { "stack", RLIMIT_STACK }, 183 #ifdef linux 184 { "nice", RLIMIT_NICE }, 185 { "rtprio", RLIMIT_RTPRIO }, 186 { "msgqueue", RLIMIT_MSGQUEUE }, 187 { "sigpending", RLIMIT_SIGPENDING }, 188 #endif 189 { NULL, 0 } 190 }; 191 192 static void closefd(int fd) 193 { 194 if (fd > STDERR_FILENO) 195 close(fd); 196 } 197 198 /* convert a string into numeric syslog facility or return -1 if no match found */ 199 static int 200 syslog_facility_str_to_int(const char *facility) 201 { 202 CODE *p = facilitynames; 203 204 while (p->c_name && strcasecmp(p->c_name, facility)) 205 p++; 206 207 return p->c_val; 208 } 209 210 static void 211 instance_limits(const char *limit, const char *value) 212 { 213 int i; 214 struct rlimit rlim; 215 unsigned long cur, max; 216 217 for (i = 0; rlimit_names[i].name != NULL; i++) { 218 if (strcmp(rlimit_names[i].name, limit)) 219 continue; 220 if (!strcmp(value, "unlimited")) { 221 rlim.rlim_cur = RLIM_INFINITY; 222 rlim.rlim_max = RLIM_INFINITY; 223 } else { 224 if (getrlimit(rlimit_names[i].resource, &rlim)) 225 return; 226 227 cur = rlim.rlim_cur; 228 max = rlim.rlim_max; 229 230 if (sscanf(value, "%lu %lu", &cur, &max) < 1) 231 return; 232 233 rlim.rlim_cur = cur; 234 rlim.rlim_max = max; 235 } 236 237 setrlimit(rlimit_names[i].resource, &rlim); 238 return; 239 } 240 } 241 242 static char * 243 instance_gen_setns_argstr(struct blob_attr *attr) 244 { 245 struct blob_attr *tb[__JAIL_SETNS_ATTR_MAX]; 246 struct blob_attr *cur; 247 int rem, len, total; 248 char *ret; 249 250 blobmsg_parse(jail_setns_attr, __JAIL_SETNS_ATTR_MAX, tb, 251 blobmsg_data(attr), blobmsg_data_len(attr)); 252 253 if (!tb[JAIL_SETNS_ATTR_PID] || !tb[JAIL_SETNS_ATTR_NS]) 254 return NULL; 255 256 len = snprintf(NULL, 0, "%d:", blobmsg_get_u32(tb[JAIL_SETNS_ATTR_PID])); 257 258 blobmsg_for_each_attr(cur, tb[JAIL_SETNS_ATTR_NS], rem) { 259 char *tmp; 260 261 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) 262 return NULL; 263 264 tmp = blobmsg_get_string(cur); 265 if (!tmp) 266 return NULL; 267 268 len += strlen(tmp) + 1; 269 } 270 271 total = len; 272 ret = malloc(total); 273 if (!ret) 274 return NULL; 275 276 len = snprintf(ret, total, "%d:", blobmsg_get_u32(tb[JAIL_SETNS_ATTR_PID])); 277 278 blobmsg_for_each_attr(cur, tb[JAIL_SETNS_ATTR_NS], rem) { 279 strncpy(&ret[len], blobmsg_get_string(cur), total - len); 280 len += strlen(blobmsg_get_string(cur)); 281 ret[len++] = ','; 282 } 283 ret[total - 1] = '\0'; 284 285 return ret; 286 } 287 288 static inline int 289 jail_run(struct service_instance *in, char **argv) 290 { 291 char *term_timeout_str; 292 struct blobmsg_list_node *var; 293 struct jail *jail = &in->jail; 294 int argc = 0; 295 296 argv[argc++] = UJAIL_BIN_PATH; 297 298 if (asprintf(&term_timeout_str, "%d", in->term_timeout) == -1) 299 exit(ENOMEM); 300 301 argv[argc++] = "-t"; 302 argv[argc++] = term_timeout_str; 303 304 if (jail->name) { 305 argv[argc++] = "-n"; 306 argv[argc++] = jail->name; 307 } 308 309 if (jail->hostname) { 310 argv[argc++] = "-h"; 311 argv[argc++] = jail->hostname; 312 } 313 314 if (in->seccomp) { 315 argv[argc++] = "-S"; 316 argv[argc++] = in->seccomp; 317 } 318 319 if (in->user) { 320 argv[argc++] = "-U"; 321 argv[argc++] = in->user; 322 } 323 324 if (in->group) { 325 argv[argc++] = "-G"; 326 argv[argc++] = in->group; 327 } 328 329 if (in->capabilities) { 330 argv[argc++] = "-C"; 331 argv[argc++] = in->capabilities; 332 } 333 334 if (in->no_new_privs) 335 argv[argc++] = "-c"; 336 337 if (jail->procfs) 338 argv[argc++] = "-p"; 339 340 if (jail->sysfs) 341 argv[argc++] = "-s"; 342 343 if (jail->ubus) 344 argv[argc++] = "-u"; 345 346 if (jail->log) 347 argv[argc++] = "-l"; 348 349 if (jail->ronly) 350 argv[argc++] = "-o"; 351 352 if (jail->netns) 353 argv[argc++] = "-N"; 354 355 if (jail->userns) 356 argv[argc++] = "-f"; 357 358 if (jail->cgroupsns) 359 argv[argc++] = "-F"; 360 361 if (jail->console) 362 argv[argc++] = "-y"; 363 364 if (in->extroot) { 365 argv[argc++] = "-R"; 366 argv[argc++] = in->extroot; 367 } 368 369 if (in->overlaydir) { 370 argv[argc++] = "-O"; 371 argv[argc++] = in->overlaydir; 372 } 373 374 if (in->tmpoverlaysize) { 375 argv[argc++] = "-T"; 376 argv[argc++] = in->tmpoverlaysize; 377 } 378 379 if (in->immediately) 380 argv[argc++] = "-i"; 381 382 if (jail->pidfile) { 383 argv[argc++] = "-P"; 384 argv[argc++] = jail->pidfile; 385 } 386 387 if (in->bundle) { 388 argv[argc++] = "-J"; 389 argv[argc++] = in->bundle; 390 } 391 392 if (in->require_jail) 393 argv[argc++] = "-E"; 394 395 blobmsg_list_for_each(&in->env, var) { 396 argv[argc++] = "-e"; 397 argv[argc++] = (char *) blobmsg_name(var->data); 398 } 399 400 blobmsg_list_for_each(&jail->mount, var) { 401 const char *type = blobmsg_data(var->data); 402 403 if (*type == '1') 404 argv[argc++] = "-w"; 405 else 406 argv[argc++] = "-r"; 407 argv[argc++] = (char *) blobmsg_name(var->data); 408 } 409 410 blobmsg_list_for_each(&jail->setns, var) { 411 char *setns_arg = instance_gen_setns_argstr(var->data); 412 413 if (setns_arg) { 414 argv[argc++] = "-j"; 415 argv[argc++] = setns_arg; 416 } 417 } 418 419 argv[argc++] = "--"; 420 421 return argc; 422 } 423 424 static int 425 instance_removepid(struct service_instance *in) { 426 if (!in->pidfile) 427 return 0; 428 if (unlink(in->pidfile)) { 429 ERROR("Failed to remove pidfile: %s: %m\n", in->pidfile); 430 return 1; 431 } 432 return 0; 433 } 434 435 static int 436 instance_writepid(struct service_instance *in) 437 { 438 FILE *_pidfile; 439 440 if (!in->pidfile) { 441 return 0; 442 } 443 _pidfile = fopen(in->pidfile, "w"); 444 if (_pidfile == NULL) { 445 ERROR("failed to open pidfile for writing: %s: %m", in->pidfile); 446 return 1; 447 } 448 if (fprintf(_pidfile, "%d\n", in->proc.pid) < 0) { 449 ERROR("failed to write pidfile: %s: %m", in->pidfile); 450 fclose(_pidfile); 451 return 2; 452 } 453 if (fclose(_pidfile)) { 454 ERROR("failed to close pidfile: %s: %m", in->pidfile); 455 return 3; 456 } 457 458 return 0; 459 } 460 461 static void 462 instance_run(struct service_instance *in, int _stdout, int _stderr) 463 { 464 struct blobmsg_list_node *var; 465 struct blob_attr *cur; 466 char **argv; 467 int argc = 1; /* NULL terminated */ 468 int rem, _stdin; 469 bool seccomp = !in->trace && !in->has_jail && in->seccomp; 470 bool setlbf = _stdout >= 0; 471 472 if (in->nice) 473 setpriority(PRIO_PROCESS, 0, in->nice); 474 475 blobmsg_for_each_attr(cur, in->command, rem) 476 argc++; 477 478 blobmsg_list_for_each(&in->env, var) 479 setenv(blobmsg_name(var->data), blobmsg_data(var->data), 1); 480 481 if (seccomp) 482 setenv("SECCOMP_FILE", in->seccomp, 1); 483 484 if (setlbf) 485 setenv("LD_PRELOAD", "/lib/libsetlbf.so", 1); 486 487 blobmsg_list_for_each(&in->limits, var) 488 instance_limits(blobmsg_name(var->data), blobmsg_data(var->data)); 489 490 if (in->trace || seccomp) 491 argc += 1; 492 493 argv = alloca(sizeof(char *) * (argc + in->jail.argc)); 494 argc = 0; 495 496 #ifdef SECCOMP_SUPPORT 497 if (in->trace) 498 argv[argc++] = "/sbin/utrace"; 499 else if (seccomp) 500 argv[argc++] = "/sbin/seccomp-trace"; 501 #else 502 if (in->trace || seccomp) 503 ULOG_WARN("Seccomp support for %s::%s not available\n", in->srv->name, in->name); 504 #endif 505 506 if (in->has_jail) { 507 argc = jail_run(in, argv); 508 if (argc != in->jail.argc) 509 ULOG_WARN("expected %i jail params, used %i for %s::%s\n", 510 in->jail.argc, argc, in->srv->name, in->name); 511 } 512 513 blobmsg_for_each_attr(cur, in->command, rem) 514 argv[argc++] = blobmsg_data(cur); 515 516 argv[argc] = NULL; 517 518 _stdin = open("/dev/null", O_RDONLY); 519 520 if (_stdout == -1) 521 _stdout = open("/dev/null", O_WRONLY); 522 523 if (_stderr == -1) 524 _stderr = open("/dev/null", O_WRONLY); 525 526 if (_stdin > -1) { 527 dup2(_stdin, STDIN_FILENO); 528 closefd(_stdin); 529 } 530 if (_stdout > -1) { 531 dup2(_stdout, STDOUT_FILENO); 532 closefd(_stdout); 533 } 534 if (_stderr > -1) { 535 dup2(_stderr, STDERR_FILENO); 536 closefd(_stderr); 537 } 538 539 if (!in->has_jail && in->user && in->pw_gid && initgroups(in->user, in->pw_gid)) { 540 ERROR("failed to initgroups() for user %s: %m\n", in->user); 541 exit(127); 542 } 543 if (!in->has_jail && in->gr_gid && setgid(in->gr_gid)) { 544 ERROR("failed to set group id %d: %m\n", in->gr_gid); 545 exit(127); 546 } 547 if (!in->has_jail && in->uid && setuid(in->uid)) { 548 ERROR("failed to set user id %d: %m\n", in->uid); 549 exit(127); 550 } 551 552 execvp(argv[0], argv); 553 exit(127); 554 } 555 556 static void 557 instance_add_cgroup(const char *service, const char *instance) 558 { 559 struct stat sb; 560 char cgnamebuf[256]; 561 int fd; 562 563 if (stat("/sys/fs/cgroup/cgroup.subtree_control", &sb)) 564 return; 565 566 mkdir(CGROUP_BASEDIR, 0700); 567 568 snprintf(cgnamebuf, sizeof(cgnamebuf), "%s/%s", CGROUP_BASEDIR, service); 569 mkdir(cgnamebuf, 0700); 570 snprintf(cgnamebuf, sizeof(cgnamebuf), "%s/%s/%s", CGROUP_BASEDIR, service, instance); 571 mkdir(cgnamebuf, 0700); 572 strcat(cgnamebuf, "/cgroup.procs"); 573 574 fd = open(cgnamebuf, O_WRONLY); 575 if (fd == -1) 576 return; 577 578 dprintf(fd, "%d", getpid()); 579 close(fd); 580 } 581 582 static void 583 instance_free_stdio(struct service_instance *in) 584 { 585 if (in->_stdout.fd.fd > -1) { 586 ustream_free(&in->_stdout.stream); 587 close(in->_stdout.fd.fd); 588 in->_stdout.fd.fd = -1; 589 } 590 591 if (in->_stderr.fd.fd > -1) { 592 ustream_free(&in->_stderr.stream); 593 close(in->_stderr.fd.fd); 594 in->_stderr.fd.fd = -1; 595 } 596 597 if (in->console.fd.fd > -1) { 598 ustream_free(&in->console.stream); 599 close(in->console.fd.fd); 600 in->console.fd.fd = -1; 601 } 602 603 if (in->console_client.fd.fd > -1) { 604 ustream_free(&in->console_client.stream); 605 close(in->console_client.fd.fd); 606 in->console_client.fd.fd = -1; 607 } 608 } 609 610 void 611 instance_start(struct service_instance *in) 612 { 613 int pid; 614 int opipe[2] = { -1, -1 }; 615 int epipe[2] = { -1, -1 }; 616 617 if (!avl_is_empty(&in->errors.avl)) { 618 LOG("Not starting instance %s::%s, an error was indicated\n", in->srv->name, in->name); 619 return; 620 } 621 622 if (!in->bundle && !in->command) { 623 LOG("Not starting instance %s::%s, command not set\n", in->srv->name, in->name); 624 return; 625 } 626 627 if (in->proc.pending) { 628 if (in->halt) 629 in->restart = true; 630 return; 631 } 632 633 instance_free_stdio(in); 634 if (in->_stdout.fd.fd > -2) { 635 if (pipe(opipe)) { 636 ULOG_WARN("pipe() failed: %m\n"); 637 opipe[0] = opipe[1] = -1; 638 } 639 } 640 641 if (in->_stderr.fd.fd > -2) { 642 if (pipe(epipe)) { 643 ULOG_WARN("pipe() failed: %m\n"); 644 epipe[0] = epipe[1] = -1; 645 } 646 } 647 648 in->restart = false; 649 in->halt = false; 650 651 if (!in->valid) 652 return; 653 654 pid = fork(); 655 if (pid < 0) 656 return; 657 658 if (!pid) { 659 uloop_done(); 660 closefd(opipe[0]); 661 closefd(epipe[0]); 662 instance_add_cgroup(in->srv->name, in->name); 663 instance_run(in, opipe[1], epipe[1]); 664 return; 665 } 666 667 P_DEBUG(2, "Started instance %s::%s[%d]\n", in->srv->name, in->name, pid); 668 in->proc.pid = pid; 669 instance_writepid(in); 670 clock_gettime(CLOCK_MONOTONIC, &in->start); 671 uloop_process_add(&in->proc); 672 673 if (opipe[0] > -1) { 674 ustream_fd_init(&in->_stdout, opipe[0]); 675 closefd(opipe[1]); 676 fcntl(opipe[0], F_SETFD, FD_CLOEXEC); 677 } 678 679 if (epipe[0] > -1) { 680 ustream_fd_init(&in->_stderr, epipe[0]); 681 closefd(epipe[1]); 682 fcntl(epipe[0], F_SETFD, FD_CLOEXEC); 683 } 684 685 if (in->watchdog.mode != INSTANCE_WATCHDOG_MODE_DISABLED) { 686 uloop_timeout_set(&in->watchdog.timeout, in->watchdog.freq * 1000); 687 P_DEBUG(2, "Started instance %s::%s watchdog timer : timeout = %d\n", in->srv->name, in->name, in->watchdog.freq); 688 } 689 690 service_event("instance.start", in->srv->name, in->name); 691 } 692 693 static void 694 instance_stdio(struct ustream *s, int prio, struct service_instance *in) 695 { 696 char *newline, *str, *arg0, ident[32]; 697 int len; 698 699 arg0 = basename(blobmsg_data(blobmsg_data(in->command))); 700 snprintf(ident, sizeof(ident), "%s[%d]", arg0, in->proc.pid); 701 ulog_open(ULOG_SYSLOG, in->syslog_facility, ident); 702 703 do { 704 str = ustream_get_read_buf(s, &len); 705 if (!str) 706 break; 707 708 newline = memchr(str, '\n', len); 709 if (!newline && (s->r.buffer_len != len)) 710 break; 711 712 if (newline) { 713 *newline = 0; 714 len = newline + 1 - str; 715 } 716 ulog(prio, "%s\n", str); 717 718 ustream_consume(s, len); 719 } while (1); 720 721 ulog_open(ULOG_SYSLOG, LOG_DAEMON, "procd"); 722 } 723 724 static void 725 instance_stdout(struct ustream *s, int bytes) 726 { 727 instance_stdio(s, LOG_INFO, 728 container_of(s, struct service_instance, _stdout.stream)); 729 } 730 731 static void 732 instance_console(struct ustream *s, int bytes) 733 { 734 struct service_instance *in = container_of(s, struct service_instance, console.stream); 735 char *buf; 736 int len; 737 738 do { 739 buf = ustream_get_read_buf(s, &len); 740 if (!buf) 741 break; 742 743 ulog(LOG_INFO, "out: %s\n", buf); 744 745 /* test if console client is attached */ 746 if (in->console_client.fd.fd > -1) 747 ustream_write(&in->console_client.stream, buf, len, false); 748 749 ustream_consume(s, len); 750 } while (1); 751 } 752 753 static void 754 instance_console_client(struct ustream *s, int bytes) 755 { 756 struct service_instance *in = container_of(s, struct service_instance, console_client.stream); 757 char *buf; 758 int len; 759 760 do { 761 buf = ustream_get_read_buf(s, &len); 762 if (!buf) 763 break; 764 765 ulog(LOG_INFO, "in: %s\n", buf); 766 ustream_write(&in->console.stream, buf, len, false); 767 ustream_consume(s, len); 768 } while (1); 769 } 770 771 static void 772 instance_stderr(struct ustream *s, int bytes) 773 { 774 instance_stdio(s, LOG_ERR, 775 container_of(s, struct service_instance, _stderr.stream)); 776 } 777 778 static void 779 instance_timeout(struct uloop_timeout *t) 780 { 781 struct service_instance *in; 782 783 in = container_of(t, struct service_instance, timeout); 784 785 if (in->halt) { 786 LOG("Instance %s::%s pid %d not stopped on SIGTERM, sending SIGKILL instead\n", 787 in->srv->name, in->name, in->proc.pid); 788 kill(in->proc.pid, SIGKILL); 789 } else if (in->restart || in->respawn) 790 instance_start(in); 791 } 792 793 static void 794 instance_delete(struct service_instance *in) 795 { 796 struct service *s = in->srv; 797 798 avl_delete(&s->instances.avl, &in->node.avl); 799 instance_free(in); 800 service_stopped(s); 801 } 802 803 static int 804 instance_exit_code(int ret) 805 { 806 if (WIFEXITED(ret)) { 807 return WEXITSTATUS(ret); 808 } 809 810 if (WIFSIGNALED(ret)) { 811 return SIGNALLED_OFFSET + WTERMSIG(ret); 812 } 813 814 if (WIFSTOPPED(ret)) { 815 return WSTOPSIG(ret); 816 } 817 818 return 1; 819 } 820 821 static void 822 instance_exit(struct uloop_process *p, int ret) 823 { 824 struct service_instance *in; 825 struct timespec tp; 826 long runtime; 827 828 in = container_of(p, struct service_instance, proc); 829 830 clock_gettime(CLOCK_MONOTONIC, &tp); 831 runtime = tp.tv_sec - in->start.tv_sec; 832 833 P_DEBUG(2, "Instance %s::%s exit with error code %d after %ld seconds\n", in->srv->name, in->name, ret, runtime); 834 835 in->exit_code = instance_exit_code(ret); 836 uloop_timeout_cancel(&in->timeout); 837 uloop_timeout_cancel(&in->watchdog.timeout); 838 service_event("instance.stop", in->srv->name, in->name); 839 840 if (in->halt) { 841 instance_removepid(in); 842 if (in->restart) 843 instance_start(in); 844 else 845 instance_delete(in); 846 } else if (in->restart) { 847 instance_start(in); 848 } else if (in->respawn) { 849 if (runtime < in->respawn_threshold) 850 in->respawn_count++; 851 else 852 in->respawn_count = 0; 853 if (in->respawn_count > in->respawn_retry && in->respawn_retry > 0 ) { 854 LOG("Instance %s::%s s in a crash loop %d crashes, %ld seconds since last crash\n", 855 in->srv->name, in->name, in->respawn_count, runtime); 856 in->restart = in->respawn = 0; 857 in->halt = 1; 858 service_event("instance.fail", in->srv->name, in->name); 859 } else { 860 service_event("instance.respawn", in->srv->name, in->name); 861 uloop_timeout_set(&in->timeout, in->respawn_timeout * 1000); 862 } 863 } 864 } 865 866 void 867 instance_stop(struct service_instance *in, bool halt) 868 { 869 if (!in->proc.pending) { 870 if (halt) 871 instance_delete(in); 872 return; 873 } 874 in->halt = halt; 875 in->restart = in->respawn = false; 876 kill(in->proc.pid, SIGTERM); 877 if (!in->has_jail) 878 uloop_timeout_set(&in->timeout, in->term_timeout * 1000); 879 } 880 881 static void 882 instance_restart(struct service_instance *in) 883 { 884 if (!in->proc.pending) 885 return; 886 887 if (in->reload_signal) { 888 kill(in->proc.pid, in->reload_signal); 889 return; 890 } 891 892 in->halt = true; 893 in->restart = true; 894 kill(in->proc.pid, SIGTERM); 895 if (!in->has_jail) 896 uloop_timeout_set(&in->timeout, in->term_timeout * 1000); 897 } 898 899 static void 900 instance_watchdog(struct uloop_timeout *t) 901 { 902 struct service_instance *in = container_of(t, struct service_instance, watchdog.timeout); 903 904 P_DEBUG(3, "instance %s::%s watchdog timer expired\n", in->srv->name, in->name); 905 906 if (in->respawn) 907 instance_restart(in); 908 else 909 instance_stop(in, true); 910 } 911 912 static bool string_changed(const char *a, const char *b) 913 { 914 return !((!a && !b) || (a && b && !strcmp(a, b))); 915 } 916 917 static bool 918 instance_config_changed(struct service_instance *in, struct service_instance *in_new) 919 { 920 if (!in->valid) 921 return true; 922 923 if (!blob_attr_equal(in->command, in_new->command)) 924 return true; 925 926 if (string_changed(in->bundle, in_new->bundle)) 927 return true; 928 929 if (string_changed(in->extroot, in_new->extroot)) 930 return true; 931 932 if (string_changed(in->overlaydir, in_new->overlaydir)) 933 return true; 934 935 if (string_changed(in->tmpoverlaysize, in_new->tmpoverlaysize)) 936 return true; 937 938 if (!blobmsg_list_equal(&in->env, &in_new->env)) 939 return true; 940 941 if (!blobmsg_list_equal(&in->netdev, &in_new->netdev)) 942 return true; 943 944 if (!blobmsg_list_equal(&in->file, &in_new->file)) 945 return true; 946 947 if (in->nice != in_new->nice) 948 return true; 949 950 if (in->syslog_facility != in_new->syslog_facility) 951 return true; 952 953 if (string_changed(in->user, in_new->user)) 954 return true; 955 956 if (string_changed(in->group, in_new->group)) 957 return true; 958 959 if (in->uid != in_new->uid) 960 return true; 961 962 if (in->pw_gid != in_new->pw_gid) 963 return true; 964 965 if (in->gr_gid != in_new->gr_gid) 966 return true; 967 968 if (string_changed(in->pidfile, in_new->pidfile)) 969 return true; 970 971 if (in->respawn_retry != in_new->respawn_retry) 972 return true; 973 if (in->respawn_threshold != in_new->respawn_threshold) 974 return true; 975 if (in->respawn_timeout != in_new->respawn_timeout) 976 return true; 977 978 if (in->reload_signal != in_new->reload_signal) 979 return true; 980 981 if (in->term_timeout != in_new->term_timeout) 982 return true; 983 984 if (string_changed(in->seccomp, in_new->seccomp)) 985 return true; 986 987 if (string_changed(in->capabilities, in_new->capabilities)) 988 return true; 989 990 if (!blobmsg_list_equal(&in->limits, &in_new->limits)) 991 return true; 992 993 if (!blobmsg_list_equal(&in->jail.mount, &in_new->jail.mount)) 994 return true; 995 996 if (!blobmsg_list_equal(&in->jail.setns, &in_new->jail.setns)) 997 return true; 998 999 if (!blobmsg_list_equal(&in->errors, &in_new->errors)) 1000 return true; 1001 1002 if (in->has_jail != in_new->has_jail) 1003 return true; 1004 1005 if (in->trace != in_new->trace) 1006 return true; 1007 1008 if (in->require_jail != in_new->require_jail) 1009 return true; 1010 1011 if (in->immediately != in_new->immediately) 1012 return true; 1013 1014 if (in->no_new_privs != in_new->no_new_privs) 1015 return true; 1016 1017 if (string_changed(in->jail.name, in_new->jail.name)) 1018 return true; 1019 1020 if (string_changed(in->jail.hostname, in_new->jail.hostname)) 1021 return true; 1022 1023 if (string_changed(in->jail.pidfile, in_new->jail.pidfile)) 1024 return true; 1025 1026 if (in->jail.procfs != in_new->jail.procfs) 1027 return true; 1028 1029 if (in->jail.sysfs != in_new->jail.sysfs) 1030 return true; 1031 1032 if (in->jail.ubus != in_new->jail.ubus) 1033 return true; 1034 1035 if (in->jail.log != in_new->jail.log) 1036 return true; 1037 1038 if (in->jail.ronly != in_new->jail.ronly) 1039 return true; 1040 1041 if (in->jail.netns != in_new->jail.netns) 1042 return true; 1043 1044 if (in->jail.userns != in_new->jail.userns) 1045 return true; 1046 1047 if (in->jail.cgroupsns != in_new->jail.cgroupsns) 1048 return true; 1049 1050 if (in->jail.console != in_new->jail.console) 1051 return true; 1052 1053 if (in->watchdog.mode != in_new->watchdog.mode) 1054 return true; 1055 1056 if (in->watchdog.freq != in_new->watchdog.freq) 1057 return true; 1058 1059 return false; 1060 } 1061 1062 static bool 1063 instance_netdev_cmp(struct blobmsg_list_node *l1, struct blobmsg_list_node *l2) 1064 { 1065 struct instance_netdev *n1 = container_of(l1, struct instance_netdev, node); 1066 struct instance_netdev *n2 = container_of(l2, struct instance_netdev, node); 1067 1068 return n1->ifindex == n2->ifindex; 1069 } 1070 1071 static void 1072 instance_netdev_update(struct blobmsg_list_node *l) 1073 { 1074 struct instance_netdev *n = container_of(l, struct instance_netdev, node); 1075 1076 n->ifindex = if_nametoindex(n->node.avl.key); 1077 } 1078 1079 static bool 1080 instance_file_cmp(struct blobmsg_list_node *l1, struct blobmsg_list_node *l2) 1081 { 1082 struct instance_file *f1 = container_of(l1, struct instance_file, node); 1083 struct instance_file *f2 = container_of(l2, struct instance_file, node); 1084 1085 return !memcmp(f1->md5, f2->md5, sizeof(f1->md5)); 1086 } 1087 1088 static void 1089 instance_file_update(struct blobmsg_list_node *l) 1090 { 1091 struct instance_file *f = container_of(l, struct instance_file, node); 1092 md5_ctx_t md5; 1093 char buf[256]; 1094 int len, fd; 1095 1096 memset(f->md5, 0, sizeof(f->md5)); 1097 1098 fd = open(l->avl.key, O_RDONLY); 1099 if (fd < 0) 1100 return; 1101 1102 md5_begin(&md5); 1103 do { 1104 len = read(fd, buf, sizeof(buf)); 1105 if (len < 0) { 1106 if (errno == EINTR) 1107 continue; 1108 1109 break; 1110 } 1111 if (!len) 1112 break; 1113 1114 md5_hash(buf, len, &md5); 1115 } while(1); 1116 1117 md5_end(f->md5, &md5); 1118 close(fd); 1119 } 1120 1121 static void 1122 instance_fill_any(struct blobmsg_list *l, struct blob_attr *cur) 1123 { 1124 if (!cur) 1125 return; 1126 1127 blobmsg_list_fill(l, blobmsg_data(cur), blobmsg_data_len(cur), false); 1128 } 1129 1130 static bool 1131 instance_fill_array(struct blobmsg_list *l, struct blob_attr *cur, blobmsg_update_cb cb, bool array) 1132 { 1133 struct blobmsg_list_node *node; 1134 1135 if (!cur) 1136 return true; 1137 1138 if (!blobmsg_check_attr_list(cur, BLOBMSG_TYPE_STRING)) 1139 return false; 1140 1141 blobmsg_list_fill(l, blobmsg_data(cur), blobmsg_data_len(cur), array); 1142 if (cb) { 1143 blobmsg_list_for_each(l, node) 1144 cb(node); 1145 } 1146 return true; 1147 } 1148 1149 static int 1150 instance_jail_parse(struct service_instance *in, struct blob_attr *attr) 1151 { 1152 struct blob_attr *tb[__JAIL_ATTR_MAX]; 1153 struct jail *jail = &in->jail; 1154 struct blobmsg_list_node *var; 1155 1156 blobmsg_parse(jail_attr, __JAIL_ATTR_MAX, tb, 1157 blobmsg_data(attr), blobmsg_data_len(attr)); 1158 1159 jail->argc = 4; 1160 1161 if (tb[JAIL_ATTR_REQUIREJAIL] && blobmsg_get_bool(tb[JAIL_ATTR_REQUIREJAIL])) { 1162 in->require_jail = true; 1163 jail->argc++; 1164 } 1165 if (tb[JAIL_ATTR_IMMEDIATELY] && blobmsg_get_bool(tb[JAIL_ATTR_IMMEDIATELY])) { 1166 in->immediately = true; 1167 jail->argc++; 1168 } 1169 if (tb[JAIL_ATTR_NAME]) { 1170 jail->name = strdup(blobmsg_get_string(tb[JAIL_ATTR_NAME])); 1171 jail->argc += 2; 1172 } 1173 if (tb[JAIL_ATTR_HOSTNAME]) { 1174 jail->hostname = strdup(blobmsg_get_string(tb[JAIL_ATTR_HOSTNAME])); 1175 jail->argc += 2; 1176 } 1177 if (tb[JAIL_ATTR_PROCFS] && blobmsg_get_bool(tb[JAIL_ATTR_PROCFS])) { 1178 jail->procfs = true; 1179 jail->argc++; 1180 } 1181 if (tb[JAIL_ATTR_SYSFS] && blobmsg_get_bool(tb[JAIL_ATTR_SYSFS])) { 1182 jail->sysfs = true; 1183 jail->argc++; 1184 } 1185 if (tb[JAIL_ATTR_UBUS] && blobmsg_get_bool(tb[JAIL_ATTR_UBUS])) { 1186 jail->ubus = true; 1187 jail->argc++; 1188 } 1189 if (tb[JAIL_ATTR_LOG] && blobmsg_get_bool(tb[JAIL_ATTR_LOG])) { 1190 jail->log = true; 1191 jail->argc++; 1192 } 1193 if (tb[JAIL_ATTR_RONLY] && blobmsg_get_bool(tb[JAIL_ATTR_RONLY])) { 1194 jail->ronly = true; 1195 jail->argc++; 1196 } 1197 if (tb[JAIL_ATTR_NETNS] && blobmsg_get_bool(tb[JAIL_ATTR_NETNS])) { 1198 jail->netns = true; 1199 jail->argc++; 1200 } 1201 if (tb[JAIL_ATTR_USERNS] && blobmsg_get_bool(tb[JAIL_ATTR_USERNS])) { 1202 jail->userns = true; 1203 jail->argc++; 1204 } 1205 if (tb[JAIL_ATTR_CGROUPSNS] && blobmsg_get_bool(tb[JAIL_ATTR_CGROUPSNS])) { 1206 jail->cgroupsns = true; 1207 jail->argc++; 1208 } 1209 if (tb[JAIL_ATTR_CONSOLE] && blobmsg_get_bool(tb[JAIL_ATTR_CONSOLE])) { 1210 jail->console = true; 1211 jail->argc++; 1212 } 1213 if (tb[JAIL_ATTR_PIDFILE]) { 1214 jail->pidfile = strdup(blobmsg_get_string(tb[JAIL_ATTR_PIDFILE])); 1215 jail->argc += 2; 1216 } 1217 1218 if (tb[JAIL_ATTR_SETNS]) { 1219 struct blob_attr *cur; 1220 int rem; 1221 1222 blobmsg_for_each_attr(cur, tb[JAIL_ATTR_SETNS], rem) 1223 jail->argc += 2; 1224 blobmsg_list_fill(&jail->setns, blobmsg_data(tb[JAIL_ATTR_SETNS]), 1225 blobmsg_data_len(tb[JAIL_ATTR_SETNS]), true); 1226 } 1227 1228 if (tb[JAIL_ATTR_MOUNT]) { 1229 struct blob_attr *cur; 1230 int rem; 1231 1232 blobmsg_for_each_attr(cur, tb[JAIL_ATTR_MOUNT], rem) 1233 jail->argc += 2; 1234 instance_fill_array(&jail->mount, tb[JAIL_ATTR_MOUNT], NULL, false); 1235 } 1236 1237 blobmsg_list_for_each(&in->env, var) 1238 jail->argc += 2; 1239 1240 if (in->seccomp) 1241 jail->argc += 2; 1242 1243 if (in->capabilities) 1244 jail->argc += 2; 1245 1246 if (in->user) 1247 jail->argc += 2; 1248 1249 if (in->group) 1250 jail->argc += 2; 1251 1252 if (in->extroot) 1253 jail->argc += 2; 1254 1255 if (in->overlaydir) 1256 jail->argc += 2; 1257 1258 if (in->tmpoverlaysize) 1259 jail->argc += 2; 1260 1261 if (in->no_new_privs) 1262 jail->argc++; 1263 1264 if (in->bundle) 1265 jail->argc += 2; 1266 1267 return true; 1268 } 1269 1270 static bool 1271 instance_config_parse_command(struct service_instance *in, struct blob_attr **tb) 1272 { 1273 struct blob_attr *cur, *cur2; 1274 bool ret = false; 1275 int rem; 1276 1277 cur = tb[INSTANCE_ATTR_COMMAND]; 1278 if (!cur) { 1279 in->command = NULL; 1280 return true; 1281 } 1282 1283 if (!blobmsg_check_attr_list(cur, BLOBMSG_TYPE_STRING)) 1284 return false; 1285 1286 blobmsg_for_each_attr(cur2, cur, rem) { 1287 ret = true; 1288 break; 1289 } 1290 1291 in->command = cur; 1292 return ret; 1293 } 1294 1295 static bool 1296 instance_config_parse(struct service_instance *in) 1297 { 1298 struct blob_attr *tb[__INSTANCE_ATTR_MAX]; 1299 struct blob_attr *cur, *cur2; 1300 struct stat s; 1301 int rem, r; 1302 1303 blobmsg_parse(instance_attr, __INSTANCE_ATTR_MAX, tb, 1304 blobmsg_data(in->config), blobmsg_data_len(in->config)); 1305 1306 if (!tb[INSTANCE_ATTR_BUNDLE] && !instance_config_parse_command(in, tb)) 1307 return false; 1308 1309 if (tb[INSTANCE_ATTR_TERMTIMEOUT]) 1310 in->term_timeout = blobmsg_get_u32(tb[INSTANCE_ATTR_TERMTIMEOUT]); 1311 if (tb[INSTANCE_ATTR_RESPAWN]) { 1312 int i = 0; 1313 uint32_t vals[3] = { 3600, 5, 5}; 1314 1315 blobmsg_for_each_attr(cur2, tb[INSTANCE_ATTR_RESPAWN], rem) { 1316 if ((i >= 3) && (blobmsg_type(cur2) == BLOBMSG_TYPE_STRING)) 1317 continue; 1318 vals[i] = atoi(blobmsg_get_string(cur2)); 1319 i++; 1320 } 1321 in->respawn = true; 1322 in->respawn_count = 0; 1323 in->respawn_threshold = vals[0]; 1324 in->respawn_timeout = vals[1]; 1325 in->respawn_retry = vals[2]; 1326 } 1327 if (tb[INSTANCE_ATTR_TRIGGER]) { 1328 in->trigger = tb[INSTANCE_ATTR_TRIGGER]; 1329 trigger_add(in->trigger, in); 1330 } 1331 1332 if (tb[INSTANCE_ATTR_WATCH]) { 1333 blobmsg_for_each_attr(cur2, tb[INSTANCE_ATTR_WATCH], rem) { 1334 if (blobmsg_type(cur2) != BLOBMSG_TYPE_STRING) 1335 continue; 1336 P_DEBUG(3, "watch for %s\n", blobmsg_get_string(cur2)); 1337 watch_add(blobmsg_get_string(cur2), in); 1338 } 1339 } 1340 1341 if ((cur = tb[INSTANCE_ATTR_NICE])) { 1342 in->nice = (int8_t) blobmsg_get_u32(cur); 1343 if (in->nice < -20 || in->nice > 20) 1344 return false; 1345 } 1346 1347 if (tb[INSTANCE_ATTR_USER]) { 1348 const char *user = blobmsg_get_string(tb[INSTANCE_ATTR_USER]); 1349 struct passwd *p = getpwnam(user); 1350 if (p) { 1351 in->user = strdup(user); 1352 in->uid = p->pw_uid; 1353 in->gr_gid = in->pw_gid = p->pw_gid; 1354 } 1355 } 1356 1357 if (tb[INSTANCE_ATTR_GROUP]) { 1358 const char *group = blobmsg_get_string(tb[INSTANCE_ATTR_GROUP]); 1359 struct group *p = getgrnam(group); 1360 if (p) { 1361 in->group = strdup(group); 1362 in->gr_gid = p->gr_gid; 1363 } 1364 } 1365 1366 if (tb[INSTANCE_ATTR_TRACE]) 1367 in->trace = blobmsg_get_bool(tb[INSTANCE_ATTR_TRACE]); 1368 1369 if (tb[INSTANCE_ATTR_NO_NEW_PRIVS]) 1370 in->no_new_privs = blobmsg_get_bool(tb[INSTANCE_ATTR_NO_NEW_PRIVS]); 1371 1372 if (!in->trace && tb[INSTANCE_ATTR_SECCOMP]) 1373 in->seccomp = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_SECCOMP])); 1374 1375 if (tb[INSTANCE_ATTR_CAPABILITIES]) 1376 in->capabilities = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_CAPABILITIES])); 1377 1378 if (tb[INSTANCE_ATTR_EXTROOT]) 1379 in->extroot = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_EXTROOT])); 1380 1381 if (tb[INSTANCE_ATTR_OVERLAYDIR]) 1382 in->overlaydir = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_OVERLAYDIR])); 1383 1384 if (tb[INSTANCE_ATTR_TMPOVERLAYSIZE]) 1385 in->tmpoverlaysize = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_TMPOVERLAYSIZE])); 1386 1387 if (tb[INSTANCE_ATTR_BUNDLE]) 1388 in->bundle = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_BUNDLE])); 1389 1390 if (tb[INSTANCE_ATTR_PIDFILE]) { 1391 char *pidfile = blobmsg_get_string(tb[INSTANCE_ATTR_PIDFILE]); 1392 if (pidfile) 1393 in->pidfile = strdup(pidfile); 1394 } 1395 1396 if (tb[INSTANCE_ATTR_RELOADSIG]) 1397 in->reload_signal = blobmsg_get_u32(tb[INSTANCE_ATTR_RELOADSIG]); 1398 1399 if (tb[INSTANCE_ATTR_STDOUT] && blobmsg_get_bool(tb[INSTANCE_ATTR_STDOUT])) 1400 in->_stdout.fd.fd = -1; 1401 1402 if (tb[INSTANCE_ATTR_STDERR] && blobmsg_get_bool(tb[INSTANCE_ATTR_STDERR])) 1403 in->_stderr.fd.fd = -1; 1404 1405 instance_fill_any(&in->data, tb[INSTANCE_ATTR_DATA]); 1406 1407 if (!instance_fill_array(&in->env, tb[INSTANCE_ATTR_ENV], NULL, false)) 1408 return false; 1409 1410 if (!instance_fill_array(&in->netdev, tb[INSTANCE_ATTR_NETDEV], instance_netdev_update, true)) 1411 return false; 1412 1413 if (!instance_fill_array(&in->file, tb[INSTANCE_ATTR_FILE], instance_file_update, true)) 1414 return false; 1415 1416 if (!instance_fill_array(&in->limits, tb[INSTANCE_ATTR_LIMITS], NULL, false)) 1417 return false; 1418 1419 if (!instance_fill_array(&in->errors, tb[INSTANCE_ATTR_ERROR], NULL, true)) 1420 return false; 1421 1422 if (tb[INSTANCE_ATTR_FACILITY]) { 1423 int facility = syslog_facility_str_to_int(blobmsg_get_string(tb[INSTANCE_ATTR_FACILITY])); 1424 if (facility != -1) { 1425 in->syslog_facility = facility; 1426 P_DEBUG(3, "setting facility '%s'\n", blobmsg_get_string(tb[INSTANCE_ATTR_FACILITY])); 1427 } else 1428 P_DEBUG(3, "unknown syslog facility '%s' given, using default (LOG_DAEMON)\n", blobmsg_get_string(tb[INSTANCE_ATTR_FACILITY])); 1429 } 1430 1431 if (tb[INSTANCE_ATTR_WATCHDOG]) { 1432 int i = 0; 1433 uint32_t vals[2] = { 0, 30 }; 1434 1435 blobmsg_for_each_attr(cur2, tb[INSTANCE_ATTR_WATCHDOG], rem) { 1436 if (i >= 2) 1437 break; 1438 1439 vals[i] = atoi(blobmsg_get_string(cur2)); 1440 i++; 1441 } 1442 1443 if (vals[0] >= 0 && vals[0] < __INSTANCE_WATCHDOG_MODE_MAX) { 1444 in->watchdog.mode = vals[0]; 1445 P_DEBUG(3, "setting watchdog mode (%d)\n", vals[0]); 1446 } else { 1447 in->watchdog.mode = 0; 1448 P_DEBUG(3, "unknown watchdog mode (%d) given, using default (0)\n", vals[0]); 1449 } 1450 1451 if (vals[1] > 0) { 1452 in->watchdog.freq = vals[1]; 1453 P_DEBUG(3, "setting watchdog timeout (%d)\n", vals[0]); 1454 } else { 1455 in->watchdog.freq = 30; 1456 P_DEBUG(3, "invalid watchdog timeout (%d) given, using default (30)\n", vals[1]); 1457 } 1458 } 1459 1460 if (!in->trace && tb[INSTANCE_ATTR_JAIL]) 1461 in->has_jail = instance_jail_parse(in, tb[INSTANCE_ATTR_JAIL]); 1462 1463 if (in->has_jail) { 1464 r = stat(UJAIL_BIN_PATH, &s); 1465 if (r < 0) { 1466 if (in->require_jail) { 1467 ERROR("Cannot jail service %s::%s. %s: %m (%d)\n", 1468 in->srv->name, in->name, UJAIL_BIN_PATH, r); 1469 return false; 1470 } 1471 P_DEBUG(2, "unable to find %s: %m (%d)\n", UJAIL_BIN_PATH, r); 1472 in->has_jail = false; 1473 } 1474 } 1475 1476 return true; 1477 } 1478 1479 static void 1480 instance_config_cleanup(struct service_instance *in) 1481 { 1482 blobmsg_list_free(&in->env); 1483 blobmsg_list_free(&in->data); 1484 blobmsg_list_free(&in->netdev); 1485 blobmsg_list_free(&in->file); 1486 blobmsg_list_free(&in->limits); 1487 blobmsg_list_free(&in->errors); 1488 blobmsg_list_free(&in->jail.mount); 1489 blobmsg_list_free(&in->jail.setns); 1490 } 1491 1492 static void 1493 instance_config_move_strdup(char **dst, char *src) 1494 { 1495 if (*dst) { 1496 free(*dst); 1497 *dst = NULL; 1498 } 1499 1500 if (!src) 1501 return; 1502 1503 *dst = strdup(src); 1504 } 1505 1506 static void 1507 instance_config_move(struct service_instance *in, struct service_instance *in_src) 1508 { 1509 instance_config_cleanup(in); 1510 blobmsg_list_move(&in->env, &in_src->env); 1511 blobmsg_list_move(&in->data, &in_src->data); 1512 blobmsg_list_move(&in->netdev, &in_src->netdev); 1513 blobmsg_list_move(&in->file, &in_src->file); 1514 blobmsg_list_move(&in->limits, &in_src->limits); 1515 blobmsg_list_move(&in->errors, &in_src->errors); 1516 blobmsg_list_move(&in->jail.mount, &in_src->jail.mount); 1517 blobmsg_list_move(&in->jail.setns, &in_src->jail.setns); 1518 in->trigger = in_src->trigger; 1519 in->command = in_src->command; 1520 in->respawn = in_src->respawn; 1521 in->respawn_retry = in_src->respawn_retry; 1522 in->respawn_threshold = in_src->respawn_threshold; 1523 in->respawn_timeout = in_src->respawn_timeout; 1524 in->reload_signal = in_src->reload_signal; 1525 in->term_timeout = in_src->term_timeout; 1526 in->watchdog.mode = in_src->watchdog.mode; 1527 in->watchdog.freq = in_src->watchdog.freq; 1528 in->watchdog.timeout = in_src->watchdog.timeout; 1529 in->name = in_src->name; 1530 in->nice = in_src->nice; 1531 in->trace = in_src->trace; 1532 in->node.avl.key = in_src->node.avl.key; 1533 in->syslog_facility = in_src->syslog_facility; 1534 in->require_jail = in_src->require_jail; 1535 in->no_new_privs = in_src->no_new_privs; 1536 in->immediately = in_src->immediately; 1537 in->uid = in_src->uid; 1538 in->pw_gid = in_src->pw_gid; 1539 in->gr_gid = in_src->gr_gid; 1540 1541 in->has_jail = in_src->has_jail; 1542 in->jail.procfs = in_src->jail.procfs; 1543 in->jail.sysfs = in_src->jail.sysfs; 1544 in->jail.ubus = in_src->jail.ubus; 1545 in->jail.log = in_src->jail.log; 1546 in->jail.ronly = in_src->jail.ronly; 1547 in->jail.netns = in_src->jail.netns; 1548 in->jail.cgroupsns = in_src->jail.cgroupsns; 1549 in->jail.console = in_src->jail.console; 1550 in->jail.argc = in_src->jail.argc; 1551 1552 instance_config_move_strdup(&in->pidfile, in_src->pidfile); 1553 instance_config_move_strdup(&in->seccomp, in_src->seccomp); 1554 instance_config_move_strdup(&in->capabilities, in_src->capabilities); 1555 instance_config_move_strdup(&in->bundle, in_src->bundle); 1556 instance_config_move_strdup(&in->extroot, in_src->extroot); 1557 instance_config_move_strdup(&in->overlaydir, in_src->overlaydir); 1558 instance_config_move_strdup(&in->tmpoverlaysize, in_src->tmpoverlaysize); 1559 instance_config_move_strdup(&in->user, in_src->user); 1560 instance_config_move_strdup(&in->group, in_src->group); 1561 instance_config_move_strdup(&in->jail.name, in_src->jail.name); 1562 instance_config_move_strdup(&in->jail.hostname, in_src->jail.hostname); 1563 instance_config_move_strdup(&in->jail.pidfile, in_src->jail.pidfile); 1564 1565 free(in->config); 1566 in->config = in_src->config; 1567 in_src->config = NULL; 1568 } 1569 1570 void 1571 instance_update(struct service_instance *in, struct service_instance *in_new) 1572 { 1573 bool changed = instance_config_changed(in, in_new); 1574 bool running = in->proc.pending; 1575 bool stopping = in->halt; 1576 1577 if (!running || stopping) { 1578 instance_config_move(in, in_new); 1579 instance_start(in); 1580 } else { 1581 if (changed) 1582 instance_restart(in); 1583 instance_config_move(in, in_new); 1584 /* restart happens in the child callback handler */ 1585 } 1586 } 1587 1588 void 1589 instance_free(struct service_instance *in) 1590 { 1591 instance_free_stdio(in); 1592 uloop_process_delete(&in->proc); 1593 uloop_timeout_cancel(&in->timeout); 1594 uloop_timeout_cancel(&in->watchdog.timeout); 1595 trigger_del(in); 1596 watch_del(in); 1597 instance_config_cleanup(in); 1598 free(in->config); 1599 free(in->user); 1600 free(in->group); 1601 free(in->extroot); 1602 free(in->overlaydir); 1603 free(in->tmpoverlaysize); 1604 free(in->bundle); 1605 free(in->jail.name); 1606 free(in->jail.hostname); 1607 free(in->jail.pidfile); 1608 free(in->seccomp); 1609 free(in->capabilities); 1610 free(in->pidfile); 1611 free(in); 1612 } 1613 1614 void 1615 instance_init(struct service_instance *in, struct service *s, struct blob_attr *config) 1616 { 1617 config = blob_memdup(config); 1618 in->srv = s; 1619 in->name = blobmsg_name(config); 1620 in->config = config; 1621 in->timeout.cb = instance_timeout; 1622 in->proc.cb = instance_exit; 1623 in->term_timeout = 5; 1624 in->syslog_facility = LOG_DAEMON; 1625 in->exit_code = 0; 1626 in->require_jail = false; 1627 in->immediately = false; 1628 1629 in->_stdout.fd.fd = -2; 1630 in->_stdout.stream.string_data = true; 1631 in->_stdout.stream.notify_read = instance_stdout; 1632 1633 in->_stderr.fd.fd = -2; 1634 in->_stderr.stream.string_data = true; 1635 in->_stderr.stream.notify_read = instance_stderr; 1636 1637 in->console.fd.fd = -2; 1638 in->console.stream.string_data = true; 1639 in->console.stream.notify_read = instance_console; 1640 1641 in->console_client.fd.fd = -2; 1642 in->console_client.stream.string_data = true; 1643 in->console_client.stream.notify_read = instance_console_client; 1644 1645 blobmsg_list_init(&in->netdev, struct instance_netdev, node, instance_netdev_cmp); 1646 blobmsg_list_init(&in->file, struct instance_file, node, instance_file_cmp); 1647 blobmsg_list_simple_init(&in->env); 1648 blobmsg_list_simple_init(&in->data); 1649 blobmsg_list_simple_init(&in->limits); 1650 blobmsg_list_simple_init(&in->errors); 1651 blobmsg_list_simple_init(&in->jail.mount); 1652 blobmsg_list_simple_init(&in->jail.setns); 1653 1654 in->watchdog.timeout.cb = instance_watchdog; 1655 1656 in->valid = instance_config_parse(in); 1657 } 1658 1659 void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose) 1660 { 1661 void *i; 1662 1663 if (!in->valid) 1664 return; 1665 1666 i = blobmsg_open_table(b, in->name); 1667 blobmsg_add_u8(b, "running", in->proc.pending); 1668 if (in->proc.pending) 1669 blobmsg_add_u32(b, "pid", in->proc.pid); 1670 if (in->command) 1671 blobmsg_add_blob(b, in->command); 1672 if (in->bundle) 1673 blobmsg_add_string(b, "bundle", in->bundle); 1674 blobmsg_add_u32(b, "term_timeout", in->term_timeout); 1675 if (!in->proc.pending) 1676 blobmsg_add_u32(b, "exit_code", in->exit_code); 1677 1678 if (!avl_is_empty(&in->errors.avl)) { 1679 struct blobmsg_list_node *var; 1680 void *e = blobmsg_open_array(b, "errors"); 1681 blobmsg_list_for_each(&in->errors, var) 1682 blobmsg_add_string(b, NULL, blobmsg_data(var->data)); 1683 blobmsg_close_table(b, e); 1684 } 1685 1686 if (!avl_is_empty(&in->env.avl)) { 1687 struct blobmsg_list_node *var; 1688 void *e = blobmsg_open_table(b, "env"); 1689 blobmsg_list_for_each(&in->env, var) 1690 blobmsg_add_string(b, blobmsg_name(var->data), blobmsg_data(var->data)); 1691 blobmsg_close_table(b, e); 1692 } 1693 1694 if (!avl_is_empty(&in->data.avl)) { 1695 struct blobmsg_list_node *var; 1696 void *e = blobmsg_open_table(b, "data"); 1697 blobmsg_list_for_each(&in->data, var) 1698 blobmsg_add_blob(b, var->data); 1699 blobmsg_close_table(b, e); 1700 } 1701 1702 if (!avl_is_empty(&in->limits.avl)) { 1703 struct blobmsg_list_node *var; 1704 void *e = blobmsg_open_table(b, "limits"); 1705 blobmsg_list_for_each(&in->limits, var) 1706 blobmsg_add_string(b, blobmsg_name(var->data), blobmsg_data(var->data)); 1707 blobmsg_close_table(b, e); 1708 } 1709 1710 if (!avl_is_empty(&in->netdev.avl)) { 1711 struct blobmsg_list_node *var; 1712 void *n = blobmsg_open_array(b, "netdev"); 1713 1714 blobmsg_list_for_each(&in->netdev, var) 1715 blobmsg_add_string(b, NULL, blobmsg_data(var->data)); 1716 blobmsg_close_array(b, n); 1717 } 1718 1719 if (in->reload_signal) 1720 blobmsg_add_u32(b, "reload_signal", in->reload_signal); 1721 1722 if (in->respawn) { 1723 void *r = blobmsg_open_table(b, "respawn"); 1724 blobmsg_add_u32(b, "threshold", in->respawn_threshold); 1725 blobmsg_add_u32(b, "timeout", in->respawn_timeout); 1726 blobmsg_add_u32(b, "retry", in->respawn_retry); 1727 blobmsg_close_table(b, r); 1728 } 1729 1730 if (in->trace) 1731 blobmsg_add_u8(b, "trace", true); 1732 1733 if (in->no_new_privs) 1734 blobmsg_add_u8(b, "no_new_privs", true); 1735 1736 if (in->seccomp) 1737 blobmsg_add_string(b, "seccomp", in->seccomp); 1738 1739 if (in->capabilities) 1740 blobmsg_add_string(b, "capabilities", in->capabilities); 1741 1742 if (in->pidfile) 1743 blobmsg_add_string(b, "pidfile", in->pidfile); 1744 1745 if (in->user) 1746 blobmsg_add_string(b, "user", in->user); 1747 1748 if (in->group) 1749 blobmsg_add_string(b, "group", in->group); 1750 1751 if (in->has_jail) { 1752 void *r = blobmsg_open_table(b, "jail"); 1753 if (in->jail.name) 1754 blobmsg_add_string(b, "name", in->jail.name); 1755 if (!in->bundle) { 1756 if (in->jail.hostname) 1757 blobmsg_add_string(b, "hostname", in->jail.hostname); 1758 1759 blobmsg_add_u8(b, "procfs", in->jail.procfs); 1760 blobmsg_add_u8(b, "sysfs", in->jail.sysfs); 1761 blobmsg_add_u8(b, "ubus", in->jail.ubus); 1762 blobmsg_add_u8(b, "log", in->jail.log); 1763 blobmsg_add_u8(b, "ronly", in->jail.ronly); 1764 blobmsg_add_u8(b, "netns", in->jail.netns); 1765 blobmsg_add_u8(b, "userns", in->jail.userns); 1766 blobmsg_add_u8(b, "cgroupsns", in->jail.cgroupsns); 1767 } else { 1768 if (in->jail.pidfile) 1769 blobmsg_add_string(b, "pidfile", in->jail.pidfile); 1770 1771 blobmsg_add_u8(b, "immediately", in->immediately); 1772 } 1773 blobmsg_add_u8(b, "console", (in->console.fd.fd > -1)); 1774 blobmsg_close_table(b, r); 1775 if (!avl_is_empty(&in->jail.mount.avl)) { 1776 struct blobmsg_list_node *var; 1777 void *e = blobmsg_open_table(b, "mount"); 1778 blobmsg_list_for_each(&in->jail.mount, var) 1779 blobmsg_add_string(b, blobmsg_name(var->data), blobmsg_data(var->data)); 1780 blobmsg_close_table(b, e); 1781 } 1782 1783 if (!avl_is_empty(&in->jail.setns.avl)) { 1784 struct blobmsg_list_node *var; 1785 void *s = blobmsg_open_array(b, "setns"); 1786 blobmsg_list_for_each(&in->jail.setns, var) 1787 blobmsg_add_blob(b, var->data); 1788 blobmsg_close_array(b, s); 1789 } 1790 } 1791 1792 if (in->extroot) 1793 blobmsg_add_string(b, "extroot", in->extroot); 1794 if (in->overlaydir) 1795 blobmsg_add_string(b, "overlaydir", in->overlaydir); 1796 if (in->tmpoverlaysize) 1797 blobmsg_add_string(b, "tmpoverlaysize", in->tmpoverlaysize); 1798 1799 if (verbose && in->trigger) 1800 blobmsg_add_blob(b, in->trigger); 1801 1802 if (in->watchdog.mode != INSTANCE_WATCHDOG_MODE_DISABLED) { 1803 void *r = blobmsg_open_table(b, "watchdog"); 1804 blobmsg_add_u32(b, "mode", in->watchdog.mode); 1805 blobmsg_add_u32(b, "timeout", in->watchdog.freq); 1806 blobmsg_close_table(b, r); 1807 } 1808 1809 blobmsg_close_table(b, i); 1810 } 1811
This page was automatically generated by LXR 0.3.1. • OpenWrt