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