1 /* 2 * Changes: 3 * Nov 22, 2009: added basic live update support (Cristiano Giuffrida) 4 * Mar 02, 2009: Extended isolation policies (Jorrit N. Herder) 5 * Jul 22, 2005: Created (Jorrit N. Herder) 6 */ 7 8 #include <paths.h> 9 10 #include <sys/exec_elf.h> 11 12 #include "inc.h" 13 14 #include "kernel/proc.h" 15 16 /*===========================================================================* 17 * caller_is_root * 18 *===========================================================================*/ 19 static int caller_is_root(endpoint) 20 endpoint_t endpoint; /* caller endpoint */ 21 { 22 uid_t euid; 23 24 /* Check if caller has root user ID. */ 25 euid = getnuid(endpoint); 26 if (rs_verbose && euid != 0) 27 { 28 printf("RS: got unauthorized request from endpoint %d\n", endpoint); 29 } 30 31 return euid == 0; 32 } 33 34 /*===========================================================================* 35 * caller_can_control * 36 *===========================================================================*/ 37 static int caller_can_control(endpoint, target_rp) 38 endpoint_t endpoint; 39 struct rproc *target_rp; 40 { 41 int control_allowed = 0; 42 register struct rproc *rp; 43 register struct rprocpub *rpub; 44 char *proc_name; 45 int c; 46 47 proc_name = target_rp->r_pub->proc_name; 48 49 /* Check if label is listed in caller's isolation policy. */ 50 for (rp = BEG_RPROC_ADDR; rp < END_RPROC_ADDR; rp++) { 51 if (!(rp->r_flags & RS_IN_USE)) 52 continue; 53 54 rpub = rp->r_pub; 55 if (rpub->endpoint == endpoint) { 56 break; 57 } 58 } 59 if (rp == END_RPROC_ADDR) return 0; 60 61 for (c = 0; c < rp->r_nr_control; c++) { 62 if (strcmp(rp->r_control[c], proc_name) == 0) { 63 control_allowed = 1; 64 break; 65 } 66 } 67 68 if (rs_verbose) 69 printf("RS: allowing %u control over %s via policy: %s\n", 70 endpoint, target_rp->r_pub->label, 71 control_allowed ? "yes" : "no"); 72 73 return control_allowed; 74 } 75 76 /*===========================================================================* 77 * check_call_permission * 78 *===========================================================================*/ 79 int check_call_permission(caller, call, rp) 80 endpoint_t caller; 81 int call; 82 struct rproc *rp; 83 { 84 /* Check if the caller has permission to execute a particular call. */ 85 struct rprocpub *rpub; 86 int call_allowed; 87 88 /* Caller should be either root or have control privileges. */ 89 call_allowed = caller_is_root(caller); 90 if(rp) { 91 call_allowed |= caller_can_control(caller, rp); 92 } 93 if(!call_allowed) { 94 return EPERM; 95 } 96 97 if(rp) { 98 rpub = rp->r_pub; 99 100 /* Only allow RS_EDIT if the target is a user process. */ 101 if(!(rp->r_priv.s_flags & SYS_PROC)) { 102 if(call != RS_EDIT) return EPERM; 103 } 104 105 /* Disallow the call if another call is in progress for the service. */ 106 if((rp->r_flags & RS_LATEREPLY) 107 || (rp->r_flags & RS_INITIALIZING) || (rp->r_flags & RS_UPDATING)) { 108 return EBUSY; 109 } 110 111 /* Only allow RS_DOWN and RS_RESTART if the service has terminated. */ 112 if(rp->r_flags & RS_TERMINATED) { 113 if(call != RS_DOWN && call != RS_RESTART) return EPERM; 114 } 115 116 /* Disallow RS_DOWN for core system services. */ 117 if (rpub->sys_flags & SF_CORE_SRV) { 118 if(call == RS_DOWN) return EPERM; 119 } 120 } 121 122 return OK; 123 } 124 125 /*===========================================================================* 126 * copy_rs_start * 127 *===========================================================================*/ 128 int copy_rs_start(src_e, src_rs_start, dst_rs_start) 129 endpoint_t src_e; 130 char *src_rs_start; 131 struct rs_start *dst_rs_start; 132 { 133 int r; 134 135 r = sys_datacopy(src_e, (vir_bytes) src_rs_start, 136 SELF, (vir_bytes) dst_rs_start, sizeof(struct rs_start)); 137 138 return r; 139 } 140 141 /*===========================================================================* 142 * copy_label * 143 *===========================================================================*/ 144 int copy_label(src_e, src_label, src_len, dst_label, dst_len) 145 endpoint_t src_e; 146 char *src_label; 147 size_t src_len; 148 char *dst_label; 149 size_t dst_len; 150 { 151 int s, len; 152 153 len = MIN(dst_len-1, src_len); 154 155 s = sys_datacopy(src_e, (vir_bytes) src_label, 156 SELF, (vir_bytes) dst_label, len); 157 if (s != OK) return s; 158 159 dst_label[len] = 0; 160 161 return OK; 162 } 163 164 /*===========================================================================* 165 * build_cmd_dep * 166 *===========================================================================*/ 167 void build_cmd_dep(struct rproc *rp) 168 { 169 struct rprocpub *rpub; 170 int arg_count; 171 int len; 172 char *cmd_ptr; 173 174 rpub = rp->r_pub; 175 176 /* Build argument vector to be passed to execute call. The format of the 177 * arguments vector is: path, arguments, NULL. 178 */ 179 strcpy(rp->r_args, rp->r_cmd); /* copy raw command */ 180 arg_count = 0; /* initialize arg count */ 181 rp->r_argv[arg_count++] = rp->r_args; /* start with path */ 182 cmd_ptr = rp->r_args; /* do some parsing */ 183 while(*cmd_ptr != '\0') { /* stop at end of string */ 184 if (*cmd_ptr == ' ') { /* next argument */ 185 *cmd_ptr = '\0'; /* terminate previous */ 186 while (*++cmd_ptr == ' ') ; /* skip spaces */ 187 if (*cmd_ptr == '\0') break; /* no arg following */ 188 /* There are ARGV_ELEMENTS elements; must leave one for null */ 189 if (arg_count>=ARGV_ELEMENTS-1) { /* arg vector full */ 190 printf("RS: build_cmd_dep: too many args\n"); 191 break; 192 } 193 assert(arg_count < ARGV_ELEMENTS); 194 rp->r_argv[arg_count++] = cmd_ptr; /* add to arg vector */ 195 } 196 cmd_ptr ++; /* continue parsing */ 197 } 198 assert(arg_count < ARGV_ELEMENTS); 199 rp->r_argv[arg_count] = NULL; /* end with NULL pointer */ 200 rp->r_argc = arg_count; 201 202 /* Build process name. */ 203 cmd_ptr = strrchr(rp->r_argv[0], '/'); 204 if (cmd_ptr) 205 cmd_ptr++; 206 else 207 cmd_ptr= rp->r_argv[0]; 208 len= strlen(cmd_ptr); 209 if (len > RS_MAX_LABEL_LEN-1) 210 len= RS_MAX_LABEL_LEN-1; /* truncate name */ 211 memcpy(rpub->proc_name, cmd_ptr, len); 212 rpub->proc_name[len]= '\0'; 213 } 214 215 /*===========================================================================* 216 * srv_update * 217 *===========================================================================*/ 218 int srv_update(endpoint_t src_e, endpoint_t dst_e) 219 { 220 int r; 221 222 /* Ask VM to swap the slots of the two processes and tell the kernel to 223 * do the same. If VM is the service being updated, only perform the kernel 224 * part of the call. The new instance of VM will do the rest at 225 * initialization time. 226 */ 227 if(src_e != VM_PROC_NR) { 228 r = vm_update(src_e, dst_e); 229 } 230 else { 231 r = sys_update(src_e, dst_e); 232 } 233 234 return r; 235 } 236 237 /*===========================================================================* 238 * update_period * 239 *===========================================================================*/ 240 void update_period(message *m_ptr) 241 { 242 clock_t now = m_ptr->m_notify.timestamp; 243 short has_update_timed_out; 244 message m; 245 struct rprocpub *rpub; 246 247 rpub = rupdate.rp->r_pub; 248 249 /* See if a timeout has occurred. */ 250 has_update_timed_out = (now - rupdate.prepare_tm > rupdate.prepare_maxtime); 251 252 /* If an update timed out, end the update process and notify 253 * the old version that the update has been canceled. From now on, the old 254 * version will continue executing. 255 */ 256 if(has_update_timed_out) { 257 printf("RS: update failed: maximum prepare time reached\n"); 258 end_update(EINTR, RS_DONTREPLY); 259 260 /* Prepare cancel request. */ 261 m.m_type = RS_LU_PREPARE; 262 m.m_rs_update.state = SEF_LU_STATE_NULL; 263 if(rpub->endpoint == RS_PROC_NR) { 264 /* RS can process the request directly. */ 265 do_sef_lu_request(&m); 266 } 267 else { 268 /* Send request message to the system service. */ 269 asynsend(rpub->endpoint, &m); 270 } 271 } 272 } 273 274 /*===========================================================================* 275 * end_update * 276 *===========================================================================*/ 277 void end_update(int result, int reply_flag) 278 { 279 /* End the update process. There are two possibilities: 280 * 1) the update succeeded. In that case, cleanup the old version and mark the 281 * new version as no longer under update. 282 * 2) the update failed. In that case, cleanup the new version and mark the old 283 * version as no longer under update. Eventual late ready to update 284 * messages (if any) will simply be ignored and the service can 285 * continue executing. In addition, reset the check timestamp, so that if the 286 * service has a period, a status request will be forced in the next period. 287 */ 288 struct rproc *old_rp, *new_rp, *exiting_rp, *surviving_rp; 289 struct rproc **rps; 290 int nr_rps, i; 291 292 old_rp = rupdate.rp; 293 new_rp = old_rp->r_new_rp; 294 295 if(rs_verbose) 296 printf("RS: ending update from %s to %s with result: %d\n", 297 srv_to_string(old_rp), srv_to_string(new_rp), result); 298 299 /* Decide which version has to die out and which version has to survive. */ 300 surviving_rp = (result == OK ? new_rp : old_rp); 301 exiting_rp = (result == OK ? old_rp : new_rp); 302 303 /* End update. */ 304 rupdate.flags &= ~RS_UPDATING; 305 rupdate.rp = NULL; 306 old_rp->r_new_rp = NULL; 307 new_rp->r_old_rp = NULL; 308 old_rp->r_check_tm = 0; 309 310 /* Send a late reply if necessary. */ 311 late_reply(old_rp, result); 312 313 /* Mark the version that has to survive as no longer updating and 314 * reply when asked to. 315 */ 316 surviving_rp->r_flags &= ~RS_UPDATING; 317 if(reply_flag == RS_REPLY) { 318 message m; 319 m.m_type = result; 320 reply(surviving_rp->r_pub->endpoint, surviving_rp, &m); 321 } 322 323 /* Cleanup the version that has to die out. */ 324 get_service_instances(exiting_rp, &rps, &nr_rps); 325 for(i=0;i<nr_rps;i++) { 326 cleanup_service(rps[i]); 327 } 328 329 if(rs_verbose) 330 printf("RS: %s ended the update\n", srv_to_string(surviving_rp)); 331 } 332 333 /*===========================================================================* 334 * kill_service_debug * 335 *===========================================================================*/ 336 int kill_service_debug(file, line, rp, errstr, err) 337 char *file; 338 int line; 339 struct rproc *rp; 340 char *errstr; 341 int err; 342 { 343 /* Crash a system service and don't let it restart. */ 344 if(errstr && !shutting_down) { 345 printf("RS: %s (error %d)\n", errstr, err); 346 } 347 rp->r_flags |= RS_EXITING; /* expect exit */ 348 crash_service_debug(file, line, rp); /* simulate crash */ 349 350 return err; 351 } 352 353 /*===========================================================================* 354 * crash_service_debug * 355 *===========================================================================*/ 356 int crash_service_debug(file, line, rp) 357 char *file; 358 int line; 359 struct rproc *rp; 360 { 361 /* Simluate a crash in a system service. */ 362 struct rprocpub *rpub; 363 364 rpub = rp->r_pub; 365 366 if(rs_verbose) 367 printf("RS: %s %skilled at %s:%d\n", srv_to_string(rp), 368 rp->r_flags & RS_EXITING ? "lethally " : "", file, line); 369 370 /* RS should simply exit() directly. */ 371 if(rpub->endpoint == RS_PROC_NR) { 372 exit(1); 373 } 374 375 return sys_kill(rpub->endpoint, SIGKILL); 376 } 377 378 /*===========================================================================* 379 * cleanup_service_debug * 380 *===========================================================================*/ 381 void cleanup_service_debug(file, line, rp) 382 char *file; 383 int line; 384 struct rproc *rp; 385 { 386 struct rprocpub *rpub; 387 int s; 388 389 rpub = rp->r_pub; 390 391 if(rs_verbose) 392 printf("RS: %s cleaned up at %s:%d\n", srv_to_string(rp), 393 file, line); 394 395 /* Tell scheduler this process is finished */ 396 if ((s = sched_stop(rp->r_scheduler, rpub->endpoint)) != OK) { 397 printf("RS: warning: scheduler won't give up process: %d\n", s); 398 } 399 400 /* Ask PM to exit the service */ 401 if(rp->r_pid == -1) { 402 printf("RS: warning: attempt to kill pid -1!\n"); 403 } 404 else { 405 srv_kill(rp->r_pid, SIGKILL); 406 } 407 408 /* Free slot, unless we're about to reuse it */ 409 if (!(rp->r_flags & RS_REINCARNATE)) 410 free_slot(rp); 411 } 412 413 /*===========================================================================* 414 * create_service * 415 *===========================================================================*/ 416 int create_service(rp) 417 struct rproc *rp; 418 { 419 /* Create the given system service. */ 420 int child_proc_nr_e, child_proc_nr_n; /* child process slot */ 421 pid_t child_pid; /* child's process id */ 422 int s, use_copy, has_replica; 423 extern char **environ; 424 struct rprocpub *rpub; 425 426 rpub = rp->r_pub; 427 use_copy= (rpub->sys_flags & SF_USE_COPY); 428 has_replica= (rp->r_old_rp 429 || (rp->r_prev_rp && !(rp->r_prev_rp->r_flags & RS_TERMINATED))); 430 431 /* Do we need an existing replica to create the service? */ 432 if(!has_replica && (rpub->sys_flags & SF_NEED_REPL)) { 433 printf("RS: unable to create service '%s' without a replica\n", 434 rpub->label); 435 free_slot(rp); 436 return(EPERM); 437 } 438 439 /* Do we need an in-memory copy to create the service? */ 440 if(!use_copy && (rpub->sys_flags & SF_NEED_COPY)) { 441 printf("RS: unable to create service '%s' without an in-memory copy\n", 442 rpub->label); 443 free_slot(rp); 444 return(EPERM); 445 } 446 447 /* Do we have a copy or a command to create the service? */ 448 if(!use_copy && !strcmp(rp->r_cmd, "")) { 449 printf("RS: unable to create service '%s' without a copy or command\n", 450 rpub->label); 451 free_slot(rp); 452 return(EPERM); 453 } 454 455 /* Now fork and branch for parent and child process (and check for error). 456 * After fork()ing, we need to pin RS memory again or pagefaults will occur 457 * on future writes. 458 */ 459 if(rs_verbose) 460 printf("RS: forking child with srv_fork()...\n"); 461 child_pid= srv_fork(rp->r_uid, 0); /* Force group to operator for now */ 462 if(child_pid < 0) { 463 printf("RS: srv_fork() failed (error %d)\n", child_pid); 464 free_slot(rp); 465 return(child_pid); 466 } 467 468 /* Get endpoint of the child. */ 469 if ((s = getprocnr(child_pid, &child_proc_nr_e)) != 0) 470 panic("unable to get child endpoint: %d", s); 471 472 /* There is now a child process. Update the system process table. */ 473 child_proc_nr_n = _ENDPOINT_P(child_proc_nr_e); 474 rp->r_flags = RS_IN_USE; /* mark slot in use */ 475 rpub->endpoint = child_proc_nr_e; /* set child endpoint */ 476 rp->r_pid = child_pid; /* set child pid */ 477 rp->r_check_tm = 0; /* not checked yet */ 478 getticks(&rp->r_alive_tm); /* currently alive */ 479 rp->r_stop_tm = 0; /* not exiting yet */ 480 rp->r_backoff = 0; /* not to be restarted */ 481 rproc_ptr[child_proc_nr_n] = rp; /* mapping for fast access */ 482 rpub->in_use = TRUE; /* public entry is now in use */ 483 484 /* Set and synch the privilege structure for the new service. */ 485 if ((s = sys_privctl(child_proc_nr_e, SYS_PRIV_SET_SYS, &rp->r_priv)) != OK 486 || (s = sys_getpriv(&rp->r_priv, child_proc_nr_e)) != OK) { 487 printf("RS: unable to set privilege structure: %d\n", s); 488 cleanup_service(rp); 489 vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN); 490 return ENOMEM; 491 } 492 493 /* Set the scheduler for this process */ 494 if ((s = sched_init_proc(rp)) != OK) { 495 printf("RS: unable to start scheduling: %d\n", s); 496 cleanup_service(rp); 497 vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN); 498 return s; 499 } 500 501 /* Copy the executable image into the child process. If no copy exists, 502 * allocate one and free it right after exec completes. 503 */ 504 if(use_copy) { 505 if(rs_verbose) 506 printf("RS: %s uses an in-memory copy\n", 507 srv_to_string(rp)); 508 } 509 else { 510 if ((s = read_exec(rp)) != OK) { 511 printf("RS: read_exec failed: %d\n", s); 512 cleanup_service(rp); 513 vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN); 514 return s; 515 } 516 } 517 if(rs_verbose) 518 printf("RS: execing child with srv_execve()...\n"); 519 s = srv_execve(child_proc_nr_e, rp->r_exec, rp->r_exec_len, rp->r_argv, 520 environ); 521 vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN); 522 if (s != OK) { 523 printf("RS: srv_execve failed: %d\n", s); 524 cleanup_service(rp); 525 return s; 526 } 527 if(!use_copy) { 528 free_exec(rp); 529 } 530 531 /* If this is a VM instance, let VM know now. */ 532 if(rp->r_priv.s_flags & VM_SYS_PROC) { 533 if(rs_verbose) 534 printf("RS: informing VM of instance %s\n", srv_to_string(rp)); 535 536 s = vm_memctl(rpub->endpoint, VM_RS_MEM_MAKE_VM); 537 if(s != OK) { 538 printf("vm_memctl failed: %d\n", s); 539 cleanup_service(rp); 540 return s; 541 } 542 } 543 544 /* Tell VM about allowed calls. */ 545 if ((s = vm_set_priv(rpub->endpoint, &rpub->vm_call_mask[0], TRUE)) != OK) { 546 printf("RS: vm_set_priv failed: %d\n", s); 547 cleanup_service(rp); 548 return s; 549 } 550 551 if(rs_verbose) 552 printf("RS: %s created\n", srv_to_string(rp)); 553 554 return OK; 555 } 556 557 /*===========================================================================* 558 * clone_service * 559 *===========================================================================*/ 560 int clone_service(rp, instance_flag) 561 struct rproc *rp; 562 int instance_flag; 563 { 564 /* Clone the given system service instance. */ 565 struct rproc *replica_rp; 566 struct rprocpub *replica_rpub; 567 struct rproc **rp_link; 568 struct rproc **replica_link; 569 struct rproc *rs_rp; 570 int rs_flags; 571 int r; 572 573 if(rs_verbose) 574 printf("RS: creating a replica for %s\n", srv_to_string(rp)); 575 576 /* Clone slot. */ 577 if((r = clone_slot(rp, &replica_rp)) != OK) { 578 return r; 579 } 580 replica_rpub = replica_rp->r_pub; 581 582 /* Clone is a live updated or restarted service instance? */ 583 if(instance_flag == LU_SYS_PROC) { 584 rp_link = &rp->r_new_rp; 585 replica_link = &replica_rp->r_old_rp; 586 } 587 else { 588 rp_link = &rp->r_next_rp; 589 replica_link = &replica_rp->r_prev_rp; 590 } 591 replica_rp->r_priv.s_flags |= instance_flag; 592 593 /* Link the two slots. */ 594 *rp_link = replica_rp; 595 *replica_link = rp; 596 597 /* Create a new replica of the service. */ 598 r = create_service(replica_rp); 599 if(r != OK) { 600 *rp_link = NULL; 601 return r; 602 } 603 604 /* If this instance is for restarting RS, set up a backup signal manager. */ 605 rs_flags = (ROOT_SYS_PROC | RST_SYS_PROC); 606 if((replica_rp->r_priv.s_flags & rs_flags) == rs_flags) { 607 rs_rp = rproc_ptr[_ENDPOINT_P(RS_PROC_NR)]; 608 609 /* Update signal managers. */ 610 r = update_sig_mgrs(rs_rp, SELF, replica_rpub->endpoint); 611 if(r == OK) { 612 r = update_sig_mgrs(replica_rp, SELF, NONE); 613 } 614 if(r != OK) { 615 *rp_link = NULL; 616 return kill_service(replica_rp, "update_sig_mgrs failed", r); 617 } 618 } 619 620 return OK; 621 } 622 623 /*===========================================================================* 624 * publish_service * 625 *===========================================================================*/ 626 int publish_service(rp) 627 struct rproc *rp; /* pointer to service slot */ 628 { 629 /* Publish a service. */ 630 int r; 631 struct rprocpub *rpub; 632 struct rs_pci pci_acl; 633 message m; 634 endpoint_t ep; 635 636 rpub = rp->r_pub; 637 638 /* Register label with DS. */ 639 r = ds_publish_label(rpub->label, rpub->endpoint, DSF_OVERWRITE); 640 if (r != OK) { 641 return kill_service(rp, "ds_publish_label call failed", r); 642 } 643 644 /* If the service is a driver, map it. */ 645 if (rpub->dev_nr > 0) { 646 /* The purpose of non-blocking forks is to avoid involving VFS in the 647 * forking process, because VFS may be blocked on a ipc_sendrec() to a MFS 648 * that is waiting for a endpoint update for a dead driver. We have just 649 * published that update, but VFS may still be blocked. As a result, VFS 650 * may not yet have received PM's fork message. Hence, if we call 651 * mapdriver() immediately, VFS may not know about the process and thus 652 * refuse to add the driver entry. The following temporary hack works 653 * around this by forcing blocking communication from PM to VFS. Once VFS 654 * has been made non-blocking towards MFS instances, this hack and the 655 * big part of srv_fork() can go. 656 */ 657 setuid(0); 658 659 if ((r = mapdriver(rpub->label, rpub->dev_nr)) != OK) { 660 return kill_service(rp, "couldn't map driver", r); 661 } 662 } 663 664 #if USE_PCI 665 /* If PCI properties are set, inform the PCI driver about the new service. */ 666 if(rpub->pci_acl.rsp_nr_device || rpub->pci_acl.rsp_nr_class) { 667 pci_acl = rpub->pci_acl; 668 strcpy(pci_acl.rsp_label, rpub->label); 669 pci_acl.rsp_endpoint= rpub->endpoint; 670 671 r = pci_set_acl(&pci_acl); 672 if (r != OK) { 673 return kill_service(rp, "pci_set_acl call failed", r); 674 } 675 } 676 #endif /* USE_PCI */ 677 678 if (rpub->devman_id != 0) { 679 r = ds_retrieve_label_endpt("devman",&ep); 680 681 if (r != OK) { 682 return kill_service(rp, "devman not running?", r); 683 } 684 m.m_type = DEVMAN_BIND; 685 m.DEVMAN_ENDPOINT = rpub->endpoint; 686 m.DEVMAN_DEVICE_ID = rpub->devman_id; 687 r = ipc_sendrec(ep, &m); 688 if (r != OK || m.DEVMAN_RESULT != OK) { 689 return kill_service(rp, "devman bind device failed", r); 690 } 691 } 692 693 if(rs_verbose) 694 printf("RS: %s published\n", srv_to_string(rp)); 695 696 return OK; 697 } 698 699 /*===========================================================================* 700 * unpublish_service * 701 *===========================================================================*/ 702 int unpublish_service(rp) 703 struct rproc *rp; /* pointer to service slot */ 704 { 705 /* Unpublish a service. */ 706 struct rprocpub *rpub; 707 int r, result; 708 message m; 709 endpoint_t ep; 710 711 712 rpub = rp->r_pub; 713 result = OK; 714 715 /* Unregister label with DS. */ 716 r = ds_delete_label(rpub->label); 717 if (r != OK && !shutting_down) { 718 printf("RS: ds_delete_label call failed (error %d)\n", r); 719 result = r; 720 } 721 722 /* No need to inform VFS and VM, cleanup is done on exit automatically. */ 723 724 #if USE_PCI 725 /* If PCI properties are set, inform the PCI driver. */ 726 if(rpub->pci_acl.rsp_nr_device || rpub->pci_acl.rsp_nr_class) { 727 r = pci_del_acl(rpub->endpoint); 728 if (r != OK && !shutting_down) { 729 printf("RS: pci_del_acl call failed (error %d)\n", r); 730 result = r; 731 } 732 } 733 #endif /* USE_PCI */ 734 735 if (rpub->devman_id != 0) { 736 r = ds_retrieve_label_endpt("devman",&ep); 737 738 if (r != OK) { 739 printf("RS: devman not running?"); 740 } else { 741 m.m_type = DEVMAN_UNBIND; 742 m.DEVMAN_ENDPOINT = rpub->endpoint; 743 m.DEVMAN_DEVICE_ID = rpub->devman_id; 744 r = ipc_sendrec(ep, &m); 745 746 if (r != OK || m.DEVMAN_RESULT != OK) { 747 printf("RS: devman unbind device failed"); 748 } 749 } 750 } 751 752 if(rs_verbose) 753 printf("RS: %s unpublished\n", srv_to_string(rp)); 754 755 return result; 756 } 757 758 /*===========================================================================* 759 * run_service * 760 *===========================================================================*/ 761 int run_service(rp, init_type) 762 struct rproc *rp; 763 int init_type; 764 { 765 /* Let a newly created service run. */ 766 struct rprocpub *rpub; 767 int s; 768 769 rpub = rp->r_pub; 770 771 /* Allow the service to run. */ 772 if ((s = sys_privctl(rpub->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) { 773 return kill_service(rp, "unable to allow the service to run",s); 774 } 775 776 /* Initialize service. */ 777 if((s = init_service(rp, init_type)) != OK) { 778 return kill_service(rp, "unable to initialize service", s); 779 } 780 781 if(rs_verbose) 782 printf("RS: %s allowed to run\n", srv_to_string(rp)); 783 784 return OK; 785 } 786 787 /*===========================================================================* 788 * start_service * 789 *===========================================================================*/ 790 int start_service(rp) 791 struct rproc *rp; 792 { 793 /* Start a system service. */ 794 int r, init_type; 795 struct rprocpub *rpub; 796 797 rpub = rp->r_pub; 798 799 /* Create and make active. */ 800 r = create_service(rp); 801 if(r != OK) { 802 return r; 803 } 804 activate_service(rp, NULL); 805 806 /* Publish service properties. */ 807 r = publish_service(rp); 808 if (r != OK) { 809 return r; 810 } 811 812 /* Run. */ 813 init_type = SEF_INIT_FRESH; 814 r = run_service(rp, init_type); 815 if(r != OK) { 816 return r; 817 } 818 819 if(rs_verbose) 820 printf("RS: %s started with major %d\n", srv_to_string(rp), 821 rpub->dev_nr); 822 823 return OK; 824 } 825 826 /*===========================================================================* 827 * stop_service * 828 *===========================================================================*/ 829 void stop_service(struct rproc *rp,int how) 830 { 831 struct rprocpub *rpub; 832 int signo; 833 834 rpub = rp->r_pub; 835 836 /* Try to stop the system service. First send a SIGTERM signal to ask the 837 * system service to terminate. If the service didn't install a signal 838 * handler, it will be killed. If it did and ignores the signal, we'll 839 * find out because we record the time here and send a SIGKILL. 840 */ 841 if(rs_verbose) 842 printf("RS: %s signaled with SIGTERM\n", srv_to_string(rp)); 843 844 signo = rpub->endpoint != RS_PROC_NR ? SIGTERM : SIGHUP; /* SIGHUP for RS. */ 845 846 rp->r_flags |= how; /* what to on exit? */ 847 sys_kill(rpub->endpoint, signo); /* first try friendly */ 848 getticks(&rp->r_stop_tm); /* record current time */ 849 } 850 851 /*===========================================================================* 852 * update_service * 853 *===========================================================================*/ 854 int update_service(src_rpp, dst_rpp, swap_flag) 855 struct rproc **src_rpp; 856 struct rproc **dst_rpp; 857 int swap_flag; 858 { 859 /* Update an existing service. */ 860 int r; 861 struct rproc *src_rp; 862 struct rproc *dst_rp; 863 struct rprocpub *src_rpub; 864 struct rprocpub *dst_rpub; 865 int pid; 866 endpoint_t endpoint; 867 868 src_rp = *src_rpp; 869 dst_rp = *dst_rpp; 870 src_rpub = src_rp->r_pub; 871 dst_rpub = dst_rp->r_pub; 872 873 if(rs_verbose) 874 printf("RS: %s updating into %s\n", 875 srv_to_string(src_rp), srv_to_string(dst_rp)); 876 877 /* Swap the slots of the two processes when asked to. */ 878 if(swap_flag == RS_SWAP) { 879 if((r = srv_update(src_rpub->endpoint, dst_rpub->endpoint)) != OK) { 880 return r; 881 } 882 } 883 884 /* Swap slots here as well. */ 885 pid = src_rp->r_pid; 886 endpoint = src_rpub->endpoint; 887 swap_slot(&src_rp, &dst_rp); 888 889 /* Reassign pids and endpoints. */ 890 src_rp->r_pid = dst_rp->r_pid; 891 src_rp->r_pub->endpoint = dst_rp->r_pub->endpoint; 892 rproc_ptr[_ENDPOINT_P(src_rp->r_pub->endpoint)] = src_rp; 893 dst_rp->r_pid = pid; 894 dst_rp->r_pub->endpoint = endpoint; 895 rproc_ptr[_ENDPOINT_P(dst_rp->r_pub->endpoint)] = dst_rp; 896 897 /* Adjust input pointers. */ 898 *src_rpp = src_rp; 899 *dst_rpp = dst_rp; 900 901 /* Make the new version active. */ 902 activate_service(dst_rp, src_rp); 903 904 if(rs_verbose) 905 printf("RS: %s updated into %s\n", 906 srv_to_string(src_rp), srv_to_string(dst_rp)); 907 908 return OK; 909 } 910 911 /*===========================================================================* 912 * activate_service * 913 *===========================================================================*/ 914 void activate_service(struct rproc *rp, struct rproc *ex_rp) 915 { 916 /* Activate a service instance and deactivate another one if requested. */ 917 918 if(ex_rp && (ex_rp->r_flags & RS_ACTIVE) ) { 919 ex_rp->r_flags &= ~RS_ACTIVE; 920 if(rs_verbose) 921 printf("RS: %s becomes inactive\n", srv_to_string(ex_rp)); 922 } 923 924 if(! (rp->r_flags & RS_ACTIVE) ) { 925 rp->r_flags |= RS_ACTIVE; 926 if(rs_verbose) 927 printf("RS: %s becomes active\n", srv_to_string(rp)); 928 } 929 } 930 931 /*===========================================================================* 932 * reincarnate_service * 933 *===========================================================================*/ 934 void reincarnate_service(struct rproc *rp) 935 { 936 /* Restart a service as if it were never started before. */ 937 struct rprocpub *rpub; 938 int i; 939 940 rpub = rp->r_pub; 941 942 rp->r_flags &= RS_IN_USE; 943 rp->r_pid = -1; 944 rproc_ptr[_ENDPOINT_P(rpub->endpoint)] = NULL; 945 946 /* Restore original IRQ and I/O range tables in the priv struct. This is the 947 * only part of the privilege structure that can be modified by processes 948 * other than RS itself. 949 */ 950 rp->r_priv.s_nr_irq = rp->r_nr_irq; 951 for (i = 0; i < rp->r_nr_irq; i++) 952 rp->r_priv.s_irq_tab[i] = rp->r_irq_tab[i]; 953 rp->r_priv.s_nr_io_range = rp->r_nr_io_range; 954 for (i = 0; i < rp->r_nr_io_range; i++) 955 rp->r_priv.s_io_tab[i] = rp->r_io_tab[i]; 956 957 rp->r_old_rp = NULL; 958 rp->r_new_rp = NULL; 959 rp->r_prev_rp = NULL; 960 rp->r_next_rp = NULL; 961 962 start_service(rp); 963 } 964 965 /*===========================================================================* 966 * terminate_service * 967 *===========================================================================*/ 968 void terminate_service(struct rproc *rp) 969 { 970 /* Handle a termination event for a system service. */ 971 struct rproc **rps; 972 struct rprocpub *rpub; 973 int nr_rps; 974 int i, r; 975 976 rpub = rp->r_pub; 977 978 if(rs_verbose) 979 printf("RS: %s terminated\n", srv_to_string(rp)); 980 981 /* Deal with failures during initialization. */ 982 if(rp->r_flags & RS_INITIALIZING) { 983 if (rpub->sys_flags & SF_NO_BIN_EXP) { 984 /* If service was deliberately started with binary exponential offset 985 * disabled, we're going to assume we want to refresh a service upon 986 * failure. 987 */ 988 if(rs_verbose) 989 printf("RS: service '%s' exited during initialization; " 990 "refreshing\n", rpub->label); 991 rp->r_flags |= RS_REFRESHING; /* restart initialization. */ 992 } else { 993 if(rs_verbose) 994 printf("RS: service '%s' exited during initialization; " 995 "not restarting\n", rpub->label); 996 rp->r_flags |= RS_EXITING; /* don't restart. */ 997 } 998 999 /* If updating, rollback. */ 1000 if(rp->r_flags & RS_UPDATING) { 1001 struct rproc *old_rp, *new_rp; 1002 printf("RS: update failed: state transfer failed. Rolling back...\n"); 1003 new_rp = rp; 1004 old_rp = new_rp->r_old_rp; 1005 new_rp->r_flags &= ~RS_INITIALIZING; 1006 r = update_service(&new_rp, &old_rp, RS_SWAP); 1007 assert(r == OK); /* can't fail */ 1008 end_update(ERESTART, RS_REPLY); 1009 return; 1010 } 1011 } 1012 1013 if (rp->r_flags & RS_EXITING) { 1014 /* If a core system service is exiting, we are in trouble. */ 1015 if (rp->r_pub->sys_flags & SF_CORE_SRV && !shutting_down) { 1016 printf("core system service died: %s\n", srv_to_string(rp)); 1017 _exit(1); 1018 } 1019 1020 /* See if a late reply has to be sent. */ 1021 r = (rp->r_caller_request == RS_DOWN ? OK : EDEADEPT); 1022 late_reply(rp, r); 1023 1024 /* Unpublish the service. */ 1025 unpublish_service(rp); 1026 1027 /* Cleanup all the instances of the service. */ 1028 get_service_instances(rp, &rps, &nr_rps); 1029 for(i=0;i<nr_rps;i++) { 1030 cleanup_service(rps[i]); 1031 } 1032 1033 /* If the service is reincarnating, its slot has not been cleaned up. 1034 * Check for this flag now, and attempt to start the service again. 1035 * If this fails, start_service() itself will perform cleanup. 1036 */ 1037 if (rp->r_flags & RS_REINCARNATE) { 1038 reincarnate_service(rp); 1039 } 1040 } 1041 else if(rp->r_flags & RS_REFRESHING) { 1042 /* Restart service. */ 1043 restart_service(rp); 1044 } 1045 else { 1046 /* If an update is in progress, end it. The old version 1047 * that just exited will continue executing. 1048 */ 1049 if(rp->r_flags & RS_UPDATING) { 1050 end_update(ERESTART, RS_DONTREPLY); 1051 } 1052 1053 /* Determine what to do. If this is the first unexpected 1054 * exit, immediately restart this service. Otherwise use 1055 * a binary exponential backoff. 1056 */ 1057 if (rp->r_restarts > 0) { 1058 if (!(rpub->sys_flags & SF_NO_BIN_EXP)) { 1059 rp->r_backoff = 1 << MIN(rp->r_restarts,(BACKOFF_BITS-2)); 1060 rp->r_backoff = MIN(rp->r_backoff,MAX_BACKOFF); 1061 if ((rpub->sys_flags & SF_USE_COPY) && rp->r_backoff > 1) 1062 rp->r_backoff= 1; 1063 } 1064 else { 1065 rp->r_backoff = 1; 1066 } 1067 return; 1068 } 1069 1070 /* Restart service. */ 1071 restart_service(rp); 1072 } 1073 } 1074 1075 /*===========================================================================* 1076 * run_script * 1077 *===========================================================================*/ 1078 static int run_script(struct rproc *rp) 1079 { 1080 int r, endpoint; 1081 pid_t pid; 1082 char *reason; 1083 char incarnation_str[20]; /* Enough for a counter? */ 1084 char *envp[1] = { NULL }; 1085 struct rprocpub *rpub; 1086 1087 rpub = rp->r_pub; 1088 if (rp->r_flags & RS_REFRESHING) 1089 reason= "restart"; 1090 else if (rp->r_flags & RS_NOPINGREPLY) 1091 reason= "no-heartbeat"; 1092 else reason= "terminated"; 1093 sprintf(incarnation_str, "%d", rp->r_restarts); 1094 1095 if(rs_verbose) { 1096 printf("RS: %s:\n", srv_to_string(rp)); 1097 printf("RS: calling script '%s'\n", rp->r_script); 1098 printf("RS: reason: '%s'\n", reason); 1099 printf("RS: incarnation: '%s'\n", incarnation_str); 1100 } 1101 1102 pid= fork(); 1103 switch(pid) 1104 { 1105 case -1: 1106 return kill_service(rp, "unable to fork script", errno); 1107 case 0: 1108 execle(_PATH_BSHELL, "sh", rp->r_script, rpub->label, reason, 1109 incarnation_str, (char*) NULL, envp); 1110 printf("RS: run_script: execl '%s' failed: %s\n", 1111 rp->r_script, strerror(errno)); 1112 exit(1); 1113 default: 1114 /* Set the privilege structure for the child process. */ 1115 if ((r = getprocnr(pid, &endpoint)) != 0) 1116 panic("unable to get child endpoint: %d", r); 1117 if ((r = sys_privctl(endpoint, SYS_PRIV_SET_USER, NULL)) 1118 != OK) { 1119 return kill_service(rp,"can't set script privileges",r); 1120 } 1121 /* Set the script's privileges on other servers. */ 1122 vm_set_priv(endpoint, NULL, FALSE); 1123 if ((r = vm_set_priv(endpoint, NULL, FALSE)) != OK) { 1124 return kill_service(rp,"can't set script VM privs",r); 1125 } 1126 /* Allow the script to run. */ 1127 if ((r = sys_privctl(endpoint, SYS_PRIV_ALLOW, NULL)) != OK) { 1128 return kill_service(rp,"can't let the script run",r); 1129 } 1130 /* Pin RS memory again after fork()ing. */ 1131 vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN); 1132 } 1133 return OK; 1134 } 1135 1136 /*===========================================================================* 1137 * restart_service * 1138 *===========================================================================*/ 1139 void restart_service(struct rproc *rp) 1140 { 1141 /* Restart service via a recovery script or directly. */ 1142 struct rproc *replica_rp; 1143 int r; 1144 1145 /* See if a late reply has to be sent. */ 1146 late_reply(rp, OK); 1147 1148 /* This hack disables restarting of file servers, which at the moment always 1149 * cause VFS to hang indefinitely. As soon as VFS no longer blocks on calls 1150 * to file servers, this exception can be removed again. 1151 */ 1152 if (!strncmp(rp->r_pub->label, "fs_", 3)) { 1153 kill_service(rp, "file servers cannot be restarted yet", ENOSYS); 1154 return; 1155 } 1156 1157 /* Run a recovery script if available. */ 1158 if (rp->r_script[0] != '\0') { 1159 run_script(rp); 1160 return; 1161 } 1162 1163 /* Restart directly. We need a replica if not already available. */ 1164 if(rp->r_next_rp == NULL) { 1165 /* Create the replica. */ 1166 r = clone_service(rp, RST_SYS_PROC); 1167 if(r != OK) { 1168 kill_service(rp, "unable to clone service", r); 1169 return; 1170 } 1171 } 1172 replica_rp = rp->r_next_rp; 1173 1174 /* Update the service into the replica. */ 1175 r = update_service(&rp, &replica_rp, RS_SWAP); 1176 if(r != OK) { 1177 kill_service(rp, "unable to update into new replica", r); 1178 return; 1179 } 1180 1181 /* Let the new replica run. */ 1182 r = run_service(replica_rp, SEF_INIT_RESTART); 1183 if(r != OK) { 1184 kill_service(rp, "unable to let the replica run", r); 1185 return; 1186 } 1187 1188 if(rs_verbose) 1189 printf("RS: %s restarted into %s\n", 1190 srv_to_string(rp), srv_to_string(replica_rp)); 1191 } 1192 1193 /*===========================================================================* 1194 * inherit_service_defaults * 1195 *===========================================================================*/ 1196 void inherit_service_defaults(def_rp, rp) 1197 struct rproc *def_rp; 1198 struct rproc *rp; 1199 { 1200 struct rprocpub *def_rpub; 1201 struct rprocpub *rpub; 1202 1203 def_rpub = def_rp->r_pub; 1204 rpub = rp->r_pub; 1205 1206 /* Device and PCI settings. These properties cannot change. */ 1207 rpub->dev_nr = def_rpub->dev_nr; 1208 rpub->pci_acl = def_rpub->pci_acl; 1209 1210 /* Immutable system and privilege flags. */ 1211 rpub->sys_flags &= ~IMM_SF; 1212 rpub->sys_flags |= (def_rpub->sys_flags & IMM_SF); 1213 rp->r_priv.s_flags &= ~IMM_F; 1214 rp->r_priv.s_flags |= (def_rp->r_priv.s_flags & IMM_F); 1215 1216 /* Allowed traps. They cannot change. */ 1217 rp->r_priv.s_trap_mask = def_rp->r_priv.s_trap_mask; 1218 } 1219 1220 /*===========================================================================* 1221 * get_service_instances * 1222 *===========================================================================*/ 1223 void get_service_instances(rp, rps, length) 1224 struct rproc *rp; 1225 struct rproc ***rps; 1226 int *length; 1227 { 1228 /* Retrieve all the service instances of a given service. */ 1229 static struct rproc *instances[5]; 1230 int nr_instances; 1231 1232 nr_instances = 0; 1233 instances[nr_instances++] = rp; 1234 if(rp->r_prev_rp) instances[nr_instances++] = rp->r_prev_rp; 1235 if(rp->r_next_rp) instances[nr_instances++] = rp->r_next_rp; 1236 if(rp->r_old_rp) instances[nr_instances++] = rp->r_old_rp; 1237 if(rp->r_new_rp) instances[nr_instances++] = rp->r_new_rp; 1238 1239 *rps = instances; 1240 *length = nr_instances; 1241 } 1242 1243 /*===========================================================================* 1244 * share_exec * 1245 *===========================================================================*/ 1246 void share_exec(rp_dst, rp_src) 1247 struct rproc *rp_dst, *rp_src; 1248 { 1249 if(rs_verbose) 1250 printf("RS: %s shares exec image with %s\n", 1251 srv_to_string(rp_dst), srv_to_string(rp_src)); 1252 1253 /* Share exec image from rp_src to rp_dst. */ 1254 rp_dst->r_exec_len = rp_src->r_exec_len; 1255 rp_dst->r_exec = rp_src->r_exec; 1256 } 1257 1258 /*===========================================================================* 1259 * read_exec * 1260 *===========================================================================*/ 1261 int read_exec(rp) 1262 struct rproc *rp; 1263 { 1264 int e, r, fd; 1265 char *e_name; 1266 struct stat sb; 1267 1268 e_name= rp->r_argv[0]; 1269 if(rs_verbose) 1270 printf("RS: service '%s' reads exec image from: %s\n", rp->r_pub->label, 1271 e_name); 1272 1273 r= stat(e_name, &sb); 1274 if (r != 0) 1275 return -errno; 1276 1277 if (sb.st_size < sizeof(Elf_Ehdr)) 1278 return ENOEXEC; 1279 1280 fd= open(e_name, O_RDONLY); 1281 if (fd == -1) 1282 return -errno; 1283 1284 rp->r_exec_len= sb.st_size; 1285 rp->r_exec= malloc(rp->r_exec_len); 1286 if (rp->r_exec == NULL) 1287 { 1288 printf("RS: read_exec: unable to allocate %zu bytes\n", 1289 rp->r_exec_len); 1290 close(fd); 1291 return ENOMEM; 1292 } 1293 1294 r= read(fd, rp->r_exec, rp->r_exec_len); 1295 e= errno; 1296 close(fd); 1297 if (r == rp->r_exec_len) 1298 return OK; 1299 1300 printf("RS: read_exec: read failed %d, errno %d\n", r, e); 1301 1302 free_exec(rp); 1303 1304 if (r >= 0) 1305 return EIO; 1306 else 1307 return -e; 1308 } 1309 1310 /*===========================================================================* 1311 * free_exec * 1312 *===========================================================================*/ 1313 void free_exec(rp) 1314 struct rproc *rp; 1315 { 1316 /* Free an exec image. */ 1317 int slot_nr, has_shared_exec; 1318 struct rproc *other_rp; 1319 1320 /* Search for some other slot sharing the same exec image. */ 1321 has_shared_exec = FALSE; 1322 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) { 1323 other_rp = &rproc[slot_nr]; /* get pointer to slot */ 1324 if (other_rp->r_flags & RS_IN_USE && other_rp != rp 1325 && other_rp->r_exec == rp->r_exec) { /* found! */ 1326 has_shared_exec = TRUE; 1327 break; 1328 } 1329 } 1330 1331 /* If nobody uses our copy of the exec image, we can try to get rid of it. */ 1332 if(!has_shared_exec) { 1333 if(rs_verbose) 1334 printf("RS: %s frees exec image\n", srv_to_string(rp)); 1335 free(rp->r_exec); 1336 } 1337 else { 1338 if(rs_verbose) 1339 printf("RS: %s no longer sharing exec image with %s\n", 1340 srv_to_string(rp), srv_to_string(other_rp)); 1341 } 1342 rp->r_exec = NULL; 1343 rp->r_exec_len = 0; 1344 } 1345 1346 /*===========================================================================* 1347 * edit_slot * 1348 *===========================================================================*/ 1349 int edit_slot(rp, rs_start, source) 1350 struct rproc *rp; 1351 struct rs_start *rs_start; 1352 endpoint_t source; 1353 { 1354 /* Edit a given slot to override existing settings. */ 1355 struct rprocpub *rpub; 1356 char *label; 1357 int len; 1358 int s, i; 1359 int basic_kc[] = { SYS_BASIC_CALLS, NULL_C }; 1360 int basic_vmc[] = { VM_BASIC_CALLS, NULL_C }; 1361 1362 rpub = rp->r_pub; 1363 1364 /* Update IPC target list. */ 1365 if (rs_start->rss_ipclen==0 || rs_start->rss_ipclen+1>sizeof(rp->r_ipc_list)){ 1366 printf("RS: edit_slot: ipc list empty or long for '%s'\n", rpub->label); 1367 return EINVAL; 1368 } 1369 s=sys_datacopy(source, (vir_bytes) rs_start->rss_ipc, 1370 SELF, (vir_bytes) rp->r_ipc_list, rs_start->rss_ipclen); 1371 if (s != OK) return(s); 1372 rp->r_ipc_list[rs_start->rss_ipclen]= '\0'; 1373 1374 /* Update IRQs. */ 1375 if(rs_start->rss_nr_irq == RSS_IRQ_ALL) { 1376 rs_start->rss_nr_irq = 0; 1377 } 1378 else { 1379 rp->r_priv.s_flags |= CHECK_IRQ; 1380 } 1381 if (rs_start->rss_nr_irq > NR_IRQ) { 1382 printf("RS: edit_slot: too many IRQs requested\n"); 1383 return EINVAL; 1384 } 1385 rp->r_nr_irq= rp->r_priv.s_nr_irq= rs_start->rss_nr_irq; 1386 for (i= 0; i<rp->r_priv.s_nr_irq; i++) { 1387 rp->r_irq_tab[i]= rp->r_priv.s_irq_tab[i]= rs_start->rss_irq[i]; 1388 if(rs_verbose) 1389 printf("RS: edit_slot: IRQ %d\n", rp->r_priv.s_irq_tab[i]); 1390 } 1391 1392 /* Update I/O ranges. */ 1393 if(rs_start->rss_nr_io == RSS_IO_ALL) { 1394 rs_start->rss_nr_io = 0; 1395 } 1396 else { 1397 rp->r_priv.s_flags |= CHECK_IO_PORT; 1398 } 1399 if (rs_start->rss_nr_io > NR_IO_RANGE) { 1400 printf("RS: edit_slot: too many I/O ranges requested\n"); 1401 return EINVAL; 1402 } 1403 rp->r_nr_io_range= rp->r_priv.s_nr_io_range= rs_start->rss_nr_io; 1404 for (i= 0; i<rp->r_priv.s_nr_io_range; i++) { 1405 rp->r_priv.s_io_tab[i].ior_base= rs_start->rss_io[i].base; 1406 rp->r_priv.s_io_tab[i].ior_limit= 1407 rs_start->rss_io[i].base+rs_start->rss_io[i].len-1; 1408 rp->r_io_tab[i] = rp->r_priv.s_io_tab[i]; 1409 if(rs_verbose) 1410 printf("RS: edit_slot: I/O [%x..%x]\n", 1411 rp->r_priv.s_io_tab[i].ior_base, 1412 rp->r_priv.s_io_tab[i].ior_limit); 1413 } 1414 1415 /* Update kernel call mask. Inherit basic kernel calls when asked to. */ 1416 memcpy(rp->r_priv.s_k_call_mask, rs_start->rss_system, 1417 sizeof(rp->r_priv.s_k_call_mask)); 1418 if(rs_start->rss_flags & RSS_SYS_BASIC_CALLS) { 1419 fill_call_mask(basic_kc, NR_SYS_CALLS, 1420 rp->r_priv.s_k_call_mask, KERNEL_CALL, FALSE); 1421 } 1422 1423 /* Update VM call mask. Inherit basic VM calls. */ 1424 memcpy(rpub->vm_call_mask, rs_start->rss_vm, 1425 sizeof(rpub->vm_call_mask)); 1426 if(rs_start->rss_flags & RSS_VM_BASIC_CALLS) { 1427 fill_call_mask(basic_vmc, NR_VM_CALLS, 1428 rpub->vm_call_mask, VM_RQ_BASE, FALSE); 1429 } 1430 1431 /* Update control labels. */ 1432 if(rs_start->rss_nr_control > 0) { 1433 int i, s; 1434 if (rs_start->rss_nr_control > RS_NR_CONTROL) { 1435 printf("RS: edit_slot: too many control labels\n"); 1436 return EINVAL; 1437 } 1438 for (i=0; i<rs_start->rss_nr_control; i++) { 1439 s = copy_label(source, rs_start->rss_control[i].l_addr, 1440 rs_start->rss_control[i].l_len, rp->r_control[i], 1441 sizeof(rp->r_control[i])); 1442 if(s != OK) 1443 return s; 1444 } 1445 rp->r_nr_control = rs_start->rss_nr_control; 1446 1447 if (rs_verbose) { 1448 printf("RS: edit_slot: control labels:"); 1449 for (i=0; i<rp->r_nr_control; i++) 1450 printf(" %s", rp->r_control[i]); 1451 printf("\n"); 1452 } 1453 } 1454 1455 /* Update signal manager. */ 1456 rp->r_priv.s_sig_mgr = rs_start->rss_sigmgr; 1457 1458 /* Update scheduling properties if possible. */ 1459 if(rp->r_scheduler != NONE) { 1460 rp->r_scheduler = rs_start->rss_scheduler; 1461 rp->r_priority = rs_start->rss_priority; 1462 rp->r_quantum = rs_start->rss_quantum; 1463 rp->r_cpu = rs_start->rss_cpu; 1464 } 1465 1466 /* Update command and arguments. */ 1467 if (rs_start->rss_cmdlen > MAX_COMMAND_LEN-1) return(E2BIG); 1468 s=sys_datacopy(source, (vir_bytes) rs_start->rss_cmd, 1469 SELF, (vir_bytes) rp->r_cmd, rs_start->rss_cmdlen); 1470 if (s != OK) return(s); 1471 rp->r_cmd[rs_start->rss_cmdlen] = '\0'; /* ensure it is terminated */ 1472 if (rp->r_cmd[0] != '/') return(EINVAL); /* insist on absolute path */ 1473 1474 /* Build cmd dependencies: argv and program name. */ 1475 build_cmd_dep(rp); 1476 1477 /* Update label if not already set. */ 1478 if(!strcmp(rpub->label, "")) { 1479 if(rs_start->rss_label.l_len > 0) { 1480 /* RS_UP caller has supplied a custom label for this service. */ 1481 int s = copy_label(source, rs_start->rss_label.l_addr, 1482 rs_start->rss_label.l_len, rpub->label, sizeof(rpub->label)); 1483 if(s != OK) 1484 return s; 1485 if(rs_verbose) 1486 printf("RS: edit_slot: using label (custom) '%s'\n", rpub->label); 1487 } else { 1488 /* Default label for the service. */ 1489 label = rpub->proc_name; 1490 len= strlen(label); 1491 memcpy(rpub->label, label, len); 1492 rpub->label[len]= '\0'; 1493 if(rs_verbose) 1494 printf("RS: edit_slot: using label (from proc_name) '%s'\n", 1495 rpub->label); 1496 } 1497 } 1498 1499 /* Update recovery script. */ 1500 if (rs_start->rss_scriptlen > MAX_SCRIPT_LEN-1) return(E2BIG); 1501 if (rs_start->rss_script != NULL && !(rpub->sys_flags & SF_CORE_SRV)) { 1502 s=sys_datacopy(source, (vir_bytes) rs_start->rss_script, 1503 SELF, (vir_bytes) rp->r_script, rs_start->rss_scriptlen); 1504 if (s != OK) return(s); 1505 rp->r_script[rs_start->rss_scriptlen] = '\0'; 1506 } 1507 1508 /* Update system flags and in-memory copy. */ 1509 if ((rs_start->rss_flags & RSS_COPY) && !(rpub->sys_flags & SF_USE_COPY)) { 1510 int exst_cpy; 1511 struct rproc *rp2; 1512 struct rprocpub *rpub2; 1513 exst_cpy = 0; 1514 1515 if(rs_start->rss_flags & RSS_REUSE) { 1516 int i; 1517 1518 for(i = 0; i < NR_SYS_PROCS; i++) { 1519 rp2 = &rproc[i]; 1520 if (!(rp2->r_flags & RS_IN_USE)) { 1521 continue; 1522 } 1523 rpub2 = rproc[i].r_pub; 1524 if(strcmp(rpub->proc_name, rpub2->proc_name) == 0 && 1525 (rpub2->sys_flags & SF_USE_COPY)) { 1526 /* We have found the same binary that's 1527 * already been copied */ 1528 exst_cpy = 1; 1529 break; 1530 } 1531 } 1532 } 1533 1534 s = OK; 1535 if(!exst_cpy) 1536 s = read_exec(rp); 1537 else 1538 share_exec(rp, rp2); 1539 1540 if (s != OK) 1541 return s; 1542 1543 rpub->sys_flags |= SF_USE_COPY; 1544 } 1545 if (rs_start->rss_flags & RSS_REPLICA) { 1546 rpub->sys_flags |= SF_USE_REPL; 1547 } 1548 if (rs_start->rss_flags & RSS_NO_BIN_EXP) { 1549 rpub->sys_flags |= SF_NO_BIN_EXP; 1550 } 1551 1552 /* Update period. */ 1553 if(rpub->endpoint != RS_PROC_NR) { 1554 rp->r_period = rs_start->rss_period; 1555 } 1556 1557 /* (Re)initialize privilege settings. */ 1558 init_privs(rp, &rp->r_priv); 1559 1560 return OK; 1561 } 1562 1563 /*===========================================================================* 1564 * init_slot * 1565 *===========================================================================*/ 1566 int init_slot(rp, rs_start, source) 1567 struct rproc *rp; 1568 struct rs_start *rs_start; 1569 endpoint_t source; 1570 { 1571 /* Initialize a slot as requested by the client. */ 1572 struct rprocpub *rpub; 1573 int i; 1574 1575 rpub = rp->r_pub; 1576 1577 /* All dynamically created services get the same sys and privilege flags, and 1578 * allowed traps. Other privilege settings can be specified at runtime. The 1579 * privilege id is dynamically allocated by the kernel. 1580 */ 1581 rpub->sys_flags = DSRV_SF; /* system flags */ 1582 rp->r_priv.s_flags = DSRV_F; /* privilege flags */ 1583 rp->r_priv.s_trap_mask = DSRV_T; /* allowed traps */ 1584 rp->r_priv.s_bak_sig_mgr = NONE; /* backup signal manager */ 1585 1586 /* Initialize uid. */ 1587 rp->r_uid= rs_start->rss_uid; 1588 1589 /* Initialize device driver settings. */ 1590 rpub->dev_nr = rs_start->rss_major; 1591 rpub->devman_id = rs_start->devman_id; 1592 1593 /* Initialize pci settings. */ 1594 if (rs_start->rss_nr_pci_id > RS_NR_PCI_DEVICE) { 1595 printf("RS: init_slot: too many PCI device IDs\n"); 1596 return EINVAL; 1597 } 1598 rpub->pci_acl.rsp_nr_device = rs_start->rss_nr_pci_id; 1599 for (i= 0; i<rpub->pci_acl.rsp_nr_device; i++) { 1600 rpub->pci_acl.rsp_device[i].vid= rs_start->rss_pci_id[i].vid; 1601 rpub->pci_acl.rsp_device[i].did= rs_start->rss_pci_id[i].did; 1602 rpub->pci_acl.rsp_device[i].sub_vid= rs_start->rss_pci_id[i].sub_vid; 1603 rpub->pci_acl.rsp_device[i].sub_did= rs_start->rss_pci_id[i].sub_did; 1604 if(rs_verbose) 1605 printf("RS: init_slot: PCI %04x/%04x (sub %04x:%04x)\n", 1606 rpub->pci_acl.rsp_device[i].vid, 1607 rpub->pci_acl.rsp_device[i].did, 1608 rpub->pci_acl.rsp_device[i].sub_vid, 1609 rpub->pci_acl.rsp_device[i].sub_did); 1610 } 1611 if (rs_start->rss_nr_pci_class > RS_NR_PCI_CLASS) { 1612 printf("RS: init_slot: too many PCI class IDs\n"); 1613 return EINVAL; 1614 } 1615 rpub->pci_acl.rsp_nr_class= rs_start->rss_nr_pci_class; 1616 for (i= 0; i<rpub->pci_acl.rsp_nr_class; i++) { 1617 rpub->pci_acl.rsp_class[i].pciclass=rs_start->rss_pci_class[i].pciclass; 1618 rpub->pci_acl.rsp_class[i].mask= rs_start->rss_pci_class[i].mask; 1619 if(rs_verbose) 1620 printf("RS: init_slot: PCI class %06x mask %06x\n", 1621 (unsigned int) rpub->pci_acl.rsp_class[i].pciclass, 1622 (unsigned int) rpub->pci_acl.rsp_class[i].mask); 1623 } 1624 1625 /* Initialize some fields. */ 1626 rp->r_restarts = 0; /* no restarts yet */ 1627 rp->r_old_rp = NULL; /* no old version yet */ 1628 rp->r_new_rp = NULL; /* no new version yet */ 1629 rp->r_prev_rp = NULL; /* no prev replica yet */ 1630 rp->r_next_rp = NULL; /* no next replica yet */ 1631 rp->r_exec = NULL; /* no in-memory copy yet */ 1632 rp->r_exec_len = 0; 1633 rp->r_script[0]= '\0'; /* no recovery script yet */ 1634 rpub->label[0]= '\0'; /* no label yet */ 1635 rp->r_scheduler = -1; /* no scheduler yet */ 1636 rp->r_priv.s_sig_mgr = -1; /* no signal manager yet */ 1637 1638 /* Initialize editable slot settings. */ 1639 return edit_slot(rp, rs_start, source); 1640 } 1641 1642 /*===========================================================================* 1643 * clone_slot * 1644 *===========================================================================*/ 1645 int clone_slot(rp, clone_rpp) 1646 struct rproc *rp; 1647 struct rproc **clone_rpp; 1648 { 1649 int r; 1650 struct rproc *clone_rp; 1651 struct rprocpub *rpub, *clone_rpub; 1652 1653 /* Allocate a system service slot for the clone. */ 1654 r = alloc_slot(&clone_rp); 1655 if(r != OK) { 1656 printf("RS: clone_slot: unable to allocate a new slot: %d\n", r); 1657 return r; 1658 } 1659 1660 rpub = rp->r_pub; 1661 clone_rpub = clone_rp->r_pub; 1662 1663 /* Synch the privilege structure of the source with the kernel. */ 1664 if ((r = sys_getpriv(&(rp->r_priv), rpub->endpoint)) != OK) { 1665 panic("unable to synch privilege structure: %d", r); 1666 } 1667 1668 /* Shallow copy. */ 1669 *clone_rp = *rp; 1670 *clone_rpub = *rpub; 1671 1672 /* Deep copy. */ 1673 clone_rp->r_flags &= ~RS_ACTIVE; /* the clone is not active yet */ 1674 clone_rp->r_pid = -1; /* no pid yet */ 1675 clone_rpub->endpoint = -1; /* no endpoint yet */ 1676 clone_rp->r_pub = clone_rpub; /* restore pointer to public entry */ 1677 build_cmd_dep(clone_rp); /* rebuild cmd dependencies */ 1678 if(clone_rpub->sys_flags & SF_USE_COPY) { 1679 share_exec(clone_rp, rp); /* share exec image */ 1680 } 1681 clone_rp->r_old_rp = NULL; /* no old version yet */ 1682 clone_rp->r_new_rp = NULL; /* no new version yet */ 1683 clone_rp->r_prev_rp = NULL; /* no prev replica yet */ 1684 clone_rp->r_next_rp = NULL; /* no next replica yet */ 1685 1686 /* Force dynamic privilege id. */ 1687 clone_rp->r_priv.s_flags |= DYN_PRIV_ID; 1688 1689 /* Clear instance flags. */ 1690 clone_rp->r_priv.s_flags &= ~(LU_SYS_PROC | RST_SYS_PROC); 1691 1692 *clone_rpp = clone_rp; 1693 return OK; 1694 } 1695 1696 /*===========================================================================* 1697 * swap_slot_pointer * 1698 *===========================================================================*/ 1699 static void swap_slot_pointer(struct rproc **rpp, struct rproc *src_rp, 1700 struct rproc *dst_rp) 1701 { 1702 if(*rpp == src_rp) { 1703 *rpp = dst_rp; 1704 } 1705 else if(*rpp == dst_rp) { 1706 *rpp = src_rp; 1707 } 1708 } 1709 1710 /*===========================================================================* 1711 * swap_slot * 1712 *===========================================================================*/ 1713 void swap_slot(src_rpp, dst_rpp) 1714 struct rproc **src_rpp; 1715 struct rproc **dst_rpp; 1716 { 1717 /* Swap two service slots. */ 1718 struct rproc *src_rp; 1719 struct rproc *dst_rp; 1720 struct rprocpub *src_rpub; 1721 struct rprocpub *dst_rpub; 1722 struct rproc orig_src_rproc, orig_dst_rproc; 1723 struct rprocpub orig_src_rprocpub, orig_dst_rprocpub; 1724 1725 src_rp = *src_rpp; 1726 dst_rp = *dst_rpp; 1727 src_rpub = src_rp->r_pub; 1728 dst_rpub = dst_rp->r_pub; 1729 1730 /* Save existing data first. */ 1731 orig_src_rproc = *src_rp; 1732 orig_src_rprocpub = *src_rpub; 1733 orig_dst_rproc = *dst_rp; 1734 orig_dst_rprocpub = *dst_rpub; 1735 1736 /* Swap slots. */ 1737 *src_rp = orig_dst_rproc; 1738 *src_rpub = orig_dst_rprocpub; 1739 *dst_rp = orig_src_rproc; 1740 *dst_rpub = orig_src_rprocpub; 1741 1742 /* Restore public entries. */ 1743 src_rp->r_pub = orig_src_rproc.r_pub; 1744 dst_rp->r_pub = orig_dst_rproc.r_pub; 1745 1746 /* Rebuild command dependencies. */ 1747 build_cmd_dep(src_rp); 1748 build_cmd_dep(dst_rp); 1749 1750 /* Swap local slot pointers. */ 1751 swap_slot_pointer(&src_rp->r_prev_rp, src_rp, dst_rp); 1752 swap_slot_pointer(&src_rp->r_next_rp, src_rp, dst_rp); 1753 swap_slot_pointer(&src_rp->r_old_rp, src_rp, dst_rp); 1754 swap_slot_pointer(&src_rp->r_new_rp, src_rp, dst_rp); 1755 swap_slot_pointer(&dst_rp->r_prev_rp, src_rp, dst_rp); 1756 swap_slot_pointer(&dst_rp->r_next_rp, src_rp, dst_rp); 1757 swap_slot_pointer(&dst_rp->r_old_rp, src_rp, dst_rp); 1758 swap_slot_pointer(&dst_rp->r_new_rp, src_rp, dst_rp); 1759 1760 /* Swap global slot pointers. */ 1761 swap_slot_pointer(&rupdate.rp, src_rp, dst_rp); 1762 swap_slot_pointer(&rproc_ptr[_ENDPOINT_P(src_rp->r_pub->endpoint)], 1763 src_rp, dst_rp); 1764 swap_slot_pointer(&rproc_ptr[_ENDPOINT_P(dst_rp->r_pub->endpoint)], 1765 src_rp, dst_rp); 1766 1767 /* Adjust input pointers. */ 1768 *src_rpp = dst_rp; 1769 *dst_rpp = src_rp; 1770 } 1771 1772 /*===========================================================================* 1773 * lookup_slot_by_label * 1774 *===========================================================================*/ 1775 struct rproc* lookup_slot_by_label(char *label) 1776 { 1777 /* Lookup a service slot matching the given label. */ 1778 int slot_nr; 1779 struct rproc *rp; 1780 struct rprocpub *rpub; 1781 1782 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) { 1783 rp = &rproc[slot_nr]; 1784 if (!(rp->r_flags & RS_ACTIVE)) { 1785 continue; 1786 } 1787 rpub = rp->r_pub; 1788 if (strcmp(rpub->label, label) == 0) { 1789 return rp; 1790 } 1791 } 1792 1793 return NULL; 1794 } 1795 1796 /*===========================================================================* 1797 * lookup_slot_by_pid * 1798 *===========================================================================*/ 1799 struct rproc* lookup_slot_by_pid(pid_t pid) 1800 { 1801 /* Lookup a service slot matching the given pid. */ 1802 int slot_nr; 1803 struct rproc *rp; 1804 1805 if(pid < 0) { 1806 return NULL; 1807 } 1808 1809 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) { 1810 rp = &rproc[slot_nr]; 1811 if (!(rp->r_flags & RS_IN_USE)) { 1812 continue; 1813 } 1814 if (rp->r_pid == pid) { 1815 return rp; 1816 } 1817 } 1818 1819 return NULL; 1820 } 1821 1822 /*===========================================================================* 1823 * lookup_slot_by_dev_nr * 1824 *===========================================================================*/ 1825 struct rproc* lookup_slot_by_dev_nr(dev_t dev_nr) 1826 { 1827 /* Lookup a service slot matching the given device number. */ 1828 int slot_nr; 1829 struct rproc *rp; 1830 struct rprocpub *rpub; 1831 1832 if(dev_nr <= 0) { 1833 return NULL; 1834 } 1835 1836 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) { 1837 rp = &rproc[slot_nr]; 1838 rpub = rp->r_pub; 1839 if (!(rp->r_flags & RS_IN_USE)) { 1840 continue; 1841 } 1842 if (rpub->dev_nr == dev_nr) { 1843 return rp; 1844 } 1845 } 1846 1847 return NULL; 1848 } 1849 1850 /*===========================================================================* 1851 * lookup_slot_by_flags * 1852 *===========================================================================*/ 1853 struct rproc* lookup_slot_by_flags(int flags) 1854 { 1855 /* Lookup a service slot matching the given flags. */ 1856 int slot_nr; 1857 struct rproc *rp; 1858 1859 if(!flags) { 1860 return NULL; 1861 } 1862 1863 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) { 1864 rp = &rproc[slot_nr]; 1865 if (!(rp->r_flags & RS_IN_USE)) { 1866 continue; 1867 } 1868 if (rp->r_flags & flags) { 1869 return rp; 1870 } 1871 } 1872 1873 return NULL; 1874 } 1875 1876 /*===========================================================================* 1877 * alloc_slot * 1878 *===========================================================================*/ 1879 int alloc_slot(rpp) 1880 struct rproc **rpp; 1881 { 1882 /* Alloc a new system service slot. */ 1883 int slot_nr; 1884 1885 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) { 1886 *rpp = &rproc[slot_nr]; /* get pointer to slot */ 1887 if (!((*rpp)->r_flags & RS_IN_USE)) /* check if available */ 1888 break; 1889 } 1890 if (slot_nr >= NR_SYS_PROCS) { 1891 return ENOMEM; 1892 } 1893 1894 return OK; 1895 } 1896 1897 /*===========================================================================* 1898 * free_slot * 1899 *===========================================================================*/ 1900 void free_slot(rp) 1901 struct rproc *rp; 1902 { 1903 /* Free a system service slot. */ 1904 struct rprocpub *rpub; 1905 1906 rpub = rp->r_pub; 1907 1908 /* Send a late reply if there is any pending. */ 1909 late_reply(rp, OK); 1910 1911 /* Free memory if necessary. */ 1912 if(rpub->sys_flags & SF_USE_COPY) { 1913 free_exec(rp); 1914 } 1915 1916 /* Mark slot as no longer in use.. */ 1917 rp->r_flags = 0; 1918 rp->r_pid = -1; 1919 rpub->in_use = FALSE; 1920 rproc_ptr[_ENDPOINT_P(rpub->endpoint)] = NULL; 1921 } 1922 1923 1924 /*===========================================================================* 1925 * get_next_name * 1926 *===========================================================================*/ 1927 static char *get_next_name(ptr, name, caller_label) 1928 char *ptr; 1929 char *name; 1930 char *caller_label; 1931 { 1932 /* Get the next name from the list of (IPC) program names. 1933 */ 1934 char *p, *q; 1935 size_t len; 1936 1937 for (p= ptr; p[0] != '\0'; p= q) 1938 { 1939 /* Skip leading space */ 1940 while (p[0] != '\0' && isspace((unsigned char)p[0])) 1941 p++; 1942 1943 /* Find start of next word */ 1944 q= p; 1945 while (q[0] != '\0' && !isspace((unsigned char)q[0])) 1946 q++; 1947 if (q == p) 1948 continue; 1949 len= q-p; 1950 if (len > RS_MAX_LABEL_LEN) 1951 { 1952 printf( 1953 "rs:get_next_name: bad ipc list entry '%.*s' for %s: too long\n", 1954 (int) len, p, caller_label); 1955 continue; 1956 } 1957 memcpy(name, p, len); 1958 name[len]= '\0'; 1959 1960 return q; /* found another */ 1961 } 1962 1963 return NULL; /* done */ 1964 } 1965 1966 /*===========================================================================* 1967 * add_forward_ipc * 1968 *===========================================================================*/ 1969 void add_forward_ipc(rp, privp) 1970 struct rproc *rp; 1971 struct priv *privp; 1972 { 1973 /* Add IPC send permissions to a process based on that process's IPC 1974 * list. 1975 */ 1976 char name[RS_MAX_LABEL_LEN+1], *p; 1977 struct rproc *rrp; 1978 endpoint_t endpoint; 1979 int r; 1980 int priv_id; 1981 struct priv priv; 1982 struct rprocpub *rpub; 1983 1984 rpub = rp->r_pub; 1985 p = rp->r_ipc_list; 1986 1987 while ((p = get_next_name(p, name, rpub->label)) != NULL) { 1988 1989 if (strcmp(name, "SYSTEM") == 0) 1990 endpoint= SYSTEM; 1991 else if (strcmp(name, "USER") == 0) 1992 endpoint= INIT_PROC_NR; /* all user procs */ 1993 else 1994 { 1995 /* Set a privilege bit for every process matching the 1996 * given process name. It is perfectly fine if this 1997 * loop does not find any matches, as the target 1998 * process(es) may not have been started yet. See 1999 * add_backward_ipc() below. 2000 */ 2001 for (rrp=BEG_RPROC_ADDR; rrp<END_RPROC_ADDR; rrp++) { 2002 if (!(rrp->r_flags & RS_IN_USE)) 2003 continue; 2004 2005 if (!strcmp(rrp->r_pub->proc_name, name)) { 2006 #if PRIV_DEBUG 2007 printf(" RS: add_forward_ipc: setting" 2008 " sendto bit for %d...\n", 2009 rrp->r_pub->endpoint); 2010 #endif 2011 2012 priv_id= rrp->r_priv.s_id; 2013 set_sys_bit(privp->s_ipc_to, priv_id); 2014 } 2015 } 2016 2017 continue; 2018 } 2019 2020 /* This code only applies to the exception cases. */ 2021 if ((r = sys_getpriv(&priv, endpoint)) < 0) 2022 { 2023 printf( 2024 "add_forward_ipc: unable to get priv_id for '%s': %d\n", 2025 name, r); 2026 continue; 2027 } 2028 2029 #if PRIV_DEBUG 2030 printf(" RS: add_forward_ipc: setting sendto bit for %d...\n", 2031 endpoint); 2032 #endif 2033 priv_id= priv.s_id; 2034 set_sys_bit(privp->s_ipc_to, priv_id); 2035 } 2036 } 2037 2038 2039 /*===========================================================================* 2040 * add_backward_ipc * 2041 *===========================================================================*/ 2042 void add_backward_ipc(rp, privp) 2043 struct rproc *rp; 2044 struct priv *privp; 2045 { 2046 /* Add IPC send permissions to a process based on other processes' IPC 2047 * lists. This is enough to allow each such two processes to talk to 2048 * each other, as the kernel guarantees send mask symmetry. We need to 2049 * add these permissions now because the current process may not yet 2050 * have existed at the time that the other process was initialized. 2051 */ 2052 char name[RS_MAX_LABEL_LEN+1], *p; 2053 struct rproc *rrp; 2054 struct rprocpub *rrpub; 2055 char *proc_name; 2056 int priv_id, is_ipc_all, is_ipc_all_sys; 2057 2058 proc_name = rp->r_pub->proc_name; 2059 2060 for (rrp=BEG_RPROC_ADDR; rrp<END_RPROC_ADDR; rrp++) { 2061 if (!(rrp->r_flags & RS_IN_USE)) 2062 continue; 2063 2064 if (!rrp->r_ipc_list[0]) 2065 continue; 2066 2067 /* If the process being checked is set to allow IPC to all 2068 * other processes, or for all other system processes and the 2069 * target process is a system process, add a permission bit. 2070 */ 2071 rrpub = rrp->r_pub; 2072 2073 is_ipc_all = !strcmp(rrp->r_ipc_list, RSS_IPC_ALL); 2074 is_ipc_all_sys = !strcmp(rrp->r_ipc_list, RSS_IPC_ALL_SYS); 2075 2076 if (is_ipc_all || 2077 (is_ipc_all_sys && (privp->s_flags & SYS_PROC))) { 2078 #if PRIV_DEBUG 2079 printf(" RS: add_backward_ipc: setting sendto bit " 2080 "for %d...\n", rrpub->endpoint); 2081 #endif 2082 priv_id= rrp->r_priv.s_id; 2083 set_sys_bit(privp->s_ipc_to, priv_id); 2084 2085 continue; 2086 } 2087 2088 /* An IPC target list was provided for the process being 2089 * checked here. Make sure that the name of the new process 2090 * is in that process's list. There may be multiple matches. 2091 */ 2092 p = rrp->r_ipc_list; 2093 2094 while ((p = get_next_name(p, name, rrpub->label)) != NULL) { 2095 if (!strcmp(proc_name, name)) { 2096 #if PRIV_DEBUG 2097 printf(" RS: add_backward_ipc: setting sendto" 2098 " bit for %d...\n", 2099 rrpub->endpoint); 2100 #endif 2101 priv_id= rrp->r_priv.s_id; 2102 set_sys_bit(privp->s_ipc_to, priv_id); 2103 } 2104 } 2105 } 2106 } 2107 2108 2109 /*===========================================================================* 2110 * init_privs * 2111 *===========================================================================*/ 2112 void init_privs(rp, privp) 2113 struct rproc *rp; 2114 struct priv *privp; 2115 { 2116 int i; 2117 int is_ipc_all, is_ipc_all_sys; 2118 2119 /* Clear s_ipc_to */ 2120 fill_send_mask(&privp->s_ipc_to, FALSE); 2121 2122 is_ipc_all = !strcmp(rp->r_ipc_list, RSS_IPC_ALL); 2123 is_ipc_all_sys = !strcmp(rp->r_ipc_list, RSS_IPC_ALL_SYS); 2124 2125 #if PRIV_DEBUG 2126 printf(" RS: init_privs: ipc list is '%s'...\n", rp->r_ipc_list); 2127 #endif 2128 2129 if (!is_ipc_all && !is_ipc_all_sys) 2130 { 2131 add_forward_ipc(rp, privp); 2132 add_backward_ipc(rp, privp); 2133 2134 } 2135 else 2136 { 2137 for (i= 0; i<NR_SYS_PROCS; i++) 2138 { 2139 if (is_ipc_all || i != USER_PRIV_ID) 2140 set_sys_bit(privp->s_ipc_to, i); 2141 } 2142 } 2143 } 2144 2145