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