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 #include <sys/types.h> 16 #include <sys/socket.h> 17 #include <sys/stat.h> 18 #include <sys/utsname.h> 19 #include <sys/types.h> 20 #include <fcntl.h> 21 22 #include <unistd.h> 23 24 #include <libubox/blobmsg_json.h> 25 #include <libubox/avl-cmp.h> 26 27 #include "../procd.h" 28 29 #include "service.h" 30 #include "instance.h" 31 32 #include "../rcS.h" 33 #include "../stdio-fds.h" 34 35 AVL_TREE(services, avl_strcmp, false, NULL); 36 AVL_TREE(containers, avl_strcmp, false, NULL); 37 static struct blob_buf b; 38 static struct ubus_context *ctx; 39 static struct ubus_object main_object; 40 41 static void 42 service_instance_add(struct service *s, struct blob_attr *attr, int *stdio_fds, 43 int *notify_fd) 44 { 45 struct service_instance *in; 46 47 if (blobmsg_type(attr) != BLOBMSG_TYPE_TABLE) 48 return; 49 50 in = calloc(1, sizeof(*in)); 51 if (!in) 52 return; 53 54 instance_init(in, s, attr); 55 if (stdio_fds && stdio_fds[1] > -1) 56 instance_stdio_set(in, stdio_fds); 57 58 if (notify_fd && *notify_fd > -1) 59 instance_notify_set(in, notify_fd); 60 61 vlist_add(&s->instances, &in->node, (void *) in->name); 62 } 63 64 void service_data_trigger(struct blobmsg_list *list) 65 { 66 struct blobmsg_list_node *node; 67 68 avl_for_each_element(&list->avl, node, avl) { 69 blob_buf_init(&b, 0); 70 blobmsg_add_string(&b, "name", blobmsg_name(node->data)); 71 trigger_event("service.data.update", b.head); 72 } 73 } 74 75 static void 76 service_instance_update(struct vlist_tree *tree, struct vlist_node *node_new, 77 struct vlist_node *node_old) 78 { 79 struct service_instance *in_o = NULL, *in_n = NULL; 80 81 if (node_old) 82 in_o = container_of(node_old, struct service_instance, node); 83 84 if (node_new) 85 in_n = container_of(node_new, struct service_instance, node); 86 87 if (in_o && in_n) { 88 P_DEBUG(2, "Update instance %s::%s\n", in_o->srv->name, in_o->name); 89 instance_update(in_o, in_n); 90 instance_free(in_n); 91 } else if (in_o) { 92 P_DEBUG(2, "Stop instance %s::%s\n", in_o->srv->name, in_o->name); 93 instance_stop(in_o, true); 94 } else if (in_n && in_n->srv->autostart) { 95 P_DEBUG(2, "Start instance %s::%s\n", in_n->srv->name, in_n->name); 96 instance_start(in_n); 97 } 98 blob_buf_init(&b, 0); 99 trigger_event("instance.update", b.head); 100 } 101 102 static struct service * 103 service_alloc(const char *name) 104 { 105 struct service *s; 106 char *new_name; 107 108 s = calloc_a(sizeof(*s), &new_name, strlen(name) + 1); 109 strcpy(new_name, name); 110 111 vlist_init(&s->instances, avl_strcmp, service_instance_update); 112 s->instances.no_delete = true; 113 s->name = new_name; 114 s->avl.key = s->name; 115 INIT_LIST_HEAD(&s->validators); 116 blobmsg_list_simple_init(&s->data_blob); 117 118 return s; 119 } 120 121 enum { 122 SERVICE_SET_NAME, 123 SERVICE_SET_SCRIPT, 124 SERVICE_SET_INSTANCES, 125 SERVICE_SET_TRIGGER, 126 SERVICE_SET_VALIDATE, 127 SERVICE_SET_AUTOSTART, 128 SERVICE_SET_DATA, 129 __SERVICE_SET_MAX 130 }; 131 132 static const struct blobmsg_policy service_set_attrs[__SERVICE_SET_MAX] = { 133 [SERVICE_SET_NAME] = { "name", BLOBMSG_TYPE_STRING }, 134 [SERVICE_SET_SCRIPT] = { "script", BLOBMSG_TYPE_STRING }, 135 [SERVICE_SET_INSTANCES] = { "instances", BLOBMSG_TYPE_TABLE }, 136 [SERVICE_SET_TRIGGER] = { "triggers", BLOBMSG_TYPE_ARRAY }, 137 [SERVICE_SET_VALIDATE] = { "validate", BLOBMSG_TYPE_ARRAY }, 138 [SERVICE_SET_AUTOSTART] = { "autostart", BLOBMSG_TYPE_BOOL }, 139 [SERVICE_SET_DATA] = { "data", BLOBMSG_TYPE_TABLE }, 140 }; 141 142 static int 143 service_update_data(struct service *s, struct blob_attr *data) 144 { 145 if (blob_attr_equal(s->data, data)) 146 return 0; 147 148 service_data_trigger(&s->data_blob); 149 blobmsg_list_free(&s->data_blob); 150 151 free(s->data); 152 s->data = blob_memdup(data); 153 if (!s->data) 154 return -1; 155 156 blobmsg_list_fill(&s->data_blob, blobmsg_data(s->data), 157 blobmsg_data_len(s->data), false); 158 service_data_trigger(&s->data_blob); 159 160 return 0; 161 } 162 163 static int 164 service_update(struct service *s, struct blob_attr **tb, bool add, bool init, 165 int *stdio_fds, int *notify_fd) 166 { 167 struct blob_attr *cur; 168 int rem; 169 170 if (tb[SERVICE_SET_AUTOSTART]) 171 s->autostart = blobmsg_get_bool(tb[SERVICE_SET_AUTOSTART]); 172 else if (init) 173 s->autostart = true; 174 175 if (tb[SERVICE_SET_TRIGGER]) { 176 free(s->trigger); 177 s->trigger = blob_memdup(tb[SERVICE_SET_TRIGGER]); 178 if (!s->trigger) 179 return -1; 180 181 trigger_del(s); 182 trigger_add(s->trigger, s); 183 } 184 185 if (tb[SERVICE_SET_VALIDATE]) { 186 service_validate_del(s); 187 blobmsg_for_each_attr(cur, tb[SERVICE_SET_VALIDATE], rem) 188 service_validate_add(s, cur); 189 } 190 191 if (tb[SERVICE_SET_INSTANCES]) { 192 if (!add) 193 vlist_update(&s->instances); 194 blobmsg_for_each_attr(cur, tb[SERVICE_SET_INSTANCES], rem) { 195 service_instance_add(s, cur, stdio_fds, notify_fd); 196 } 197 if (!add) 198 vlist_flush(&s->instances); 199 } 200 201 if (tb[SERVICE_SET_DATA] && 202 service_update_data(s, tb[SERVICE_SET_DATA]) < 0) 203 return -1; 204 205 s->deleted = false; 206 207 if (init || tb[SERVICE_SET_INSTANCES]) 208 rc(s->name, "running"); 209 210 return 0; 211 } 212 213 static void 214 service_delete(struct service *s, bool container) 215 { 216 blobmsg_list_free(&s->data_blob); 217 free(s->data); 218 s->data = NULL; 219 vlist_flush_all(&s->instances); 220 s->deleted = true; 221 service_stopped(s); 222 } 223 224 enum { 225 SERVICE_ATTR_NAME, 226 __SERVICE_ATTR_MAX, 227 }; 228 229 static const struct blobmsg_policy service_attrs[__SERVICE_ATTR_MAX] = { 230 [SERVICE_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING }, 231 }; 232 233 enum { 234 SERVICE_DEL_ATTR_NAME, 235 SERVICE_DEL_ATTR_INSTANCE, 236 __SERVICE_DEL_ATTR_MAX, 237 }; 238 239 static const struct blobmsg_policy service_del_attrs[__SERVICE_DEL_ATTR_MAX] = { 240 [SERVICE_DEL_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING }, 241 [SERVICE_DEL_ATTR_INSTANCE] = { "instance", BLOBMSG_TYPE_STRING }, 242 }; 243 244 enum { 245 SERVICE_LIST_ATTR_NAME, 246 SERVICE_LIST_ATTR_VERBOSE, 247 __SERVICE_LIST_ATTR_MAX, 248 }; 249 250 static const struct blobmsg_policy service_list_attrs[__SERVICE_LIST_ATTR_MAX] = { 251 [SERVICE_LIST_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING }, 252 [SERVICE_LIST_ATTR_VERBOSE] = { "verbose", BLOBMSG_TYPE_BOOL }, 253 }; 254 255 enum { 256 SERVICE_SIGNAL_ATTR_NAME, 257 SERVICE_SIGNAL_ATTR_INSTANCE, 258 SERVICE_SIGNAL_ATTR_SIGNAL, 259 __SERVICE_SIGNAL_ATTR_MAX, 260 }; 261 262 static const struct blobmsg_policy service_signal_attrs[__SERVICE_SIGNAL_ATTR_MAX] = { 263 [SERVICE_SIGNAL_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING }, 264 [SERVICE_SIGNAL_ATTR_INSTANCE] = { "instance", BLOBMSG_TYPE_STRING }, 265 [SERVICE_SIGNAL_ATTR_SIGNAL] = { "signal", BLOBMSG_TYPE_INT32 }, 266 }; 267 268 enum { 269 SERVICE_STATE_ATTR_SPAWN, 270 SERVICE_STATE_ATTR_NAME, 271 __SERVICE_STATE_ATTR_MAX, 272 }; 273 274 static const struct blobmsg_policy service_state_attrs[__SERVICE_STATE_ATTR_MAX] = { 275 [SERVICE_STATE_ATTR_SPAWN] = { "spawn", BLOBMSG_TYPE_BOOL }, 276 [SERVICE_STATE_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING }, 277 }; 278 279 enum { 280 EVENT_TYPE, 281 EVENT_DATA, 282 __EVENT_MAX 283 }; 284 285 static const struct blobmsg_policy event_policy[__EVENT_MAX] = { 286 [EVENT_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING }, 287 [EVENT_DATA] = { .name = "data", .type = BLOBMSG_TYPE_TABLE }, 288 }; 289 290 enum { 291 VALIDATE_PACKAGE, 292 VALIDATE_TYPE, 293 VALIDATE_SERVICE, 294 __VALIDATE_MAX 295 }; 296 297 static const struct blobmsg_policy validate_policy[__VALIDATE_MAX] = { 298 [VALIDATE_PACKAGE] = { .name = "package", .type = BLOBMSG_TYPE_STRING }, 299 [VALIDATE_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING }, 300 [VALIDATE_SERVICE] = { .name = "service", .type = BLOBMSG_TYPE_STRING }, 301 }; 302 303 enum { 304 DATA_NAME, 305 DATA_INSTANCE, 306 DATA_TYPE, 307 __DATA_MAX 308 }; 309 310 static const struct blobmsg_policy get_data_policy[] = { 311 [DATA_NAME] = { "name", BLOBMSG_TYPE_STRING }, 312 [DATA_INSTANCE] = { "instance", BLOBMSG_TYPE_STRING }, 313 [DATA_TYPE] = { "type", BLOBMSG_TYPE_STRING }, 314 }; 315 316 enum { 317 SET_DATA_NAME, 318 SET_DATA_INSTANCE, 319 SET_DATA_DATA, 320 __SET_DATA_MAX 321 }; 322 323 static const struct blobmsg_policy set_data_policy[__SET_DATA_MAX] = { 324 [SET_DATA_NAME] = { "name", BLOBMSG_TYPE_STRING }, 325 [SET_DATA_INSTANCE] = { "instance", BLOBMSG_TYPE_STRING }, 326 [SET_DATA_DATA] = { "data", BLOBMSG_TYPE_TABLE }, 327 }; 328 329 enum { 330 CONTAINER_CONSOLE_NAME, 331 CONTAINER_CONSOLE_INSTANCE, 332 __CONTAINER_CONSOLE_MAX, 333 }; 334 335 static const struct blobmsg_policy container_console_policy[__CONTAINER_CONSOLE_MAX] = { 336 [CONTAINER_CONSOLE_NAME] = { "name", BLOBMSG_TYPE_STRING }, 337 [CONTAINER_CONSOLE_INSTANCE] = { "instance", BLOBMSG_TYPE_STRING }, 338 }; 339 340 static inline bool is_container_obj(struct ubus_object *obj) 341 { 342 return (obj && (strcmp(obj->name, "container") == 0)); 343 } 344 345 static inline void put_namespace(struct blob_buf *b, char *name) 346 { 347 char nsfname[32]; 348 struct stat statbuf; 349 350 snprintf(nsfname, sizeof(nsfname), "/proc/self/ns/%s", name); 351 352 if (!stat(nsfname, &statbuf)) 353 blobmsg_add_string(b, NULL, name); 354 } 355 356 static void put_cgroups(struct blob_buf *b) 357 { 358 int fd, ret; 359 static char buf[512] = ""; 360 char *t, *z; 361 362 fd = open("/sys/fs/cgroup/cgroup.controllers", O_RDONLY); 363 if (fd == -1) 364 return; 365 366 ret = read(fd, &buf, sizeof(buf)); 367 /* make sure buffer is NULL-terminated */ 368 buf[sizeof(buf)-1] = '\0'; 369 370 close(fd); 371 372 if (ret < 2) 373 return; 374 375 t = buf; 376 while(t) { 377 z = t; 378 /* replace space with \0 and direct next entry */ 379 t = strchr(z, ' '); 380 if (t) { 381 *(t++) = '\0'; 382 } else { /* replace trailing new-line with \0 */ 383 t = strchr(z, '\n'); 384 if (!t) /* shouldn't happen, but don't segfault if it does */ 385 break; 386 387 *t = '\0'; 388 t = NULL; 389 } 390 blobmsg_add_string(b, NULL, z); 391 } 392 } 393 394 static int 395 container_handle_features(struct ubus_context *ctx, struct ubus_object *obj, 396 struct ubus_request_data *req, const char *method, 397 struct blob_attr *msg) 398 { 399 struct utsname utsbuf; 400 struct stat statbuf; 401 void *nsarray, *cgarray; 402 403 if (stat("/sbin/ujail", &statbuf)) 404 return UBUS_STATUS_NOT_SUPPORTED; 405 406 if (uname(&utsbuf) < 0) 407 return UBUS_STATUS_UNKNOWN_ERROR; 408 409 blob_buf_init(&b, 0); 410 blobmsg_add_string(&b, "machine", utsbuf.machine); 411 412 #ifdef SECCOMP_SUPPORT 413 blobmsg_add_u8(&b, "seccomp", true); 414 #else 415 blobmsg_add_u8(&b, "seccomp", false); 416 #endif 417 418 cgarray = blobmsg_open_array(&b, "cgroup"); 419 put_cgroups(&b); 420 blobmsg_close_array(&b, cgarray); 421 422 nsarray = blobmsg_open_array(&b, "namespaces"); 423 put_namespace(&b, "cgroup"); 424 put_namespace(&b, "ipc"); 425 put_namespace(&b, "mnt"); 426 put_namespace(&b, "net"); 427 put_namespace(&b, "pid"); 428 put_namespace(&b, "time"); 429 put_namespace(&b, "user"); 430 put_namespace(&b, "uts"); 431 blobmsg_close_array(&b, nsarray); 432 ubus_send_reply(ctx, req, b.head); 433 434 return UBUS_STATUS_OK; 435 } 436 437 static int 438 service_handle_set(struct ubus_context *ctx, struct ubus_object *obj, 439 struct ubus_request_data *req, const char *method, 440 struct blob_attr *msg) 441 { 442 struct blob_attr *tb[__SERVICE_SET_MAX], *cur; 443 int stdio_fds[3] = { -1, -1, -1 }; 444 int notify_fd = -1; 445 struct service *s = NULL; 446 const char *name; 447 bool container = is_container_obj(obj); 448 bool add = !strcmp(method, "add"); 449 int sock, ret; 450 451 blobmsg_parse(service_set_attrs, __SERVICE_SET_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 452 cur = tb[SERVICE_SET_NAME]; 453 if (!cur) 454 return UBUS_STATUS_INVALID_ARGUMENT; 455 456 name = blobmsg_data(cur); 457 458 sock = req ? ubus_request_get_caller_fd(req) : -1; 459 if (sock > -1) { 460 if (stdio_notify_fds_recv(sock, stdio_fds, ¬ify_fd)) 461 ULOG_WARN("failed to receive descriptors for %s: %m\n", name); 462 463 close(sock); 464 } 465 466 if (container) 467 s = avl_find_element(&containers, name, s, avl); 468 else 469 s = avl_find_element(&services, name, s, avl); 470 471 if (s) { 472 P_DEBUG(2, "Update service %s\n", name); 473 ret = service_update(s, tb, add, false, stdio_fds, ¬ify_fd); 474 goto out; 475 } 476 477 P_DEBUG(2, "Create service %s\n", name); 478 s = service_alloc(name); 479 if (!s) { 480 ret = UBUS_STATUS_UNKNOWN_ERROR; 481 goto out; 482 } 483 484 s->container = container; 485 486 ret = service_update(s, tb, add, true, stdio_fds, ¬ify_fd); 487 if (ret) 488 goto out; 489 490 if (container) { 491 avl_insert(&containers, &s->avl); 492 493 service_event("container.start", s->name, NULL); 494 } else { 495 avl_insert(&services, &s->avl); 496 497 service_event("service.start", s->name, NULL); 498 } 499 500 out: 501 stdio_fds_close(stdio_fds); 502 if (notify_fd > -1) 503 close(notify_fd); 504 return ret; 505 } 506 507 static void 508 service_dump(struct service *s, bool verbose) 509 { 510 struct service_instance *in; 511 void *c, *i; 512 513 c = blobmsg_open_table(&b, s->name); 514 515 if (!s->autostart) 516 blobmsg_add_u8(&b, "autostart", false); 517 518 if (!avl_is_empty(&s->data_blob.avl)) { 519 struct blobmsg_list_node *var; 520 i = blobmsg_open_table(&b, "data"); 521 blobmsg_list_for_each(&s->data_blob, var) 522 blobmsg_add_blob(&b, var->data); 523 blobmsg_close_table(&b, i); 524 } 525 526 if (!avl_is_empty(&s->instances.avl)) { 527 i = blobmsg_open_table(&b, "instances"); 528 vlist_for_each_element(&s->instances, in, node) 529 instance_dump(&b, in, verbose); 530 blobmsg_close_table(&b, i); 531 } 532 if (verbose && s->trigger) 533 blobmsg_add_blob(&b, s->trigger); 534 if (verbose && !list_empty(&s->validators)) 535 service_validate_dump(&b, s); 536 blobmsg_close_table(&b, c); 537 } 538 539 static int 540 service_handle_list(struct ubus_context *ctx, struct ubus_object *obj, 541 struct ubus_request_data *req, const char *method, 542 struct blob_attr *msg) 543 { 544 struct blob_attr *tb[__SERVICE_LIST_ATTR_MAX]; 545 struct service *s; 546 const char *name = NULL; 547 bool verbose = false; 548 bool container = is_container_obj(obj); 549 const struct avl_tree *tree = container?&containers:&services; 550 551 blobmsg_parse(service_list_attrs, __SERVICE_LIST_ATTR_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 552 553 if (tb[SERVICE_LIST_ATTR_VERBOSE]) 554 verbose = blobmsg_get_bool(tb[SERVICE_LIST_ATTR_VERBOSE]); 555 if (tb[SERVICE_LIST_ATTR_NAME]) 556 name = blobmsg_get_string(tb[SERVICE_LIST_ATTR_NAME]); 557 558 blob_buf_init(&b, 0); 559 avl_for_each_element(tree, s, avl) { 560 if (name && strcmp(s->name, name) != 0) 561 continue; 562 563 service_dump(s, verbose); 564 } 565 566 ubus_send_reply(ctx, req, b.head); 567 568 return 0; 569 } 570 571 static int 572 service_handle_delete(struct ubus_context *ctx, struct ubus_object *obj, 573 struct ubus_request_data *req, const char *method, 574 struct blob_attr *msg) 575 { 576 struct blob_attr *tb[__SERVICE_DEL_ATTR_MAX], *cur; 577 struct service *s; 578 struct service_instance *in; 579 bool container = is_container_obj(obj); 580 581 blobmsg_parse(service_del_attrs, __SERVICE_DEL_ATTR_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 582 583 cur = tb[SERVICE_DEL_ATTR_NAME]; 584 if (!cur) 585 return UBUS_STATUS_NOT_FOUND; 586 587 if (container) 588 s = avl_find_element(&containers, blobmsg_data(cur), s, avl); 589 else 590 s = avl_find_element(&services, blobmsg_data(cur), s, avl); 591 592 if (!s) 593 return UBUS_STATUS_NOT_FOUND; 594 595 cur = tb[SERVICE_DEL_ATTR_INSTANCE]; 596 if (!cur) { 597 service_delete(s, container); 598 return 0; 599 } 600 601 in = vlist_find(&s->instances, blobmsg_data(cur), in, node); 602 if (!in) { 603 ERROR("instance %s not found\n", (char *) blobmsg_data(cur)); 604 return UBUS_STATUS_NOT_FOUND; 605 } 606 607 vlist_delete(&s->instances, &in->node); 608 609 return 0; 610 } 611 612 static int 613 service_handle_kill(struct service_instance *in, int sig) 614 { 615 if (instance_signal(in, sig) == 0) 616 return 0; 617 618 switch (errno) { 619 case EINVAL: return UBUS_STATUS_INVALID_ARGUMENT; 620 case EPERM: return UBUS_STATUS_PERMISSION_DENIED; 621 case ESRCH: return UBUS_STATUS_NOT_FOUND; 622 } 623 624 return UBUS_STATUS_UNKNOWN_ERROR; 625 } 626 627 static int 628 service_handle_signal(struct ubus_context *ctx, struct ubus_object *obj, 629 struct ubus_request_data *req, const char *method, 630 struct blob_attr *msg) 631 { 632 struct blob_attr *tb[__SERVICE_SIGNAL_ATTR_MAX], *cur; 633 struct service *s; 634 struct service_instance *in; 635 bool container = is_container_obj(obj); 636 int sig = SIGHUP; 637 int rv = 0; 638 639 blobmsg_parse(service_signal_attrs, __SERVICE_SIGNAL_ATTR_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 640 641 cur = tb[SERVICE_SIGNAL_ATTR_SIGNAL]; 642 if (cur) 643 sig = blobmsg_get_u32(cur); 644 645 cur = tb[SERVICE_SIGNAL_ATTR_NAME]; 646 if (!cur) 647 return UBUS_STATUS_NOT_FOUND; 648 649 if (container) 650 s = avl_find_element(&containers, blobmsg_data(cur), s, avl); 651 else 652 s = avl_find_element(&services, blobmsg_data(cur), s, avl); 653 654 if (!s) 655 return UBUS_STATUS_NOT_FOUND; 656 657 cur = tb[SERVICE_SIGNAL_ATTR_INSTANCE]; 658 if (!cur) { 659 vlist_for_each_element(&s->instances, in, node) 660 rv = service_handle_kill(in, sig); 661 662 return rv; 663 } 664 665 in = vlist_find(&s->instances, blobmsg_data(cur), in, node); 666 if (!in) { 667 ERROR("instance %s not found\n", blobmsg_get_string(cur)); 668 return UBUS_STATUS_NOT_FOUND; 669 } 670 671 return service_handle_kill(in, sig); 672 } 673 674 static int 675 service_handle_state(struct ubus_context *ctx, struct ubus_object *obj, 676 struct ubus_request_data *req, const char *method, 677 struct blob_attr *msg) 678 { 679 struct blob_attr *tb[__SERVICE_STATE_ATTR_MAX]; 680 struct service *s; 681 struct service_instance *in; 682 bool container = is_container_obj(obj); 683 int spawn; 684 685 blobmsg_parse(service_state_attrs, __SERVICE_STATE_ATTR_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 686 687 if (!tb[SERVICE_STATE_ATTR_SPAWN]) 688 return UBUS_STATUS_INVALID_ARGUMENT; 689 690 if (!tb[SERVICE_STATE_ATTR_NAME]) 691 return UBUS_STATUS_NOT_FOUND; 692 693 if (container) 694 s = avl_find_element(&containers, blobmsg_data(tb[SERVICE_STATE_ATTR_NAME]), s, avl); 695 else 696 s = avl_find_element(&services, blobmsg_data(tb[SERVICE_STATE_ATTR_NAME]), s, avl); 697 698 if (!s) 699 return UBUS_STATUS_NOT_FOUND; 700 701 spawn = !!blobmsg_get_u8(tb[SERVICE_STATE_ATTR_SPAWN]); 702 vlist_for_each_element(&s->instances, in, node) { 703 if (!!in->proc.pending == !!spawn) 704 continue; 705 else if (!in->proc.pending) 706 instance_start(in); 707 else 708 instance_stop(in, false); 709 } 710 711 return UBUS_STATUS_OK; 712 } 713 714 static void 715 service_avl_stop_all(struct avl_tree *sctree, unsigned int *term_timeout) 716 { 717 struct service *s; 718 719 avl_for_each_element(sctree, s, avl) { 720 struct service_instance *in, *ptr; 721 722 vlist_for_each_element_safe(&s->instances, in, node, ptr) { 723 if (in->term_timeout > *term_timeout) 724 *term_timeout = in->term_timeout; 725 instance_stop(in, true); 726 } 727 } 728 } 729 730 void 731 service_stop_all(void) 732 { 733 unsigned int term_timeout = 0; 734 735 service_avl_stop_all(&containers, &term_timeout); 736 service_avl_stop_all(&services, &term_timeout); 737 procd_inittab_kill(); 738 739 sleep(term_timeout); 740 } 741 742 static int 743 service_handle_update(struct ubus_context *ctx, struct ubus_object *obj, 744 struct ubus_request_data *req, const char *method, 745 struct blob_attr *msg) 746 { 747 struct blob_attr *tb[__SERVICE_ATTR_MAX], *cur; 748 struct service *s; 749 bool container = is_container_obj(obj); 750 751 blobmsg_parse(service_attrs, __SERVICE_ATTR_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 752 753 cur = tb[SERVICE_SET_NAME]; 754 if (!cur) 755 return UBUS_STATUS_INVALID_ARGUMENT; 756 757 if (container) 758 s = avl_find_element(&containers, blobmsg_data(cur), s, avl); 759 else 760 s = avl_find_element(&services, blobmsg_data(cur), s, avl); 761 762 if (!s) 763 return UBUS_STATUS_NOT_FOUND; 764 765 if (!strcmp(method, "update_start")) 766 vlist_update(&s->instances); 767 else 768 vlist_flush(&s->instances); 769 770 return 0; 771 } 772 773 static void ubus_event_bcast(const char *type, const char *param1, const char *val1, 774 const char *param2, const char *val2) 775 { 776 if (!ctx) 777 return; 778 779 blob_buf_init(&b, 0); 780 if (param1 && val1) 781 blobmsg_add_string(&b, param1, val1); 782 if (param2 && val2) 783 blobmsg_add_string(&b, param2, val2); 784 ubus_notify(ctx, &main_object, type, b.head, -1); 785 } 786 787 static int 788 service_handle_event(struct ubus_context *ctx, struct ubus_object *obj, 789 struct ubus_request_data *req, const char *method, 790 struct blob_attr *msg) 791 { 792 struct blob_attr *tb[__EVENT_MAX]; 793 const char *event; 794 795 if (!msg) 796 return UBUS_STATUS_INVALID_ARGUMENT; 797 798 blobmsg_parse(event_policy, __EVENT_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 799 if (!tb[EVENT_TYPE] || !tb[EVENT_DATA]) 800 return UBUS_STATUS_INVALID_ARGUMENT; 801 802 event = blobmsg_get_string(tb[EVENT_TYPE]); 803 trigger_event(event, tb[EVENT_DATA]); 804 805 blob_buf_init(&b, 0); 806 blobmsg_add_string(&b, "type", event); 807 blobmsg_add_blob(&b, tb[EVENT_DATA]); 808 ubus_notify(ctx, &main_object, "event.trigger", b.head, -1); 809 810 if (!strcmp(event, "config.change")) { 811 struct blob_attr *tb2[__VALIDATE_MAX]; 812 813 blobmsg_parse(validate_policy, __VALIDATE_MAX, tb2, 814 blobmsg_data(tb[EVENT_DATA]), blobmsg_data_len(tb[EVENT_DATA])); 815 if (tb2[VALIDATE_PACKAGE]) 816 ubus_event_bcast("config.change", "config", 817 blobmsg_get_string(tb2[VALIDATE_PACKAGE]), NULL, NULL); 818 } 819 return 0; 820 } 821 822 static int 823 service_handle_validate(struct ubus_context *ctx, struct ubus_object *obj, 824 struct ubus_request_data *req, const char *method, 825 struct blob_attr *msg) 826 { 827 struct blob_attr *tb[__VALIDATE_MAX]; 828 char *p = NULL, *t = NULL; 829 830 if (!msg) 831 return UBUS_STATUS_INVALID_ARGUMENT; 832 833 blobmsg_parse(validate_policy, __VALIDATE_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 834 if (tb[VALIDATE_SERVICE]) { 835 return 0; 836 } 837 if (tb[VALIDATE_PACKAGE]) 838 p = blobmsg_get_string(tb[VALIDATE_PACKAGE]); 839 840 if (tb[VALIDATE_TYPE]) 841 t = blobmsg_get_string(tb[VALIDATE_TYPE]); 842 843 blob_buf_init(&b, 0); 844 service_validate_dump_all(&b, p, t); 845 ubus_send_reply(ctx, req, b.head); 846 847 return 0; 848 } 849 850 static void 851 service_dump_data(struct avl_tree *tree, const char *name, const char *instance, 852 const char *type) 853 { 854 struct service_instance *in; 855 struct service *s; 856 857 avl_for_each_element(tree, s, avl) { 858 void *cs = NULL; 859 void *ci = NULL; 860 struct blobmsg_list_node *var; 861 862 if (name && strcmp(name, s->name)) 863 continue; 864 865 blobmsg_list_for_each(&s->data_blob, var) { 866 if (type && strcmp(blobmsg_name(var->data), type)) 867 continue; 868 869 if (!cs) 870 cs = blobmsg_open_table(&b, s->name); 871 if (!ci) 872 ci = blobmsg_open_table(&b, "*"); 873 874 blobmsg_add_blob(&b, var->data); 875 } 876 877 if (ci) 878 blobmsg_close_table(&b, ci); 879 880 vlist_for_each_element(&s->instances, in, node) { 881 ci = NULL; 882 883 if (instance && strcmp(instance, in->name)) 884 continue; 885 886 blobmsg_list_for_each(&in->data, var) { 887 if (type && 888 strcmp(blobmsg_name(var->data), type)) 889 continue; 890 891 if (!cs) 892 cs = blobmsg_open_table(&b, s->name); 893 if (!ci) 894 ci = blobmsg_open_table(&b, in->name); 895 896 blobmsg_add_blob(&b, var->data); 897 } 898 899 if (ci) 900 blobmsg_close_table(&b, ci); 901 } 902 903 if (cs) 904 blobmsg_close_table(&b, cs); 905 } 906 } 907 908 static int 909 service_get_data(struct ubus_context *ctx, struct ubus_object *obj, 910 struct ubus_request_data *req, const char *method, 911 struct blob_attr *msg) 912 { 913 struct blob_attr *tb[__DATA_MAX]; 914 const char *name = NULL; 915 const char *instance = NULL; 916 const char *type = NULL; 917 918 blobmsg_parse(get_data_policy, __DATA_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 919 if (tb[DATA_NAME]) 920 name = blobmsg_data(tb[DATA_NAME]); 921 if (tb[DATA_INSTANCE]) 922 instance = blobmsg_data(tb[DATA_INSTANCE]); 923 if (tb[DATA_TYPE]) 924 type = blobmsg_data(tb[DATA_TYPE]); 925 926 blob_buf_init(&b, 0); 927 service_dump_data(&services, name, instance, type); 928 service_dump_data(&containers, name, instance, type); 929 930 ubus_send_reply(ctx, req, b.head); 931 return 0; 932 } 933 934 static int 935 service_handle_set_data(struct ubus_context *ctx, struct ubus_object *obj, 936 struct ubus_request_data *req, const char *method, 937 struct blob_attr *msg) 938 { 939 struct blob_attr *tb[__SET_DATA_MAX]; 940 struct service *s; 941 struct service_instance *in; 942 const char *name; 943 const char *instance = NULL; 944 945 blobmsg_parse(set_data_policy, __SET_DATA_MAX, tb, 946 blobmsg_data(msg), blobmsg_data_len(msg)); 947 948 if (!tb[SET_DATA_NAME] || !tb[SET_DATA_DATA]) 949 return UBUS_STATUS_INVALID_ARGUMENT; 950 951 name = blobmsg_get_string(tb[SET_DATA_NAME]); 952 953 s = avl_find_element(&services, name, s, avl); 954 if (!s) 955 s = avl_find_element(&containers, name, s, avl); 956 957 if (!s) 958 return UBUS_STATUS_NOT_FOUND; 959 960 if (tb[SET_DATA_INSTANCE]) 961 instance = blobmsg_get_string(tb[SET_DATA_INSTANCE]); 962 963 if (instance) { 964 in = vlist_find(&s->instances, instance, in, node); 965 if (!in) 966 return UBUS_STATUS_NOT_FOUND; 967 968 blobmsg_list_free(&in->data); 969 free(in->data_blob); 970 in->data_blob = blob_memdup(tb[SET_DATA_DATA]); 971 if (!in->data_blob) 972 return UBUS_STATUS_UNKNOWN_ERROR; 973 blobmsg_list_fill(&in->data, blobmsg_data(in->data_blob), 974 blobmsg_data_len(in->data_blob), false); 975 } else { 976 if (service_update_data(s, tb[SET_DATA_DATA]) < 0) 977 return UBUS_STATUS_UNKNOWN_ERROR; 978 } 979 980 return UBUS_STATUS_OK; 981 } 982 983 static int 984 container_handle_console(struct ubus_context *ctx, struct ubus_object *obj, 985 struct ubus_request_data *req, const char *method, 986 struct blob_attr *msg) 987 { 988 bool attach = !strcmp(method, "console_attach"); 989 struct blob_attr *tb[__CONTAINER_CONSOLE_MAX]; 990 struct service *s; 991 struct service_instance *in; 992 int console_fd = -1; 993 994 console_fd = ubus_request_get_caller_fd(req); 995 if (console_fd < 0) 996 return UBUS_STATUS_INVALID_ARGUMENT; 997 998 if (!msg) 999 goto err_console_fd; 1000 1001 blobmsg_parse(container_console_policy, __CONTAINER_CONSOLE_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 1002 if (!tb[CONTAINER_CONSOLE_NAME]) 1003 goto err_console_fd; 1004 1005 s = avl_find_element(&containers, blobmsg_data(tb[CONTAINER_CONSOLE_NAME]), s, avl); 1006 if (!s) 1007 goto err_console_fd; 1008 1009 if (tb[CONTAINER_CONSOLE_INSTANCE]) { 1010 in = vlist_find(&s->instances, blobmsg_data(tb[CONTAINER_CONSOLE_INSTANCE]), in, node); 1011 } else { 1012 /* use first element in instances list */ 1013 vlist_for_each_element(&s->instances, in, node) 1014 break; 1015 } 1016 if (!in) 1017 goto err_console_fd; 1018 1019 if (attach) { 1020 if (in->console.fd.fd < 0) { 1021 close(console_fd); 1022 return UBUS_STATUS_NOT_SUPPORTED; 1023 } 1024 1025 /* close and replace existing attached console */ 1026 if (in->console_client.fd.fd > -1) 1027 close(in->console_client.fd.fd); 1028 1029 ustream_fd_init(&in->console_client, console_fd); 1030 } else { 1031 ustream_fd_init(&in->console, console_fd); 1032 } 1033 1034 return UBUS_STATUS_OK; 1035 err_console_fd: 1036 close(console_fd); 1037 return UBUS_STATUS_INVALID_ARGUMENT; 1038 } 1039 1040 enum { 1041 SERVICE_WATCHDOG_MODE, 1042 SERVICE_WATCHDOG_TIMEOUT, 1043 SERVICE_WATCHDOG_NAME, 1044 SERVICE_WATCHDOG_INSTANCE, 1045 __SERVICE_WATCHDOG_MAX, 1046 }; 1047 1048 static const struct blobmsg_policy service_watchdog_policy[__SERVICE_WATCHDOG_MAX] = { 1049 [SERVICE_WATCHDOG_MODE] = { "mode", BLOBMSG_TYPE_INT32 }, 1050 [SERVICE_WATCHDOG_NAME] = { "name", BLOBMSG_TYPE_STRING }, 1051 [SERVICE_WATCHDOG_TIMEOUT] = { "timeout", BLOBMSG_TYPE_INT32 }, 1052 [SERVICE_WATCHDOG_INSTANCE] = { "instance", BLOBMSG_TYPE_STRING }, 1053 }; 1054 1055 static int 1056 service_handle_watchdog(struct ubus_context *ctx, struct ubus_object *obj, 1057 struct ubus_request_data *req, const char *method, 1058 struct blob_attr *msg) 1059 { 1060 struct blob_attr *tb[__SERVICE_WATCHDOG_MAX] = {0}; 1061 struct service *s; 1062 struct blob_attr *cur; 1063 struct service_instance *in; 1064 1065 blobmsg_parse(service_watchdog_policy, __SERVICE_WATCHDOG_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); 1066 cur = tb[SERVICE_WATCHDOG_NAME]; 1067 if (!cur) 1068 return UBUS_STATUS_NOT_FOUND; 1069 1070 s = avl_find_element(&services, blobmsg_data(cur), s, avl); 1071 if (!s) 1072 return UBUS_STATUS_NOT_FOUND; 1073 1074 cur = tb[SERVICE_WATCHDOG_INSTANCE]; 1075 if (!cur) 1076 return UBUS_STATUS_NOT_FOUND; 1077 1078 in = vlist_find(&s->instances, blobmsg_data(cur), in, node); 1079 if (!in) { 1080 ERROR("instance %s not found\n", blobmsg_get_string(cur)); 1081 return UBUS_STATUS_NOT_FOUND; 1082 } 1083 1084 if (tb[SERVICE_WATCHDOG_MODE]) 1085 in->watchdog.mode = blobmsg_get_u32(tb[SERVICE_WATCHDOG_MODE]); 1086 1087 if (tb[SERVICE_WATCHDOG_TIMEOUT]) 1088 in->watchdog.freq = blobmsg_get_u32(tb[SERVICE_WATCHDOG_TIMEOUT]); 1089 1090 if (in->watchdog.mode == INSTANCE_WATCHDOG_MODE_DISABLED) 1091 uloop_timeout_cancel(&in->watchdog.timeout); 1092 else 1093 uloop_timeout_set(&in->watchdog.timeout, in->watchdog.freq * 1000); 1094 1095 blob_buf_init(&b, 0); 1096 blobmsg_add_string(&b, "name", blobmsg_get_string(tb[SERVICE_WATCHDOG_NAME])); 1097 blobmsg_add_string(&b, "instance", blobmsg_get_string(tb[SERVICE_WATCHDOG_INSTANCE])); 1098 blobmsg_add_u32(&b, "mode", in->watchdog.mode); 1099 blobmsg_add_u32(&b, "timeout", in->watchdog.freq); 1100 1101 ubus_send_reply(ctx, req, b.head); 1102 1103 // If the service adjusts the mode or timeout, mark it as self managed 1104 // so that it doesn't get restarted with a new /etc/init.d/SERVICE start 1105 if (tb[SERVICE_WATCHDOG_MODE] || tb[SERVICE_WATCHDOG_TIMEOUT]) 1106 in->watchdog.self_managed = true; 1107 1108 return UBUS_STATUS_OK; 1109 } 1110 1111 static struct ubus_method main_object_methods[] = { 1112 UBUS_METHOD("set", service_handle_set, service_set_attrs), 1113 UBUS_METHOD("add", service_handle_set, service_set_attrs), 1114 UBUS_METHOD("list", service_handle_list, service_list_attrs), 1115 UBUS_METHOD("delete", service_handle_delete, service_del_attrs), 1116 UBUS_METHOD("signal", service_handle_signal, service_signal_attrs), 1117 UBUS_METHOD("update_start", service_handle_update, service_attrs), 1118 UBUS_METHOD("update_complete", service_handle_update, service_attrs), 1119 UBUS_METHOD("event", service_handle_event, event_policy), 1120 UBUS_METHOD("validate", service_handle_validate, validate_policy), 1121 UBUS_METHOD("get_data", service_get_data, get_data_policy), 1122 UBUS_METHOD("set_data", service_handle_set_data, set_data_policy), 1123 UBUS_METHOD("state", service_handle_state, service_state_attrs), 1124 UBUS_METHOD("watchdog", service_handle_watchdog, service_watchdog_policy), 1125 }; 1126 1127 static struct ubus_object_type main_object_type = 1128 UBUS_OBJECT_TYPE("service", main_object_methods); 1129 1130 static struct ubus_object main_object = { 1131 .name = "service", 1132 .type = &main_object_type, 1133 .methods = main_object_methods, 1134 .n_methods = ARRAY_SIZE(main_object_methods), 1135 }; 1136 1137 int 1138 service_start_early(char *name, char *cmdline, char *user, char *group) 1139 { 1140 void *instances, *instance, *command, *respawn; 1141 char *t; 1142 1143 blob_buf_init(&b, 0); 1144 blobmsg_add_string(&b, "name", name); 1145 instances = blobmsg_open_table(&b, "instances"); 1146 instance = blobmsg_open_table(&b, "instance1"); 1147 command = blobmsg_open_array(&b, "command"); 1148 t = strtok(cmdline, " "); 1149 while (t) { 1150 blobmsg_add_string(&b, NULL, t); 1151 t = strtok(NULL, " "); 1152 } 1153 blobmsg_close_array(&b, command); 1154 respawn = blobmsg_open_array(&b, "respawn"); 1155 blobmsg_add_string(&b, NULL, "3600"); 1156 blobmsg_add_string(&b, NULL, "1"); 1157 blobmsg_add_string(&b, NULL, ""); 1158 blobmsg_close_array(&b, respawn); 1159 if (user) 1160 blobmsg_add_string(&b, "user", user); 1161 if (group) 1162 blobmsg_add_string(&b, "group", group); 1163 1164 blobmsg_close_table(&b, instance); 1165 blobmsg_close_table(&b, instances); 1166 1167 return service_handle_set(NULL, NULL, NULL, "add", b.head); 1168 } 1169 1170 void service_stopped(struct service *s) 1171 { 1172 if (s->deleted && avl_is_empty(&s->instances.avl)) { 1173 if (s->container) { 1174 service_event("container.stop", s->name, NULL); 1175 avl_delete(&containers, &s->avl); 1176 } else { 1177 service_event("service.stop", s->name, NULL); 1178 avl_delete(&services, &s->avl); 1179 } 1180 trigger_del(s); 1181 service_validate_del(s); 1182 free(s->trigger); 1183 free(s); 1184 } 1185 } 1186 1187 void service_event(const char *type, const char *service, const char *instance) 1188 { 1189 ubus_event_bcast(type, "service", service, "instance", instance); 1190 } 1191 1192 void service_event_instance_exit(const char *type, struct service_instance *in) 1193 { 1194 if (!ctx) 1195 return; 1196 1197 blob_buf_init(&b, 0); 1198 blobmsg_add_string(&b, "service", in->srv->name); 1199 blobmsg_add_string(&b, "instance", in->name); 1200 blobmsg_add_u32(&b, "pid", in->proc.pid); 1201 blobmsg_add_u32(&b, "exit_code", in->exit_code); 1202 blobmsg_add_u32(&b, "respawn_count", in->respawn_count); 1203 if (in->command) { 1204 struct blob_attr *cur; 1205 int rem; 1206 void *a = blobmsg_open_array(&b, "command"); 1207 blobmsg_for_each_attr(cur, in->command, rem) 1208 blobmsg_add_string(&b, NULL, blobmsg_get_string(cur)); 1209 blobmsg_close_array(&b, a); 1210 } 1211 ubus_notify(ctx, &main_object, type, b.head, -1); 1212 } 1213 1214 static struct ubus_method container_object_methods[] = { 1215 UBUS_METHOD("set", service_handle_set, service_set_attrs), 1216 UBUS_METHOD("add", service_handle_set, service_set_attrs), 1217 UBUS_METHOD("list", service_handle_list, service_list_attrs), 1218 UBUS_METHOD("delete", service_handle_delete, service_del_attrs), 1219 UBUS_METHOD("state", service_handle_state, service_state_attrs), 1220 UBUS_METHOD_NOARG("get_features", container_handle_features), 1221 UBUS_METHOD("console_set", container_handle_console, container_console_policy), 1222 UBUS_METHOD("console_attach", container_handle_console, container_console_policy), 1223 }; 1224 1225 static struct ubus_object_type container_object_type = 1226 UBUS_OBJECT_TYPE("container", container_object_methods); 1227 1228 static struct ubus_object container_object = { 1229 .name = "container", 1230 .type = &container_object_type, 1231 .methods = container_object_methods, 1232 .n_methods = ARRAY_SIZE(container_object_methods), 1233 }; 1234 1235 void ubus_init_service(struct ubus_context *_ctx) 1236 { 1237 struct stat statbuf; 1238 1239 ctx = _ctx; 1240 ubus_add_object(ctx, &main_object); 1241 1242 if (!stat("/sbin/ujail", &statbuf)) 1243 ubus_add_object(ctx, &container_object); 1244 } 1245
This page was automatically generated by LXR 0.3.1. • OpenWrt