1 /* 2 * Changes: 3 * Jan 22, 2010: Created (Cristiano Giuffrida) 4 */ 5 6 #include "inc.h" 7 8 #include "kernel/proc.h" 9 10 static int check_request(struct rs_start *rs_start); 11 12 /*===========================================================================* 13 * do_up * 14 *===========================================================================*/ 15 int do_up(m_ptr) 16 message *m_ptr; /* request message pointer */ 17 { 18 /* A request was made to start a new system service. */ 19 struct rproc *rp; 20 struct rprocpub *rpub; 21 int r; 22 struct rs_start rs_start; 23 int noblock; 24 int init_flags = 0; 25 26 /* Check if the call can be allowed. */ 27 if((r = check_call_permission(m_ptr->m_source, RS_UP, NULL)) != OK) 28 return r; 29 30 /* Allocate a new system service slot. */ 31 r = alloc_slot(&rp); 32 if(r != OK) { 33 printf("RS: do_up: unable to allocate a new slot: %d\n", r); 34 return r; 35 } 36 rpub = rp->r_pub; 37 38 /* Copy the request structure. */ 39 r = copy_rs_start(m_ptr->m_source, m_ptr->m_rs_req.addr, &rs_start); 40 if (r != OK) { 41 return r; 42 } 43 r = check_request(&rs_start); 44 if (r != OK) { 45 return r; 46 } 47 48 /* Check flags. */ 49 noblock = (rs_start.rss_flags & RSS_NOBLOCK); 50 if(rs_start.rss_flags & RSS_FORCE_INIT_CRASH) { 51 init_flags |= SEF_INIT_CRASH; 52 } 53 if(rs_start.rss_flags & RSS_FORCE_INIT_FAIL) { 54 init_flags |= SEF_INIT_FAIL; 55 } 56 if(rs_start.rss_flags & RSS_FORCE_INIT_TIMEOUT) { 57 init_flags |= SEF_INIT_TIMEOUT; 58 } 59 if(rs_start.rss_flags & RSS_FORCE_INIT_DEFCB) { 60 init_flags |= SEF_INIT_DEFCB; 61 } 62 63 /* Initialize the slot as requested. */ 64 r = init_slot(rp, &rs_start, m_ptr->m_source); 65 if(r != OK) { 66 printf("RS: do_up: unable to init the new slot: %d\n", r); 67 return r; 68 } 69 70 /* Check for duplicates */ 71 if(lookup_slot_by_label(rpub->label)) { 72 printf("RS: service with the same label '%s' already exists\n", 73 rpub->label); 74 return EBUSY; 75 } 76 if(rpub->dev_nr>0 && lookup_slot_by_dev_nr(rpub->dev_nr)) { 77 printf("RS: service with the same device number %d already exists\n", 78 rpub->dev_nr); 79 return EBUSY; 80 } 81 82 /* All information was gathered. Now try to start the system service. */ 83 r = start_service(rp, init_flags); 84 if(r != OK) { 85 return r; 86 } 87 88 /* Unblock the caller immediately if requested. */ 89 if(noblock) { 90 return OK; 91 } 92 93 /* Late reply - send a reply when service completes initialization. */ 94 rp->r_flags |= RS_LATEREPLY; 95 rp->r_caller = m_ptr->m_source; 96 rp->r_caller_request = RS_UP; 97 98 return EDONTREPLY; 99 } 100 101 /*===========================================================================* 102 * do_down * 103 *===========================================================================*/ 104 int do_down(message *m_ptr) 105 { 106 register struct rproc *rp; 107 int s; 108 char label[RS_MAX_LABEL_LEN]; 109 110 /* Copy label. */ 111 s = copy_label(m_ptr->m_source, m_ptr->m_rs_req.addr, 112 m_ptr->m_rs_req.len, label, sizeof(label)); 113 if(s != OK) { 114 return s; 115 } 116 117 /* Lookup slot by label. */ 118 rp = lookup_slot_by_label(label); 119 if(!rp) { 120 if(rs_verbose) 121 printf("RS: do_down: service '%s' not found\n", label); 122 return(ESRCH); 123 } 124 125 /* Check if the call can be allowed. */ 126 if((s = check_call_permission(m_ptr->m_source, RS_DOWN, rp)) != OK) 127 return s; 128 129 /* Stop service. */ 130 if (rp->r_flags & RS_TERMINATED) { 131 /* A recovery script is requesting us to bring down the service. 132 * The service is already gone, simply perform cleanup. 133 */ 134 if(rs_verbose) 135 printf("RS: recovery script performs service down...\n"); 136 unpublish_service(rp); 137 cleanup_service(rp); 138 return(OK); 139 } 140 stop_service(rp,RS_EXITING); 141 142 /* Late reply - send a reply when service dies. */ 143 rp->r_flags |= RS_LATEREPLY; 144 rp->r_caller = m_ptr->m_source; 145 rp->r_caller_request = RS_DOWN; 146 147 return EDONTREPLY; 148 } 149 150 /*===========================================================================* 151 * do_restart * 152 *===========================================================================*/ 153 int do_restart(message *m_ptr) 154 { 155 struct rproc *rp; 156 int s, r; 157 char label[RS_MAX_LABEL_LEN]; 158 char script[MAX_SCRIPT_LEN]; 159 160 /* Copy label. */ 161 s = copy_label(m_ptr->m_source, m_ptr->m_rs_req.addr, 162 m_ptr->m_rs_req.len, label, sizeof(label)); 163 if(s != OK) { 164 return s; 165 } 166 167 /* Lookup slot by label. */ 168 rp = lookup_slot_by_label(label); 169 if(!rp) { 170 if(rs_verbose) 171 printf("RS: do_restart: service '%s' not found\n", label); 172 return(ESRCH); 173 } 174 175 /* Check if the call can be allowed. */ 176 if((r = check_call_permission(m_ptr->m_source, RS_RESTART, rp)) != OK) 177 return r; 178 179 /* We can only be asked to restart a service from a recovery script. */ 180 if (! (rp->r_flags & RS_TERMINATED) ) { 181 if(rs_verbose) 182 printf("RS: %s is still running\n", srv_to_string(rp)); 183 return EBUSY; 184 } 185 186 if(rs_verbose) 187 printf("RS: recovery script performs service restart...\n"); 188 189 /* Restart the service, but make sure we don't call the script again. */ 190 strcpy(script, rp->r_script); 191 rp->r_script[0] = '\0'; 192 restart_service(rp); 193 strcpy(rp->r_script, script); 194 195 return OK; 196 } 197 198 /*===========================================================================* 199 * do_clone * 200 *===========================================================================*/ 201 int do_clone(message *m_ptr) 202 { 203 struct rproc *rp; 204 struct rprocpub *rpub; 205 int s, r; 206 char label[RS_MAX_LABEL_LEN]; 207 208 /* Copy label. */ 209 s = copy_label(m_ptr->m_source, m_ptr->m_rs_req.addr, 210 m_ptr->m_rs_req.len, label, sizeof(label)); 211 if(s != OK) { 212 return s; 213 } 214 215 /* Lookup slot by label. */ 216 rp = lookup_slot_by_label(label); 217 if(!rp) { 218 if(rs_verbose) 219 printf("RS: do_clone: service '%s' not found\n", label); 220 return(ESRCH); 221 } 222 rpub = rp->r_pub; 223 224 /* Check if the call can be allowed. */ 225 if((r = check_call_permission(m_ptr->m_source, RS_CLONE, rp)) != OK) 226 return r; 227 228 /* Don't clone if a replica is already available. */ 229 if(rp->r_next_rp) { 230 return EEXIST; 231 } 232 233 /* Clone the service as requested. */ 234 rpub->sys_flags |= SF_USE_REPL; 235 if ((r = clone_service(rp, RST_SYS_PROC, 0)) != OK) { 236 rpub->sys_flags &= ~SF_USE_REPL; 237 return r; 238 } 239 240 return OK; 241 } 242 243 /*===========================================================================* 244 * do_unclone * 245 *===========================================================================*/ 246 int do_unclone(message *m_ptr) 247 { 248 struct rproc *rp; 249 struct rprocpub *rpub; 250 int s, r; 251 char label[RS_MAX_LABEL_LEN]; 252 253 /* Copy label. */ 254 s = copy_label(m_ptr->m_source, m_ptr->m_rs_req.addr, 255 m_ptr->m_rs_req.len, label, sizeof(label)); 256 if(s != OK) { 257 return s; 258 } 259 260 /* Lookup slot by label. */ 261 rp = lookup_slot_by_label(label); 262 if(!rp) { 263 if(rs_verbose) 264 printf("RS: do_unclone: service '%s' not found\n", label); 265 return(ESRCH); 266 } 267 rpub = rp->r_pub; 268 269 /* Check if the call can be allowed. */ 270 if((r = check_call_permission(m_ptr->m_source, RS_UNCLONE, rp)) != OK) 271 return r; 272 273 /* Don't unclone if no replica is available. */ 274 if(!(rpub->sys_flags & SF_USE_REPL)) { 275 return ENOENT; 276 } 277 278 /* Unclone the service as requested. */ 279 rpub->sys_flags &= ~SF_USE_REPL; 280 if(rp->r_next_rp) { 281 cleanup_service_now(rp->r_next_rp); 282 rp->r_next_rp = NULL; 283 } 284 285 return OK; 286 } 287 288 /*===========================================================================* 289 * do_edit * 290 *===========================================================================*/ 291 int do_edit(message *m_ptr) 292 { 293 struct rproc *rp; 294 struct rprocpub *rpub; 295 struct rs_start rs_start; 296 int r; 297 char label[RS_MAX_LABEL_LEN]; 298 299 /* Copy the request structure. */ 300 r = copy_rs_start(m_ptr->m_source, m_ptr->m_rs_req.addr, &rs_start); 301 if (r != OK) { 302 return r; 303 } 304 305 /* Copy label. */ 306 r = copy_label(m_ptr->m_source, rs_start.rss_label.l_addr, 307 rs_start.rss_label.l_len, label, sizeof(label)); 308 if(r != OK) { 309 return r; 310 } 311 312 /* Lookup slot by label. */ 313 rp = lookup_slot_by_label(label); 314 if(!rp) { 315 if(rs_verbose) 316 printf("RS: do_edit: service '%s' not found\n", label); 317 return ESRCH; 318 } 319 rpub = rp->r_pub; 320 321 /* Check if the call can be allowed. */ 322 if((r = check_call_permission(m_ptr->m_source, RS_EDIT, rp)) != OK) 323 return r; 324 325 if(rs_verbose) 326 printf("RS: %s edits settings\n", srv_to_string(rp)); 327 328 /* Synch the privilege structure with the kernel. */ 329 if ((r = sys_getpriv(&rp->r_priv, rpub->endpoint)) != OK) { 330 printf("RS: do_edit: unable to synch privilege structure: %d\n", r); 331 return r; 332 } 333 334 /* Tell scheduler this process is finished */ 335 if ((r = sched_stop(rp->r_scheduler, rpub->endpoint)) != OK) { 336 printf("RS: do_edit: scheduler won't give up process: %d\n", r); 337 return r; 338 } 339 340 /* Edit the slot as requested. */ 341 if((r = edit_slot(rp, &rs_start, m_ptr->m_source)) != OK) { 342 printf("RS: do_edit: unable to edit the existing slot: %d\n", r); 343 return r; 344 } 345 346 /* Update privilege structure. */ 347 r = sys_privctl(rpub->endpoint, SYS_PRIV_UPDATE_SYS, &rp->r_priv); 348 if(r != OK) { 349 printf("RS: do_edit: unable to update privilege structure: %d\n", r); 350 return r; 351 } 352 353 /* Update VM calls. */ 354 if ((r = vm_set_priv(rpub->endpoint, &rpub->vm_call_mask[0], 355 !!(rp->r_priv.s_flags & SYS_PROC))) != OK) { 356 printf("RS: do_edit: failed: %d\n", r); 357 return r; 358 } 359 360 /* Reinitialize scheduling. */ 361 if ((r = sched_init_proc(rp)) != OK) { 362 printf("RS: do_edit: unable to reinitialize scheduling: %d\n", r); 363 return r; 364 } 365 366 /* Cleanup old replicas and create a new one, if necessary. */ 367 if(rpub->sys_flags & SF_USE_REPL) { 368 if(rp->r_next_rp) { 369 cleanup_service(rp->r_next_rp); 370 rp->r_next_rp = NULL; 371 } 372 if ((r = clone_service(rp, RST_SYS_PROC, 0)) != OK) { 373 printf("RS: warning: unable to clone %s\n", srv_to_string(rp)); 374 } 375 } 376 377 return OK; 378 } 379 380 /*===========================================================================* 381 * do_refresh * 382 *===========================================================================*/ 383 int do_refresh(message *m_ptr) 384 { 385 register struct rproc *rp; 386 int s; 387 char label[RS_MAX_LABEL_LEN]; 388 389 /* Copy label. */ 390 s = copy_label(m_ptr->m_source, m_ptr->m_rs_req.addr, 391 m_ptr->m_rs_req.len, label, sizeof(label)); 392 if(s != OK) { 393 return s; 394 } 395 396 /* Lookup slot by label. */ 397 rp = lookup_slot_by_label(label); 398 if(!rp) { 399 if(rs_verbose) 400 printf("RS: do_refresh: service '%s' not found\n", label); 401 return(ESRCH); 402 } 403 404 /* Check if the call can be allowed. */ 405 if((s = check_call_permission(m_ptr->m_source, RS_REFRESH, rp)) != OK) 406 return s; 407 408 /* Refresh service. */ 409 if(rs_verbose) 410 printf("RS: %s refreshing\n", srv_to_string(rp)); 411 stop_service(rp,RS_REFRESHING); 412 413 /* Late reply - send a reply when refresh completes. */ 414 rp->r_flags |= RS_LATEREPLY; 415 rp->r_caller = m_ptr->m_source; 416 rp->r_caller_request = RS_REFRESH; 417 418 return EDONTREPLY; 419 } 420 421 /*===========================================================================* 422 * do_shutdown * 423 *===========================================================================*/ 424 int do_shutdown(message *m_ptr) 425 { 426 int slot_nr; 427 struct rproc *rp; 428 int r; 429 430 /* Check if the call can be allowed. */ 431 if (m_ptr != NULL) { 432 if((r = check_call_permission(m_ptr->m_source, RS_SHUTDOWN, NULL)) != OK) 433 return r; 434 } 435 436 if(rs_verbose) 437 printf("RS: shutting down...\n"); 438 439 /* Set flag to tell RS we are shutting down. */ 440 shutting_down = TRUE; 441 442 /* Don't restart dead services. */ 443 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) { 444 rp = &rproc[slot_nr]; 445 if (rp->r_flags & RS_IN_USE) { 446 rp->r_flags |= RS_EXITING; 447 } 448 } 449 return(OK); 450 } 451 452 /*===========================================================================* 453 * do_init_ready * 454 *===========================================================================*/ 455 int do_init_ready(message *m_ptr) 456 { 457 int who_p; 458 message m; 459 struct rproc *rp, *new_rp; 460 struct rprocpub *rpub; 461 int result; 462 int r; 463 464 who_p = _ENDPOINT_P(m_ptr->m_source); 465 result = m_ptr->m_rs_init.result; 466 467 rp = rproc_ptr[who_p]; 468 rpub = rp->r_pub; 469 470 /* Make sure the originating service was requested to initialize. */ 471 if(! (rp->r_flags & RS_INITIALIZING) ) { 472 if(rs_verbose) 473 printf("RS: do_init_ready: got unexpected init ready msg from %d\n", 474 m_ptr->m_source); 475 return EINVAL; 476 } 477 478 /* Check if something went wrong and the service failed to init. 479 * In that case, kill the service. 480 */ 481 if(result != OK) { 482 if(rs_verbose) 483 printf("RS: %s initialization error: %s\n", srv_to_string(rp), 484 init_strerror(result)); 485 if (result == ERESTART && !SRV_IS_UPDATING(rp)) 486 rp->r_flags |= RS_REINCARNATE; 487 crash_service(rp); /* simulate crash */ 488 rp->r_init_err = result; 489 return EDONTREPLY; 490 } 491 492 if(rs_verbose) 493 printf("RS: %s initialized\n", srv_to_string(rp)); 494 495 /* If updating, check if there is no service to update left. In that case, 496 * end the update process. If VM has completed initialization as part of 497 * multi-component live update, let the other services under update run now. 498 */ 499 if(SRV_IS_UPDATING(rp)) { 500 rupdate.num_init_ready_pending--; 501 rp->r_flags |= RS_INIT_DONE; 502 if(rupdate.num_init_ready_pending == 0) { 503 printf("RS: update succeeded\n"); 504 end_update(OK, RS_REPLY); 505 } 506 } 507 else { 508 /* Mark the slot as no longer initializing. */ 509 rp->r_flags &= ~RS_INITIALIZING; 510 rp->r_check_tm = 0; 511 rp->r_alive_tm = getticks(); 512 513 /* Reply and unblock the service before doing anything else. */ 514 m.m_type = OK; 515 reply(rpub->endpoint, rp, &m); 516 517 /* Finalize initialization. */ 518 end_srv_init(rp); 519 } 520 521 return EDONTREPLY; 522 } 523 524 /*===========================================================================* 525 * do_update * 526 *===========================================================================*/ 527 int do_update(message *m_ptr) 528 { 529 struct rproc *rp; 530 struct rproc *trg_rp; 531 struct rproc *new_rp; 532 struct rprocpub *rpub; 533 struct rprocupd *rpupd; 534 struct rs_start rs_start; 535 int noblock, do_self_update, force_self_update, batch_mode, prepare_only; 536 int s; 537 char label[RS_MAX_LABEL_LEN]; 538 int prepare_state, prepare_maxtime; 539 endpoint_t state_endpoint; 540 int lu_flags = 0; 541 int init_flags = 0; 542 int allow_retries = 0; 543 544 /* Copy the request structure. */ 545 s = copy_rs_start(m_ptr->m_source, m_ptr->m_rs_req.addr, &rs_start); 546 if (s != OK) { 547 return s; 548 } 549 550 /* Copy label. */ 551 s = copy_label(m_ptr->m_source, rs_start.rss_label.l_addr, 552 rs_start.rss_label.l_len, label, sizeof(label)); 553 if(s != OK) { 554 return s; 555 } 556 557 /* Lookup slot by label. */ 558 rp = lookup_slot_by_label(label); 559 if(!rp) { 560 if(rs_verbose) 561 printf("RS: do_update: service '%s' not found\n", label); 562 return ESRCH; 563 } 564 rpub = rp->r_pub; 565 566 /* Check flags. */ 567 noblock = (rs_start.rss_flags & RSS_NOBLOCK); 568 do_self_update = (rs_start.rss_flags & RSS_SELF_LU); 569 force_self_update = (rs_start.rss_flags & RSS_FORCE_SELF_LU); 570 batch_mode = (rs_start.rss_flags & RSS_BATCH); 571 prepare_only = (rs_start.rss_flags & RSS_PREPARE_ONLY_LU); 572 if(do_self_update || force_self_update) { 573 lu_flags |= SEF_LU_SELF; 574 } 575 if(prepare_only) { 576 lu_flags |= SEF_LU_PREPARE_ONLY; 577 } 578 if(rs_start.rss_flags & RSS_ASR_LU) { 579 lu_flags |= SEF_LU_ASR; 580 } 581 if(!prepare_only && (rs_start.rss_flags & RSS_DETACH)) { 582 lu_flags |= SEF_LU_DETACHED; 583 } 584 if(rs_start.rss_map_prealloc_bytes <= 0 585 && rpub->endpoint == VM_PROC_NR 586 && (((lu_flags & (SEF_LU_SELF|SEF_LU_ASR)) != SEF_LU_SELF) || rs_start.rss_flags & RSS_FORCE_INIT_ST) 587 && RS_VM_DEFAULT_MAP_PREALLOC_LEN > 0) { 588 /* Give VM some mmapped regions by default on non-identical updates.*/ 589 rs_start.rss_map_prealloc_bytes = RS_VM_DEFAULT_MAP_PREALLOC_LEN; 590 if(rs_verbose) 591 printf("RS: %s gets %ld default mmap bytes\n", srv_to_string(rp), 592 rs_start.rss_map_prealloc_bytes); 593 } 594 if((rs_start.rss_flags & RSS_NOMMAP_LU) || rs_start.rss_map_prealloc_bytes) { 595 /* Don't inherit mmapped regions at update time if requested or if 596 * mmap preallocation is used. 597 */ 598 lu_flags |= SEF_LU_NOMMAP; 599 } 600 if(rs_start.rss_flags & RSS_FORCE_INIT_CRASH) { 601 init_flags |= SEF_INIT_CRASH; 602 } 603 if(rs_start.rss_flags & RSS_FORCE_INIT_FAIL) { 604 init_flags |= SEF_INIT_FAIL; 605 } 606 if(rs_start.rss_flags & RSS_FORCE_INIT_TIMEOUT) { 607 init_flags |= SEF_INIT_TIMEOUT; 608 } 609 if(rs_start.rss_flags & RSS_FORCE_INIT_DEFCB) { 610 init_flags |= SEF_INIT_DEFCB; 611 } 612 if(rs_start.rss_flags & RSS_FORCE_INIT_ST) { 613 init_flags |= SEF_INIT_ST; 614 } 615 init_flags |= lu_flags; 616 617 /* Lookup target label (if any). */ 618 trg_rp = NULL; 619 state_endpoint = NONE; 620 if(rs_start.rss_trg_label.l_len > 0) { 621 s = copy_label(m_ptr->m_source, rs_start.rss_trg_label.l_addr, 622 rs_start.rss_trg_label.l_len, label, sizeof(label)); 623 if(s != OK) { 624 return s; 625 } 626 trg_rp = lookup_slot_by_label(label); 627 if(!trg_rp) { 628 if(rs_verbose) 629 printf("RS: do_update: target service '%s' not found\n", label); 630 return ESRCH; 631 } 632 state_endpoint = trg_rp->r_pub->endpoint; 633 } 634 635 /* Check if the call can be allowed. */ 636 if((s = check_call_permission(m_ptr->m_source, RS_UPDATE, rp)) != OK) 637 return s; 638 639 /* Retrieve live update state. */ 640 prepare_state = m_ptr->m_rs_update.state; 641 if(prepare_state == SEF_LU_STATE_NULL) { 642 return(EINVAL); 643 } 644 645 /* Retrieve prepare max time. */ 646 prepare_maxtime = m_ptr->m_rs_update.prepare_maxtime; 647 if(prepare_maxtime == 0) { 648 prepare_maxtime = RS_DEFAULT_PREPARE_MAXTIME; 649 } 650 651 /* Make sure we are not already updating. */ 652 if(RUPDATE_IS_UPDATING()) { 653 printf("RS: an update is already in progress\n"); 654 return EBUSY; 655 } 656 657 /* If an update is already scheduled, check constraints. */ 658 if(RUPDATE_IS_UPD_SCHEDULED()) { 659 if(!batch_mode) { 660 printf("RS: an update is already scheduled, cannot start a new one\n"); 661 return EBUSY; 662 } 663 if(SRV_IS_UPD_SCHEDULED(rp)) { 664 printf("RS: the specified process is already part of the currently scheduled update\n"); 665 return EINVAL; 666 } 667 } 668 669 /* Prepare-only update for VM, PM, and VFS is only supported with an unreachable state. */ 670 if(prepare_only 671 && (rp->r_pub->endpoint == VM_PROC_NR || rp->r_pub->endpoint == PM_PROC_NR || rp->r_pub->endpoint == VFS_PROC_NR)) { 672 if(prepare_state != SEF_LU_STATE_UNREACHABLE) { 673 printf("RS: prepare-only update for VM, PM and VFS is only supported with state %d\n", SEF_LU_STATE_UNREACHABLE); 674 return EINVAL; 675 } 676 } 677 678 /* Prepare-only update for RS is not supported. */ 679 if(prepare_only && rp->r_pub->endpoint == RS_PROC_NR) { 680 printf("RS: prepare-only update for RS is not supported\n"); 681 return EINVAL; 682 } 683 684 /* Initialize update descriptor. */ 685 rpupd = &rp->r_upd; 686 rupdate_upd_init(rpupd, rp); 687 rpupd->lu_flags |= lu_flags; 688 rpupd->init_flags |= init_flags; 689 rupdate_set_new_upd_flags(rpupd); 690 691 /* A self update live updates a service instance into a replica, a regular 692 * update live updates a service instance into a new version, as specified 693 * by the given binary. 694 */ 695 if(!prepare_only) { 696 if(do_self_update) { 697 if(rs_verbose) 698 printf("RS: %s requested to perform self update\n", srv_to_string(rp)); 699 700 /* Clone the system service and use the replica as the new version. */ 701 s = clone_service(rp, LU_SYS_PROC, rpupd->init_flags); 702 if(s != OK) { 703 printf("RS: do_update: unable to clone service: %d\n", s); 704 return s; 705 } 706 new_rp = rp->r_new_rp; 707 } 708 else { 709 if(rs_verbose) 710 printf("RS: %s requested to perform %s update\n", srv_to_string(rp), 711 force_self_update ? "(forced) self" : "regular"); 712 713 /* Allocate a system service slot for the new version. */ 714 s = alloc_slot(&new_rp); 715 if(s != OK) { 716 printf("RS: do_update: unable to allocate a new slot: %d\n", s); 717 return s; 718 } 719 720 /* Initialize the slot as requested. */ 721 s = init_slot(new_rp, &rs_start, m_ptr->m_source); 722 if(s != OK) { 723 printf("RS: do_update: unable to init the new slot: %d\n", s); 724 return s; 725 } 726 727 /* Let the new version inherit defaults from the old one. */ 728 inherit_service_defaults(rp, new_rp); 729 730 /* Link the two versions. */ 731 rp->r_new_rp = new_rp; 732 new_rp->r_old_rp = rp; 733 734 /* Create new version of the service but don't let it run. */ 735 new_rp->r_priv.s_flags |= LU_SYS_PROC; 736 new_rp->r_priv.s_init_flags |= rpupd->init_flags; 737 s = create_service(new_rp); 738 if(s != OK) { 739 printf("RS: do_update: unable to create a new service: %d\n", s); 740 return s; 741 } 742 } 743 744 /* Set default state endpoint. */ 745 if(state_endpoint == NONE) { 746 state_endpoint = new_rp->r_pub->endpoint; 747 } 748 749 /* If RS is updating, set up signal managers for the new instance. 750 * The current RS instance must be made the backup signal manager to 751 * support rollback in case of a crash during initialization. 752 */ 753 if(rp->r_priv.s_flags & ROOT_SYS_PROC) { 754 s = update_sig_mgrs(new_rp, SELF, new_rp->r_pub->endpoint); 755 if(s != OK) { 756 cleanup_service(new_rp); 757 return s; 758 } 759 } 760 761 /* Preallocate heap regions if requested. */ 762 if(rs_start.rss_heap_prealloc_bytes < 0) { 763 rs_start.rss_heap_prealloc_bytes = 0; 764 } 765 if(rs_start.rss_heap_prealloc_bytes) { 766 size_t len; 767 if(rs_verbose) 768 printf("RS: %s preallocating %ld heap bytes\n", srv_to_string(new_rp), 769 rs_start.rss_heap_prealloc_bytes); 770 771 len = rs_start.rss_heap_prealloc_bytes; 772 s = vm_memctl(new_rp->r_pub->endpoint, VM_RS_MEM_HEAP_PREALLOC, 773 NULL, &len); 774 if(s != OK) { 775 printf("vm_memctl(VM_RS_MEM_HEAP_PREALLOC) failed: %d\n", s); 776 cleanup_service(new_rp); 777 return s; 778 } 779 if(rp->r_priv.s_flags & ROOT_SYS_PROC) { 780 vm_memctl(new_rp->r_pub->endpoint, VM_RS_MEM_PIN, 0, 0); 781 } 782 } 783 784 /* Preallocate mmapped regions if requested. */ 785 if(rs_start.rss_map_prealloc_bytes < 0) { 786 rs_start.rss_map_prealloc_bytes = 0; 787 } 788 if(rs_start.rss_map_prealloc_bytes) { 789 void *addr = NULL; 790 if(rs_verbose) 791 printf("RS: %s preallocating %ld mmap bytes\n", srv_to_string(new_rp), 792 rs_start.rss_map_prealloc_bytes); 793 794 new_rp->r_map_prealloc_len = rs_start.rss_map_prealloc_bytes; 795 s = vm_memctl(new_rp->r_pub->endpoint, VM_RS_MEM_MAP_PREALLOC, 796 &addr, &new_rp->r_map_prealloc_len); 797 if(s != OK) { 798 printf("vm_memctl(VM_RS_MEM_MAP_PREALLOC) failed: %d\n", s); 799 cleanup_service(new_rp); 800 return s; 801 } 802 new_rp->r_map_prealloc_addr = (vir_bytes) addr; 803 } 804 } 805 806 /* Process state data. */ 807 s = init_state_data(m_ptr->m_source, prepare_state, &rs_start.rss_state_data, &rpupd->prepare_state_data); 808 if(s != OK) { 809 rupdate_upd_clear(rpupd); 810 return s; 811 } 812 813 /* Create update grants. */ 814 if(rpupd->prepare_state_data.size > 0) { 815 struct rs_state_data *state_data = &rpupd->prepare_state_data; 816 rpupd->prepare_state_data_gid = cpf_grant_direct(rpub->endpoint, (vir_bytes) state_data, 817 state_data->size, CPF_READ); 818 if(rpupd->prepare_state_data_gid == GRANT_INVALID) { 819 rupdate_upd_clear(rpupd); 820 return ENOMEM; 821 } 822 state_data->ipcf_els_gid = GRANT_INVALID; 823 if(state_data->ipcf_els) { 824 state_data->ipcf_els_gid = (int) cpf_grant_direct(rpub->endpoint, (vir_bytes) state_data->ipcf_els, 825 state_data->ipcf_els_size, CPF_READ); 826 if(state_data->ipcf_els_gid == GRANT_INVALID) { 827 rupdate_upd_clear(rpupd); 828 return ENOMEM; 829 } 830 } 831 state_data->eval_gid = GRANT_INVALID; 832 if(state_data->eval_addr) { 833 state_data->eval_gid = (int) cpf_grant_direct(rpub->endpoint, (vir_bytes) state_data->eval_addr, 834 state_data->eval_len, CPF_READ); 835 if(state_data->eval_gid == GRANT_INVALID) { 836 rupdate_upd_clear(rpupd); 837 return ENOMEM; 838 } 839 } 840 } 841 842 /* Fill the new update descriptor and add it to the update chain. */ 843 rpupd->prepare_state = prepare_state; 844 rpupd->state_endpoint = state_endpoint; 845 rpupd->prepare_tm = getticks(); 846 rpupd->prepare_maxtime = prepare_maxtime; 847 rupdate_add_upd(rpupd); 848 849 if(rs_verbose) 850 printf("RS: %s scheduled for %s\n", srv_to_string(rp), srv_upd_to_string(rpupd)); 851 852 /* If batch mode, reply immediately. More services to update will follow. */ 853 if(batch_mode) { 854 return OK; 855 } 856 857 /* Start preparing for the update process. */ 858 s = start_update_prepare(allow_retries); 859 if(s == ESRCH) { 860 /* No process left in the update chain. We are done already. */ 861 return OK; 862 } 863 if(s != OK) { 864 return s; 865 } 866 867 /* Unblock the caller immediately if requested. */ 868 if(noblock) { 869 return OK; 870 } 871 872 /* Otherwise, send a reply when the new version completes initialization. */ 873 rupdate.last_rpupd->rp->r_flags |= RS_LATEREPLY; 874 rupdate.last_rpupd->rp->r_caller = m_ptr->m_source; 875 rupdate.last_rpupd->rp->r_caller_request = RS_UPDATE; 876 877 return EDONTREPLY; 878 } 879 880 /*===========================================================================* 881 * do_upd_ready * 882 *===========================================================================*/ 883 int do_upd_ready(message *m_ptr) 884 { 885 struct rproc *rp; 886 struct rprocupd *prev_rpupd, *rpupd; 887 int who_p; 888 int result; 889 int is_rs; 890 int i; 891 892 who_p = _ENDPOINT_P(m_ptr->m_source); 893 rp = rproc_ptr[who_p]; 894 result = m_ptr->m_rs_update.result; 895 896 /* Make sure the originating service was requested to prepare for update. */ 897 rpupd = rupdate.curr_rpupd; 898 if(!rpupd || rp != rpupd->rp || RUPDATE_IS_INITIALIZING()) { 899 if(rs_verbose) 900 printf("RS: %s sent late/unexpected update ready msg\n", 901 srv_to_string(rp)); 902 return EINVAL; 903 } 904 rp->r_flags |= RS_PREPARE_DONE; 905 906 /* Check if something went wrong and the service failed to prepare 907 * for the update. In that case, end the update process. The old version will 908 * be replied to and continue executing. 909 */ 910 if(result != OK) { 911 printf("RS: update failed: %s\n", lu_strerror(result)); 912 end_update(result, RS_REPLY); 913 914 return EDONTREPLY; 915 } 916 917 if(rs_verbose) 918 printf("RS: %s ready to update\n", srv_to_string(rp)); 919 920 /* If this is a multi-component update and this is not the last service 921 * in the update, request the next process to update. 922 */ 923 if(start_update_prepare_next() != NULL) { 924 return EDONTREPLY; 925 } 926 927 /* Now perform the update and request each new instance to initialize. */ 928 start_update(); 929 930 return EDONTREPLY; 931 } 932 933 /*===========================================================================* 934 * do_period * 935 *===========================================================================*/ 936 void do_period(m_ptr) 937 message *m_ptr; 938 { 939 register struct rproc *rp; 940 register struct rprocpub *rpub; 941 clock_t now = m_ptr->m_notify.timestamp; 942 int s; 943 long period; 944 945 /* If an update is in progress, check its status. */ 946 if(RUPDATE_IS_UPDATING() && !RUPDATE_IS_INITIALIZING()) { 947 update_period(m_ptr); 948 } 949 950 /* Search system services table. Only check slots that are in use and not 951 * updating. 952 */ 953 for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) { 954 rpub = rp->r_pub; 955 956 if ((rp->r_flags & RS_ACTIVE) && (!SRV_IS_UPDATING(rp) || ((rp->r_flags & (RS_INITIALIZING|RS_INIT_DONE|RS_INIT_PENDING)) == RS_INITIALIZING))) { 957 958 /* Compute period. */ 959 period = rp->r_period; 960 if(rp->r_flags & RS_INITIALIZING) { 961 period = SRV_IS_UPDATING(rp) ? UPD_INIT_MAXTIME(&rp->r_upd) : RS_INIT_T; 962 } 963 964 /* If the service is to be revived (because it repeatedly exited, 965 * and was not directly restarted), the binary backoff field is 966 * greater than zero. 967 */ 968 if (rp->r_backoff > 0) { 969 rp->r_backoff -= 1; 970 if (rp->r_backoff == 0) { 971 restart_service(rp); 972 } 973 } 974 975 /* If the service was signaled with a SIGTERM and fails to respond, 976 * kill the system service with a SIGKILL signal. 977 */ 978 else if (rp->r_stop_tm > 0 && now - rp->r_stop_tm > 2*RS_DELTA_T 979 && rp->r_pid > 0) { 980 rp->r_stop_tm = 0; 981 crash_service(rp); /* simulate crash */ 982 } 983 984 /* There seems to be no special conditions. If the service has a 985 * period assigned check its status. 986 */ 987 else if (period > 0) { 988 989 /* Check if an answer to a status request is still pending. If 990 * the service didn't respond within time, kill it to simulate 991 * a crash. The failure will be detected and the service will 992 * be restarted automatically. Give the service a free pass if 993 * somebody is initializing. There may be some weird dependencies 994 * if another service is, for example, restarting at the same 995 * time. 996 */ 997 if (rp->r_alive_tm < rp->r_check_tm) { 998 if (now - rp->r_alive_tm > 2*period && 999 rp->r_pid > 0 && !(rp->r_flags & RS_NOPINGREPLY)) { 1000 struct rproc *rp2; 1001 int init_flag; 1002 if(rs_verbose) 1003 printf("RS: %s reported late\n", srv_to_string(rp)); 1004 init_flag = rp->r_flags & RS_INITIALIZING; 1005 rp->r_flags &= ~RS_INITIALIZING; 1006 rp2 = lookup_slot_by_flags(RS_INITIALIZING); 1007 rp->r_flags |= init_flag; 1008 if(rp2 != NULL && !SRV_IS_UPDATING(rp)) { 1009 /* Skip for now. */ 1010 if(rs_verbose) 1011 printf("RS: %s gets a free pass\n", 1012 srv_to_string(rp)); 1013 rp->r_alive_tm = now; 1014 rp->r_check_tm = now+1; 1015 continue; 1016 } 1017 rp->r_flags |= RS_NOPINGREPLY; 1018 crash_service(rp); /* simulate crash */ 1019 if(rp->r_flags & RS_INITIALIZING) { 1020 rp->r_init_err = EINTR; 1021 } 1022 } 1023 } 1024 1025 /* No answer pending. Check if a period expired since the last 1026 * check and, if so request the system service's status. 1027 */ 1028 else if (now - rp->r_check_tm > rp->r_period) { 1029 ipc_notify(rpub->endpoint); /* request status */ 1030 rp->r_check_tm = now; /* mark time */ 1031 } 1032 } 1033 } 1034 } 1035 1036 /* Reschedule a synchronous alarm for the next period. */ 1037 if (OK != (s=sys_setalarm(RS_DELTA_T, 0))) 1038 panic("couldn't set alarm: %d", s); 1039 } 1040 1041 /*===========================================================================* 1042 * do_sigchld * 1043 *===========================================================================*/ 1044 void do_sigchld() 1045 { 1046 /* PM informed us that there are dead children to cleanup. Go get them. */ 1047 pid_t pid; 1048 int status; 1049 struct rproc *rp; 1050 struct rproc **rps; 1051 int i, nr_rps, found; 1052 1053 if(rs_verbose) 1054 printf("RS: got SIGCHLD signal, cleaning up dead children\n"); 1055 1056 while ( (pid = waitpid(-1, &status, WNOHANG)) != 0 ) { 1057 rp = lookup_slot_by_pid(pid); 1058 if(rp != NULL) { 1059 1060 if(rs_verbose) 1061 printf("RS: %s exited via another signal manager\n", 1062 srv_to_string(rp)); 1063 1064 /* The slot is still there. This means RS is not the signal 1065 * manager assigned to the process. Ignore the event but 1066 * free slots for all the service instances and send a late 1067 * reply if necessary. 1068 */ 1069 found = 0; 1070 get_service_instances(rp, &rps, &nr_rps); 1071 for(i=0;i<nr_rps;i++) { 1072 if(SRV_IS_UPDATING(rps[i])) { 1073 rps[i]->r_flags &= ~(RS_UPDATING|RS_PREPARE_DONE|RS_INIT_DONE|RS_INIT_PENDING); 1074 found = 1; 1075 } 1076 free_slot(rps[i]); 1077 } 1078 if(found) { 1079 rupdate_clear_upds(); 1080 } 1081 } 1082 } 1083 } 1084 1085 /*===========================================================================* 1086 * do_getsysinfo * 1087 *===========================================================================*/ 1088 int do_getsysinfo(m_ptr) 1089 message *m_ptr; 1090 { 1091 vir_bytes src_addr, dst_addr; 1092 int dst_proc; 1093 size_t size, len; 1094 int s; 1095 1096 /* Check if the call can be allowed. */ 1097 if((s = check_call_permission(m_ptr->m_source, 0, NULL)) != OK) 1098 return s; 1099 1100 dst_proc = m_ptr->m_source; 1101 dst_addr = m_ptr->m_lsys_getsysinfo.where; 1102 size = m_ptr->m_lsys_getsysinfo.size; 1103 1104 switch(m_ptr->m_lsys_getsysinfo.what) { 1105 case SI_PROC_TAB: 1106 src_addr = (vir_bytes) rproc; 1107 len = sizeof(struct rproc) * NR_SYS_PROCS; 1108 break; 1109 case SI_PROCALL_TAB: 1110 /* Copy out both tables, one after the other. */ 1111 src_addr = (vir_bytes) rproc; 1112 len = sizeof(struct rproc) * NR_SYS_PROCS; 1113 if (len > size) 1114 return EINVAL; 1115 if ((s = sys_datacopy(SELF, src_addr, dst_proc, dst_addr, len)) != OK) 1116 return s; 1117 dst_addr += len; 1118 size -= len; 1119 /* FALLTHROUGH */ 1120 case SI_PROCPUB_TAB: 1121 src_addr = (vir_bytes) rprocpub; 1122 len = sizeof(struct rprocpub) * NR_SYS_PROCS; 1123 break; 1124 default: 1125 return(EINVAL); 1126 } 1127 1128 if (len != size) 1129 return(EINVAL); 1130 1131 return sys_datacopy(SELF, src_addr, dst_proc, dst_addr, len); 1132 } 1133 1134 /*===========================================================================* 1135 * do_lookup * 1136 *===========================================================================*/ 1137 int do_lookup(m_ptr) 1138 message *m_ptr; 1139 { 1140 static char namebuf[100]; 1141 int len, r; 1142 struct rproc *rrp; 1143 struct rprocpub *rrpub; 1144 1145 len = m_ptr->m_rs_req.name_len; 1146 1147 if(len < 2 || len >= sizeof(namebuf)) { 1148 printf("RS: len too weird (%d)\n", len); 1149 return EINVAL; 1150 } 1151 1152 if((r=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->m_rs_req.name, 1153 SELF, (vir_bytes) namebuf, len)) != OK) { 1154 printf("RS: name copy failed\n"); 1155 return r; 1156 1157 } 1158 1159 namebuf[len] = '\0'; 1160 1161 rrp = lookup_slot_by_label(namebuf); 1162 if(!rrp) { 1163 return ESRCH; 1164 } 1165 rrpub = rrp->r_pub; 1166 m_ptr->m_rs_req.endpoint = rrpub->endpoint; 1167 1168 return OK; 1169 } 1170 1171 /*===========================================================================* 1172 * do_sysctl * 1173 *===========================================================================*/ 1174 int do_sysctl(message *m_ptr) 1175 { 1176 int request_type = m_ptr->m_rs_req.subtype; 1177 int r, allow_retries = 1; 1178 switch(request_type) { 1179 case RS_SYSCTL_SRV_STATUS: 1180 print_services_status(); 1181 break; 1182 case RS_SYSCTL_UPD_START: 1183 case RS_SYSCTL_UPD_RUN: 1184 r = start_update_prepare(allow_retries); 1185 print_update_status(); 1186 if(r != OK) { 1187 if(r == ESRCH) { 1188 /* We are done already. */ 1189 r = OK; 1190 } 1191 return r; 1192 } 1193 if(request_type == RS_SYSCTL_UPD_START) { 1194 return OK; 1195 } 1196 /* Send a reply when done. */ 1197 rupdate.last_rpupd->rp->r_flags |= RS_LATEREPLY; 1198 rupdate.last_rpupd->rp->r_caller = m_ptr->m_source; 1199 rupdate.last_rpupd->rp->r_caller_request = RS_UPDATE; 1200 return EDONTREPLY; 1201 break; 1202 case RS_SYSCTL_UPD_STOP: 1203 r = abort_update_proc(EINTR); 1204 print_update_status(); 1205 return r; 1206 break; 1207 case RS_SYSCTL_UPD_STATUS: 1208 print_update_status(); 1209 break; 1210 default: 1211 printf("RS: bad sysctl type\n"); 1212 return EINVAL; 1213 break; 1214 } 1215 1216 return OK; 1217 } 1218 1219 /*===========================================================================* 1220 * do_fi * 1221 *===========================================================================*/ 1222 int do_fi(message *m_ptr) 1223 { 1224 struct rproc *rp; 1225 struct rprocpub *rpub; 1226 int s, r; 1227 char label[RS_MAX_LABEL_LEN]; 1228 1229 /* Copy label. */ 1230 s = copy_label(m_ptr->m_source, m_ptr->m_rs_req.addr, 1231 m_ptr->m_rs_req.len, label, sizeof(label)); 1232 if(s != OK) { 1233 return s; 1234 } 1235 1236 /* Lookup slot by label. */ 1237 rp = lookup_slot_by_label(label); 1238 if(!rp) { 1239 if(rs_verbose) 1240 printf("RS: do_fi: service '%s' not found\n", label); 1241 return(ESRCH); 1242 } 1243 rpub = rp->r_pub; 1244 1245 /* Check if the call can be allowed. */ 1246 if((r = check_call_permission(m_ptr->m_source, RS_FI, rp)) != OK) 1247 return r; 1248 1249 /* Inject fault into the service as requested. */ 1250 s = fi_service(rp); 1251 1252 return s; 1253 } 1254 1255 /*===========================================================================* 1256 * check_request * 1257 *===========================================================================*/ 1258 static int check_request(struct rs_start *rs_start) 1259 { 1260 /* Verify scheduling parameters */ 1261 if (rs_start->rss_scheduler != KERNEL && 1262 (rs_start->rss_scheduler < 0 || 1263 rs_start->rss_scheduler > LAST_SPECIAL_PROC_NR)) { 1264 printf("RS: check_request: invalid scheduler %d\n", 1265 rs_start->rss_scheduler); 1266 return EINVAL; 1267 } 1268 if (rs_start->rss_priority >= NR_SCHED_QUEUES) { 1269 printf("RS: check_request: priority %u out of range\n", 1270 rs_start->rss_priority); 1271 return EINVAL; 1272 } 1273 if (rs_start->rss_quantum <= 0) { 1274 printf("RS: check_request: quantum %u out of range\n", 1275 rs_start->rss_quantum); 1276 return EINVAL; 1277 } 1278 1279 if (rs_start->rss_cpu == RS_CPU_BSP) 1280 rs_start->rss_cpu = machine.bsp_id; 1281 else if (rs_start->rss_cpu == RS_CPU_DEFAULT) { 1282 /* keep the default value */ 1283 } else if (rs_start->rss_cpu < 0) 1284 return EINVAL; 1285 else if (rs_start->rss_cpu > machine.processors_count) { 1286 printf("RS: cpu number %d out of range 0-%d, using BSP\n", 1287 rs_start->rss_cpu, machine.processors_count); 1288 rs_start->rss_cpu = machine.bsp_id; 1289 } 1290 1291 /* Verify signal manager. */ 1292 if (rs_start->rss_sigmgr != SELF && 1293 (rs_start->rss_sigmgr < 0 || 1294 rs_start->rss_sigmgr > LAST_SPECIAL_PROC_NR)) { 1295 printf("RS: check_request: invalid signal manager %d\n", 1296 rs_start->rss_sigmgr); 1297 return EINVAL; 1298 } 1299 1300 return OK; 1301 } 1302 1303