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 getticks(&rp->r_alive_tm); 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(rs_start.rss_flags & RSS_UNSAFE_LU) { 582 lu_flags |= SEF_LU_UNSAFE; 583 } 584 if(!prepare_only && (rs_start.rss_flags & RSS_DETACH)) { 585 lu_flags |= SEF_LU_DETACHED; 586 } 587 if(rs_start.rss_map_prealloc_bytes <= 0 588 && rpub->endpoint == VM_PROC_NR 589 && (((lu_flags & (SEF_LU_SELF|SEF_LU_ASR)) != SEF_LU_SELF) || rs_start.rss_flags & RSS_FORCE_INIT_ST) 590 && RS_VM_DEFAULT_MAP_PREALLOC_LEN > 0) { 591 /* Give VM some mmapped regions by default on non-identical updates.*/ 592 rs_start.rss_map_prealloc_bytes = RS_VM_DEFAULT_MAP_PREALLOC_LEN; 593 if(rs_verbose) 594 printf("RS: %s gets %ld default mmap bytes\n", srv_to_string(rp), 595 rs_start.rss_map_prealloc_bytes); 596 } 597 if((rs_start.rss_flags & RSS_NOMMAP_LU) || rs_start.rss_map_prealloc_bytes) { 598 /* Don't inherit mmapped regions at update time if requested or if 599 * mmap preallocation is used. 600 */ 601 lu_flags |= SEF_LU_NOMMAP; 602 } 603 if(rs_start.rss_flags & RSS_FORCE_INIT_CRASH) { 604 init_flags |= SEF_INIT_CRASH; 605 } 606 if(rs_start.rss_flags & RSS_FORCE_INIT_FAIL) { 607 init_flags |= SEF_INIT_FAIL; 608 } 609 if(rs_start.rss_flags & RSS_FORCE_INIT_TIMEOUT) { 610 init_flags |= SEF_INIT_TIMEOUT; 611 } 612 if(rs_start.rss_flags & RSS_FORCE_INIT_DEFCB) { 613 init_flags |= SEF_INIT_DEFCB; 614 } 615 if(rs_start.rss_flags & RSS_FORCE_INIT_ST) { 616 init_flags |= SEF_INIT_ST; 617 } 618 init_flags |= lu_flags; 619 620 /* Lookup target label (if any). */ 621 trg_rp = NULL; 622 state_endpoint = NONE; 623 if(rs_start.rss_trg_label.l_len > 0) { 624 s = copy_label(m_ptr->m_source, rs_start.rss_trg_label.l_addr, 625 rs_start.rss_trg_label.l_len, label, sizeof(label)); 626 if(s != OK) { 627 return s; 628 } 629 trg_rp = lookup_slot_by_label(label); 630 if(!trg_rp) { 631 if(rs_verbose) 632 printf("RS: do_update: target service '%s' not found\n", label); 633 return ESRCH; 634 } 635 state_endpoint = trg_rp->r_pub->endpoint; 636 } 637 638 /* Check if the call can be allowed. */ 639 if((s = check_call_permission(m_ptr->m_source, RS_UPDATE, rp)) != OK) 640 return s; 641 642 /* Retrieve live update state. */ 643 prepare_state = m_ptr->m_rs_update.state; 644 if(prepare_state == SEF_LU_STATE_NULL) { 645 return(EINVAL); 646 } 647 648 /* Retrieve prepare max time. */ 649 prepare_maxtime = m_ptr->m_rs_update.prepare_maxtime; 650 if(prepare_maxtime == 0) { 651 prepare_maxtime = RS_DEFAULT_PREPARE_MAXTIME; 652 } 653 654 /* Make sure we are not already updating. */ 655 if(RUPDATE_IS_UPDATING()) { 656 printf("RS: an update is already in progress\n"); 657 return EBUSY; 658 } 659 660 /* If an update is already scheduled, check constraints. */ 661 if(RUPDATE_IS_UPD_SCHEDULED()) { 662 if(!batch_mode) { 663 printf("RS: an update is already scheduled, cannot start a new one\n"); 664 return EBUSY; 665 } 666 if(SRV_IS_UPD_SCHEDULED(rp)) { 667 printf("RS: the specified process is already part of the currently scheduled update\n"); 668 return EINVAL; 669 } 670 if(rupdate.last_rpupd->rp->r_pub->endpoint == RS_PROC_NR) { 671 printf("RS: RS should always be the last service to update in a multi-component update\n"); 672 return EINVAL; 673 } 674 } 675 676 /* Prepare-only update for VM, PM, and VFS is only supported with an unreachable state. */ 677 if(prepare_only 678 && (rp->r_pub->endpoint == VM_PROC_NR || rp->r_pub->endpoint == PM_PROC_NR || rp->r_pub->endpoint == VFS_PROC_NR)) { 679 if(prepare_state != SEF_LU_STATE_UNREACHABLE) { 680 printf("RS: prepare-only update for VM, PM and VFS is only supported with state %d\n", SEF_LU_STATE_UNREACHABLE); 681 return EINVAL; 682 } 683 } 684 685 /* Prepare-only update for RS is not supported. */ 686 if(prepare_only && rp->r_pub->endpoint == RS_PROC_NR) { 687 printf("RS: prepare-only update for RS is not supported\n"); 688 return EINVAL; 689 } 690 691 /* Initialize update descriptor. */ 692 rpupd = &rp->r_upd; 693 rupdate_upd_init(rpupd, rp); 694 rpupd->lu_flags |= lu_flags; 695 rpupd->init_flags |= init_flags; 696 rupdate_set_new_upd_flags(rpupd); 697 698 /* A self update live updates a service instance into a replica, a regular 699 * update live updates a service instance into a new version, as specified 700 * by the given binary. 701 */ 702 if(!prepare_only) { 703 if(do_self_update) { 704 if(rs_verbose) 705 printf("RS: %s requested to perform self update\n", srv_to_string(rp)); 706 707 /* Clone the system service and use the replica as the new version. */ 708 s = clone_service(rp, LU_SYS_PROC, rpupd->init_flags); 709 if(s != OK) { 710 printf("RS: do_update: unable to clone service: %d\n", s); 711 return s; 712 } 713 new_rp = rp->r_new_rp; 714 } 715 else { 716 if(rs_verbose) 717 printf("RS: %s requested to perform %s update\n", srv_to_string(rp), 718 force_self_update ? "(forced) self" : "regular"); 719 720 /* Allocate a system service slot for the new version. */ 721 s = alloc_slot(&new_rp); 722 if(s != OK) { 723 printf("RS: do_update: unable to allocate a new slot: %d\n", s); 724 return s; 725 } 726 727 /* Initialize the slot as requested. */ 728 s = init_slot(new_rp, &rs_start, m_ptr->m_source); 729 if(s != OK) { 730 printf("RS: do_update: unable to init the new slot: %d\n", s); 731 return s; 732 } 733 734 /* Let the new version inherit defaults from the old one. */ 735 inherit_service_defaults(rp, new_rp); 736 737 /* Link the two versions. */ 738 rp->r_new_rp = new_rp; 739 new_rp->r_old_rp = rp; 740 741 /* Create new version of the service but don't let it run. */ 742 new_rp->r_priv.s_flags |= LU_SYS_PROC; 743 new_rp->r_priv.s_init_flags |= rpupd->init_flags; 744 s = create_service(new_rp); 745 if(s != OK) { 746 printf("RS: do_update: unable to create a new service: %d\n", s); 747 return s; 748 } 749 } 750 751 /* Set default state endpoint. */ 752 if(state_endpoint == NONE) { 753 state_endpoint = new_rp->r_pub->endpoint; 754 } 755 756 /* If RS is updating, set up signal managers for the new instance. 757 * The current RS instance must be made the backup signal manager to 758 * support rollback in case of a crash during initialization. 759 */ 760 if(rp->r_priv.s_flags & ROOT_SYS_PROC) { 761 s = update_sig_mgrs(new_rp, SELF, new_rp->r_pub->endpoint); 762 if(s != OK) { 763 cleanup_service(new_rp); 764 return s; 765 } 766 } 767 768 /* Preallocate heap regions if requested. */ 769 if(rs_start.rss_heap_prealloc_bytes < 0) { 770 rs_start.rss_heap_prealloc_bytes = 0; 771 } 772 if(rs_start.rss_heap_prealloc_bytes) { 773 size_t len; 774 if(rs_verbose) 775 printf("RS: %s preallocating %ld heap bytes\n", srv_to_string(new_rp), 776 rs_start.rss_heap_prealloc_bytes); 777 778 len = rs_start.rss_heap_prealloc_bytes; 779 s = vm_memctl(new_rp->r_pub->endpoint, VM_RS_MEM_HEAP_PREALLOC, 780 NULL, &len); 781 if(s != OK) { 782 printf("vm_memctl(VM_RS_MEM_HEAP_PREALLOC) failed: %d\n", s); 783 cleanup_service(new_rp); 784 return s; 785 } 786 if(rp->r_priv.s_flags & ROOT_SYS_PROC) { 787 vm_memctl(new_rp->r_pub->endpoint, VM_RS_MEM_PIN, 0, 0); 788 } 789 } 790 791 /* Preallocate mmapped regions if requested. */ 792 if(rs_start.rss_map_prealloc_bytes < 0) { 793 rs_start.rss_map_prealloc_bytes = 0; 794 } 795 if(rs_start.rss_map_prealloc_bytes) { 796 void *addr = NULL; 797 if(rs_verbose) 798 printf("RS: %s preallocating %ld mmap bytes\n", srv_to_string(new_rp), 799 rs_start.rss_map_prealloc_bytes); 800 801 new_rp->r_map_prealloc_len = rs_start.rss_map_prealloc_bytes; 802 s = vm_memctl(new_rp->r_pub->endpoint, VM_RS_MEM_MAP_PREALLOC, 803 &addr, &new_rp->r_map_prealloc_len); 804 if(s != OK) { 805 printf("vm_memctl(VM_RS_MEM_MAP_PREALLOC) failed: %d\n", s); 806 cleanup_service(new_rp); 807 return s; 808 } 809 new_rp->r_map_prealloc_addr = (vir_bytes) addr; 810 } 811 } 812 813 /* Process state data. */ 814 s = init_state_data(m_ptr->m_source, prepare_state, &rs_start.rss_state_data, &rpupd->prepare_state_data); 815 if(s != OK) { 816 rupdate_upd_clear(rpupd); 817 return s; 818 } 819 820 /* Create update grants. */ 821 if(rpupd->prepare_state_data.size > 0) { 822 struct rs_state_data *state_data = &rpupd->prepare_state_data; 823 rpupd->prepare_state_data_gid = cpf_grant_direct(rpub->endpoint, (vir_bytes) state_data, 824 state_data->size, CPF_READ); 825 if(rpupd->prepare_state_data_gid == GRANT_INVALID) { 826 rupdate_upd_clear(rpupd); 827 return ENOMEM; 828 } 829 state_data->ipcf_els_gid = GRANT_INVALID; 830 if(state_data->ipcf_els) { 831 state_data->ipcf_els_gid = (int) cpf_grant_direct(rpub->endpoint, (vir_bytes) state_data->ipcf_els, 832 state_data->ipcf_els_size, CPF_READ); 833 if(state_data->ipcf_els_gid == GRANT_INVALID) { 834 rupdate_upd_clear(rpupd); 835 return ENOMEM; 836 } 837 } 838 state_data->eval_gid = GRANT_INVALID; 839 if(state_data->eval_addr) { 840 state_data->eval_gid = (int) cpf_grant_direct(rpub->endpoint, (vir_bytes) state_data->eval_addr, 841 state_data->eval_len, CPF_READ); 842 if(state_data->eval_gid == GRANT_INVALID) { 843 rupdate_upd_clear(rpupd); 844 return ENOMEM; 845 } 846 } 847 } 848 849 /* Fill the new update descriptor and add it to the update chain. */ 850 rpupd->prepare_state = prepare_state; 851 rpupd->state_endpoint = state_endpoint; 852 getticks(&rpupd->prepare_tm); 853 rpupd->prepare_maxtime = prepare_maxtime; 854 rupdate_add_upd(rpupd); 855 856 if(rs_verbose) 857 printf("RS: %s scheduled for %s\n", srv_to_string(rp), srv_upd_to_string(rpupd)); 858 859 /* If batch mode, reply immediately. More services to update will follow. */ 860 if(batch_mode) { 861 return OK; 862 } 863 864 /* Start preparing for the update process. */ 865 s = start_update_prepare(allow_retries); 866 if(s == ESRCH) { 867 /* No process left in the update chain. We are done already. */ 868 return OK; 869 } 870 if(s != OK) { 871 return s; 872 } 873 874 /* Unblock the caller immediately if requested. */ 875 if(noblock) { 876 return OK; 877 } 878 879 /* Otherwise, send a reply when the new version completes initialization. */ 880 rupdate.last_rpupd->rp->r_flags |= RS_LATEREPLY; 881 rupdate.last_rpupd->rp->r_caller = m_ptr->m_source; 882 rupdate.last_rpupd->rp->r_caller_request = RS_UPDATE; 883 884 return EDONTREPLY; 885 } 886 887 /*===========================================================================* 888 * do_upd_ready * 889 *===========================================================================*/ 890 int do_upd_ready(message *m_ptr) 891 { 892 struct rproc *rp; 893 struct rprocupd *prev_rpupd, *rpupd; 894 int who_p; 895 int result; 896 int is_rs; 897 int i; 898 899 who_p = _ENDPOINT_P(m_ptr->m_source); 900 rp = rproc_ptr[who_p]; 901 result = m_ptr->m_rs_update.result; 902 903 /* Make sure the originating service was requested to prepare for update. */ 904 rpupd = rupdate.curr_rpupd; 905 if(!rpupd || rp != rpupd->rp || RUPDATE_IS_INITIALIZING()) { 906 if(rs_verbose) 907 printf("RS: %s sent late/unexpected update ready msg\n", 908 srv_to_string(rp)); 909 return EINVAL; 910 } 911 rp->r_flags |= RS_PREPARE_DONE; 912 913 /* Check if something went wrong and the service failed to prepare 914 * for the update. In that case, end the update process. The old version will 915 * be replied to and continue executing. 916 */ 917 if(result != OK) { 918 printf("RS: update failed: %s\n", lu_strerror(result)); 919 end_update(result, RS_REPLY); 920 921 return EDONTREPLY; 922 } 923 924 if(rs_verbose) 925 printf("RS: %s ready to update\n", srv_to_string(rp)); 926 927 /* If this is a multi-component update and this is not the last service 928 * in the update, request the next process to update. 929 */ 930 if(start_update_prepare_next() != NULL) { 931 return EDONTREPLY; 932 } 933 934 /* Now perform the update and request each new instance to initialize. */ 935 start_update(); 936 937 return EDONTREPLY; 938 } 939 940 /*===========================================================================* 941 * do_period * 942 *===========================================================================*/ 943 void do_period(m_ptr) 944 message *m_ptr; 945 { 946 register struct rproc *rp; 947 register struct rprocpub *rpub; 948 clock_t now = m_ptr->m_notify.timestamp; 949 int s; 950 long period; 951 952 /* If an update is in progress, check its status. */ 953 if(RUPDATE_IS_UPDATING() && !RUPDATE_IS_INITIALIZING()) { 954 update_period(m_ptr); 955 } 956 957 /* Search system services table. Only check slots that are in use and not 958 * updating. 959 */ 960 for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) { 961 rpub = rp->r_pub; 962 963 if ((rp->r_flags & RS_ACTIVE) && (!SRV_IS_UPDATING(rp) || ((rp->r_flags & (RS_INITIALIZING|RS_INIT_DONE|RS_INIT_PENDING)) == RS_INITIALIZING))) { 964 965 /* Compute period. */ 966 period = rp->r_period; 967 if(rp->r_flags & RS_INITIALIZING) { 968 period = SRV_IS_UPDATING(rp) ? UPD_INIT_MAXTIME(&rp->r_upd) : RS_INIT_T; 969 } 970 971 /* If the service is to be revived (because it repeatedly exited, 972 * and was not directly restarted), the binary backoff field is 973 * greater than zero. 974 */ 975 if (rp->r_backoff > 0) { 976 rp->r_backoff -= 1; 977 if (rp->r_backoff == 0) { 978 restart_service(rp); 979 } 980 } 981 982 /* If the service was signaled with a SIGTERM and fails to respond, 983 * kill the system service with a SIGKILL signal. 984 */ 985 else if (rp->r_stop_tm > 0 && now - rp->r_stop_tm > 2*RS_DELTA_T 986 && rp->r_pid > 0) { 987 rp->r_stop_tm = 0; 988 crash_service(rp); /* simulate crash */ 989 } 990 991 /* There seems to be no special conditions. If the service has a 992 * period assigned check its status. 993 */ 994 else if (period > 0) { 995 996 /* Check if an answer to a status request is still pending. If 997 * the service didn't respond within time, kill it to simulate 998 * a crash. The failure will be detected and the service will 999 * be restarted automatically. Give the service a free pass if 1000 * somebody is initializing. There may be some weird dependencies 1001 * if another service is, for example, restarting at the same 1002 * time. 1003 */ 1004 if (rp->r_alive_tm < rp->r_check_tm) { 1005 if (now - rp->r_alive_tm > 2*period && 1006 rp->r_pid > 0 && !(rp->r_flags & RS_NOPINGREPLY)) { 1007 struct rproc *rp2; 1008 int init_flag; 1009 if(rs_verbose) 1010 printf("RS: %s reported late\n", srv_to_string(rp)); 1011 init_flag = rp->r_flags & RS_INITIALIZING; 1012 rp->r_flags &= ~RS_INITIALIZING; 1013 rp2 = lookup_slot_by_flags(RS_INITIALIZING); 1014 rp->r_flags |= init_flag; 1015 if(rp2 != NULL && !SRV_IS_UPDATING(rp)) { 1016 /* Skip for now. */ 1017 if(rs_verbose) 1018 printf("RS: %s gets a free pass\n", 1019 srv_to_string(rp)); 1020 rp->r_alive_tm = now; 1021 rp->r_check_tm = now+1; 1022 continue; 1023 } 1024 rp->r_flags |= RS_NOPINGREPLY; 1025 crash_service(rp); /* simulate crash */ 1026 if(rp->r_flags & RS_INITIALIZING) { 1027 rp->r_init_err = EINTR; 1028 } 1029 } 1030 } 1031 1032 /* No answer pending. Check if a period expired since the last 1033 * check and, if so request the system service's status. 1034 */ 1035 else if (now - rp->r_check_tm > rp->r_period) { 1036 ipc_notify(rpub->endpoint); /* request status */ 1037 rp->r_check_tm = now; /* mark time */ 1038 } 1039 } 1040 } 1041 } 1042 1043 /* Reschedule a synchronous alarm for the next period. */ 1044 if (OK != (s=sys_setalarm(RS_DELTA_T, 0))) 1045 panic("couldn't set alarm: %d", s); 1046 } 1047 1048 /*===========================================================================* 1049 * do_sigchld * 1050 *===========================================================================*/ 1051 void do_sigchld() 1052 { 1053 /* PM informed us that there are dead children to cleanup. Go get them. */ 1054 pid_t pid; 1055 int status; 1056 struct rproc *rp; 1057 struct rproc **rps; 1058 int i, nr_rps, found; 1059 1060 if(rs_verbose) 1061 printf("RS: got SIGCHLD signal, cleaning up dead children\n"); 1062 1063 while ( (pid = waitpid(-1, &status, WNOHANG)) != 0 ) { 1064 rp = lookup_slot_by_pid(pid); 1065 if(rp != NULL) { 1066 1067 if(rs_verbose) 1068 printf("RS: %s exited via another signal manager\n", 1069 srv_to_string(rp)); 1070 1071 /* The slot is still there. This means RS is not the signal 1072 * manager assigned to the process. Ignore the event but 1073 * free slots for all the service instances and send a late 1074 * reply if necessary. 1075 */ 1076 found = 0; 1077 get_service_instances(rp, &rps, &nr_rps); 1078 for(i=0;i<nr_rps;i++) { 1079 if(SRV_IS_UPDATING(rps[i])) { 1080 rps[i]->r_flags &= ~(RS_UPDATING|RS_PREPARE_DONE|RS_INIT_DONE|RS_INIT_PENDING); 1081 found = 1; 1082 } 1083 free_slot(rps[i]); 1084 } 1085 if(found) { 1086 rupdate_clear_upds(); 1087 } 1088 } 1089 } 1090 } 1091 1092 /*===========================================================================* 1093 * do_getsysinfo * 1094 *===========================================================================*/ 1095 int do_getsysinfo(m_ptr) 1096 message *m_ptr; 1097 { 1098 vir_bytes src_addr, dst_addr; 1099 int dst_proc; 1100 size_t size, len; 1101 int s; 1102 1103 /* Check if the call can be allowed. */ 1104 if((s = check_call_permission(m_ptr->m_source, 0, NULL)) != OK) 1105 return s; 1106 1107 dst_proc = m_ptr->m_source; 1108 dst_addr = m_ptr->m_lsys_getsysinfo.where; 1109 size = m_ptr->m_lsys_getsysinfo.size; 1110 1111 switch(m_ptr->m_lsys_getsysinfo.what) { 1112 case SI_PROC_TAB: 1113 src_addr = (vir_bytes) rproc; 1114 len = sizeof(struct rproc) * NR_SYS_PROCS; 1115 break; 1116 case SI_PROCALL_TAB: 1117 /* Copy out both tables, one after the other. */ 1118 src_addr = (vir_bytes) rproc; 1119 len = sizeof(struct rproc) * NR_SYS_PROCS; 1120 if (len > size) 1121 return EINVAL; 1122 if ((s = sys_datacopy(SELF, src_addr, dst_proc, dst_addr, len)) != OK) 1123 return s; 1124 dst_addr += len; 1125 size -= len; 1126 /* FALLTHROUGH */ 1127 case SI_PROCPUB_TAB: 1128 src_addr = (vir_bytes) rprocpub; 1129 len = sizeof(struct rprocpub) * NR_SYS_PROCS; 1130 break; 1131 default: 1132 return(EINVAL); 1133 } 1134 1135 if (len != size) 1136 return(EINVAL); 1137 1138 return sys_datacopy(SELF, src_addr, dst_proc, dst_addr, len); 1139 } 1140 1141 /*===========================================================================* 1142 * do_lookup * 1143 *===========================================================================*/ 1144 int do_lookup(m_ptr) 1145 message *m_ptr; 1146 { 1147 static char namebuf[100]; 1148 int len, r; 1149 struct rproc *rrp; 1150 struct rprocpub *rrpub; 1151 1152 len = m_ptr->m_rs_req.name_len; 1153 1154 if(len < 2 || len >= sizeof(namebuf)) { 1155 printf("RS: len too weird (%d)\n", len); 1156 return EINVAL; 1157 } 1158 1159 if((r=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->m_rs_req.name, 1160 SELF, (vir_bytes) namebuf, len)) != OK) { 1161 printf("RS: name copy failed\n"); 1162 return r; 1163 1164 } 1165 1166 namebuf[len] = '\0'; 1167 1168 rrp = lookup_slot_by_label(namebuf); 1169 if(!rrp) { 1170 return ESRCH; 1171 } 1172 rrpub = rrp->r_pub; 1173 m_ptr->m_rs_req.endpoint = rrpub->endpoint; 1174 1175 return OK; 1176 } 1177 1178 /*===========================================================================* 1179 * do_sysctl * 1180 *===========================================================================*/ 1181 int do_sysctl(message *m_ptr) 1182 { 1183 int request_type = m_ptr->m_rs_req.subtype; 1184 int r, allow_retries = 1; 1185 switch(request_type) { 1186 case RS_SYSCTL_SRV_STATUS: 1187 print_services_status(); 1188 break; 1189 case RS_SYSCTL_UPD_START: 1190 case RS_SYSCTL_UPD_RUN: 1191 r = start_update_prepare(allow_retries); 1192 print_update_status(); 1193 if(r != OK) { 1194 if(r == ESRCH) { 1195 /* We are done already. */ 1196 r = OK; 1197 } 1198 return r; 1199 } 1200 if(request_type == RS_SYSCTL_UPD_START) { 1201 return OK; 1202 } 1203 /* Send a reply when done. */ 1204 rupdate.last_rpupd->rp->r_flags |= RS_LATEREPLY; 1205 rupdate.last_rpupd->rp->r_caller = m_ptr->m_source; 1206 rupdate.last_rpupd->rp->r_caller_request = RS_UPDATE; 1207 return EDONTREPLY; 1208 break; 1209 case RS_SYSCTL_UPD_STOP: 1210 r = abort_update_proc(EINTR); 1211 print_update_status(); 1212 return r; 1213 break; 1214 case RS_SYSCTL_UPD_STATUS: 1215 print_update_status(); 1216 break; 1217 default: 1218 printf("RS: bad sysctl type\n"); 1219 return EINVAL; 1220 break; 1221 } 1222 1223 return OK; 1224 } 1225 1226 /*===========================================================================* 1227 * do_fi * 1228 *===========================================================================*/ 1229 int do_fi(message *m_ptr) 1230 { 1231 struct rproc *rp; 1232 struct rprocpub *rpub; 1233 int s, r; 1234 char label[RS_MAX_LABEL_LEN]; 1235 1236 /* Copy label. */ 1237 s = copy_label(m_ptr->m_source, m_ptr->m_rs_req.addr, 1238 m_ptr->m_rs_req.len, label, sizeof(label)); 1239 if(s != OK) { 1240 return s; 1241 } 1242 1243 /* Lookup slot by label. */ 1244 rp = lookup_slot_by_label(label); 1245 if(!rp) { 1246 if(rs_verbose) 1247 printf("RS: do_fi: service '%s' not found\n", label); 1248 return(ESRCH); 1249 } 1250 rpub = rp->r_pub; 1251 1252 /* Check if the call can be allowed. */ 1253 if((r = check_call_permission(m_ptr->m_source, RS_FI, rp)) != OK) 1254 return r; 1255 1256 /* Inject fault into the service as requested. */ 1257 s = fi_service(rp); 1258 1259 return s; 1260 } 1261 1262 /*===========================================================================* 1263 * check_request * 1264 *===========================================================================*/ 1265 static int check_request(struct rs_start *rs_start) 1266 { 1267 /* Verify scheduling parameters */ 1268 if (rs_start->rss_scheduler != KERNEL && 1269 (rs_start->rss_scheduler < 0 || 1270 rs_start->rss_scheduler > LAST_SPECIAL_PROC_NR)) { 1271 printf("RS: check_request: invalid scheduler %d\n", 1272 rs_start->rss_scheduler); 1273 return EINVAL; 1274 } 1275 if (rs_start->rss_priority >= NR_SCHED_QUEUES) { 1276 printf("RS: check_request: priority %u out of range\n", 1277 rs_start->rss_priority); 1278 return EINVAL; 1279 } 1280 if (rs_start->rss_quantum <= 0) { 1281 printf("RS: check_request: quantum %u out of range\n", 1282 rs_start->rss_quantum); 1283 return EINVAL; 1284 } 1285 1286 if (rs_start->rss_cpu == RS_CPU_BSP) 1287 rs_start->rss_cpu = machine.bsp_id; 1288 else if (rs_start->rss_cpu == RS_CPU_DEFAULT) { 1289 /* keep the default value */ 1290 } else if (rs_start->rss_cpu < 0) 1291 return EINVAL; 1292 else if (rs_start->rss_cpu > machine.processors_count) { 1293 printf("RS: cpu number %d out of range 0-%d, using BSP\n", 1294 rs_start->rss_cpu, machine.processors_count); 1295 rs_start->rss_cpu = machine.bsp_id; 1296 } 1297 1298 /* Verify signal manager. */ 1299 if (rs_start->rss_sigmgr != SELF && 1300 (rs_start->rss_sigmgr < 0 || 1301 rs_start->rss_sigmgr > LAST_SPECIAL_PROC_NR)) { 1302 printf("RS: check_request: invalid signal manager %d\n", 1303 rs_start->rss_sigmgr); 1304 return EINVAL; 1305 } 1306 1307 return OK; 1308 } 1309 1310