mkfs: drop support for running on DOS
[minix.git] / servers / rs / manager.c
blob0dc7a76d8555f18eed8304581532b786c5851276
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 */
8 #include "inc.h"
10 #include "kernel/proc.h"
12 /*===========================================================================*
13 * caller_is_root *
14 *===========================================================================*/
15 static int caller_is_root(endpoint)
16 endpoint_t endpoint; /* caller endpoint */
18 uid_t euid;
20 /* Check if caller has root user ID. */
21 euid = getnuid(endpoint);
22 if (rs_verbose && euid != 0)
24 printf("RS: got unauthorized request from endpoint %d\n", endpoint);
27 return euid == 0;
30 /*===========================================================================*
31 * caller_can_control *
32 *===========================================================================*/
33 static int caller_can_control(endpoint, target_rp)
34 endpoint_t endpoint;
35 struct rproc *target_rp;
37 int control_allowed = 0;
38 register struct rproc *rp;
39 register struct rprocpub *rpub;
40 char *proc_name;
41 int c;
43 proc_name = target_rp->r_pub->proc_name;
45 /* Check if label is listed in caller's isolation policy. */
46 for (rp = BEG_RPROC_ADDR; rp < END_RPROC_ADDR; rp++) {
47 if (!(rp->r_flags & RS_IN_USE))
48 continue;
50 rpub = rp->r_pub;
51 if (rpub->endpoint == endpoint) {
52 break;
55 if (rp == END_RPROC_ADDR) return 0;
57 for (c = 0; c < rp->r_nr_control; c++) {
58 if (strcmp(rp->r_control[c], proc_name) == 0) {
59 control_allowed = 1;
60 break;
64 if (rs_verbose)
65 printf("RS: allowing %u control over %s via policy: %s\n",
66 endpoint, target_rp->r_pub->label,
67 control_allowed ? "yes" : "no");
69 return control_allowed;
72 /*===========================================================================*
73 * check_call_permission *
74 *===========================================================================*/
75 int check_call_permission(caller, call, rp)
76 endpoint_t caller;
77 int call;
78 struct rproc *rp;
80 /* Check if the caller has permission to execute a particular call. */
81 struct rprocpub *rpub;
82 int call_allowed;
84 /* Caller should be either root or have control privileges. */
85 call_allowed = caller_is_root(caller);
86 if(rp) {
87 call_allowed |= caller_can_control(caller, rp);
89 if(!call_allowed) {
90 return EPERM;
93 if(rp) {
94 rpub = rp->r_pub;
96 /* Only allow RS_EDIT if the target is a user process. */
97 if(!(rp->r_priv.s_flags & SYS_PROC)) {
98 if(call != RS_EDIT) return EPERM;
101 /* Disallow the call if another call is in progress for the service. */
102 if((rp->r_flags & RS_LATEREPLY)
103 || (rp->r_flags & RS_INITIALIZING) || (rp->r_flags & RS_UPDATING)) {
104 return EBUSY;
107 /* Only allow RS_DOWN and RS_RESTART if the service has terminated. */
108 if(rp->r_flags & RS_TERMINATED) {
109 if(call != RS_DOWN && call != RS_RESTART) return EPERM;
112 /* Disallow RS_DOWN for core system services. */
113 if (rpub->sys_flags & SF_CORE_SRV) {
114 if(call == RS_DOWN) return EPERM;
118 return OK;
121 /*===========================================================================*
122 * copy_rs_start *
123 *===========================================================================*/
124 int copy_rs_start(src_e, src_rs_start, dst_rs_start)
125 endpoint_t src_e;
126 char *src_rs_start;
127 struct rs_start *dst_rs_start;
129 int r;
131 r = sys_datacopy(src_e, (vir_bytes) src_rs_start,
132 SELF, (vir_bytes) dst_rs_start, sizeof(struct rs_start));
134 return r;
137 /*===========================================================================*
138 * copy_label *
139 *===========================================================================*/
140 int copy_label(src_e, src_label, src_len, dst_label, dst_len)
141 endpoint_t src_e;
142 char *src_label;
143 size_t src_len;
144 char *dst_label;
145 size_t dst_len;
147 int s, len;
149 len = MIN(dst_len-1, src_len);
151 s = sys_datacopy(src_e, (vir_bytes) src_label,
152 SELF, (vir_bytes) dst_label, len);
153 if (s != OK) return s;
155 dst_label[len] = 0;
157 return OK;
160 /*===========================================================================*
161 * build_cmd_dep *
162 *===========================================================================*/
163 void build_cmd_dep(struct rproc *rp)
165 struct rprocpub *rpub;
166 int arg_count;
167 int len;
168 char *cmd_ptr;
170 rpub = rp->r_pub;
172 /* Build argument vector to be passed to execute call. The format of the
173 * arguments vector is: path, arguments, NULL.
175 strcpy(rp->r_args, rp->r_cmd); /* copy raw command */
176 arg_count = 0; /* initialize arg count */
177 rp->r_argv[arg_count++] = rp->r_args; /* start with path */
178 cmd_ptr = rp->r_args; /* do some parsing */
179 while(*cmd_ptr != '\0') { /* stop at end of string */
180 if (*cmd_ptr == ' ') { /* next argument */
181 *cmd_ptr = '\0'; /* terminate previous */
182 while (*++cmd_ptr == ' ') ; /* skip spaces */
183 if (*cmd_ptr == '\0') break; /* no arg following */
184 /* There are ARGV_ELEMENTS elements; must leave one for null */
185 if (arg_count>=ARGV_ELEMENTS-1) { /* arg vector full */
186 printf("RS: build_cmd_dep: too many args\n");
187 break;
189 assert(arg_count < ARGV_ELEMENTS);
190 rp->r_argv[arg_count++] = cmd_ptr; /* add to arg vector */
192 cmd_ptr ++; /* continue parsing */
194 assert(arg_count < ARGV_ELEMENTS);
195 rp->r_argv[arg_count] = NULL; /* end with NULL pointer */
196 rp->r_argc = arg_count;
198 /* Build process name. */
199 cmd_ptr = strrchr(rp->r_argv[0], '/');
200 if (cmd_ptr)
201 cmd_ptr++;
202 else
203 cmd_ptr= rp->r_argv[0];
204 len= strlen(cmd_ptr);
205 if (len > RS_MAX_LABEL_LEN-1)
206 len= RS_MAX_LABEL_LEN-1; /* truncate name */
207 memcpy(rpub->proc_name, cmd_ptr, len);
208 rpub->proc_name[len]= '\0';
211 /*===========================================================================*
212 * srv_fork *
213 *===========================================================================*/
214 pid_t srv_fork(uid_t reuid, gid_t regid)
216 message m;
218 m.m1_i1 = (int) reuid;
219 m.m1_i2 = (int) regid;
220 return _syscall(PM_PROC_NR, SRV_FORK, &m);
223 /*===========================================================================*
224 * srv_kill *
225 *===========================================================================*/
226 int srv_kill(pid_t pid, int sig)
228 message m;
230 m.m1_i1 = pid;
231 m.m1_i2 = sig;
232 return(_syscall(PM_PROC_NR, SRV_KILL, &m));
235 /*===========================================================================*
236 * srv_update *
237 *===========================================================================*/
238 int srv_update(endpoint_t src_e, endpoint_t dst_e)
240 int r;
242 /* Ask VM to swap the slots of the two processes and tell the kernel to
243 * do the same. If VM is the service being updated, only perform the kernel
244 * part of the call. The new instance of VM will do the rest at
245 * initialization time.
247 if(src_e != VM_PROC_NR) {
248 r = vm_update(src_e, dst_e);
250 else {
251 r = sys_update(src_e, dst_e);
254 return r;
257 /*===========================================================================*
258 * update_period *
259 *===========================================================================*/
260 void update_period(message *m_ptr)
262 clock_t now = m_ptr->NOTIFY_TIMESTAMP;
263 short has_update_timed_out;
264 message m;
265 struct rprocpub *rpub;
267 rpub = rupdate.rp->r_pub;
269 /* See if a timeout has occurred. */
270 has_update_timed_out = (now - rupdate.prepare_tm > rupdate.prepare_maxtime);
272 /* If an update timed out, end the update process and notify
273 * the old version that the update has been canceled. From now on, the old
274 * version will continue executing.
276 if(has_update_timed_out) {
277 printf("RS: update failed: maximum prepare time reached\n");
278 end_update(EINTR, RS_DONTREPLY);
280 /* Prepare cancel request. */
281 m.m_type = RS_LU_PREPARE;
282 m.RS_LU_STATE = SEF_LU_STATE_NULL;
283 if(rpub->endpoint == RS_PROC_NR) {
284 /* RS can process the request directly. */
285 do_sef_lu_request(&m);
287 else {
288 /* Send request message to the system service. */
289 asynsend(rpub->endpoint, &m);
294 /*===========================================================================*
295 * end_update *
296 *===========================================================================*/
297 void end_update(int result, int reply_flag)
299 /* End the update process. There are two possibilities:
300 * 1) the update succeeded. In that case, cleanup the old version and mark the
301 * new version as no longer under update.
302 * 2) the update failed. In that case, cleanup the new version and mark the old
303 * version as no longer under update. Eventual late ready to update
304 * messages (if any) will simply be ignored and the service can
305 * continue executing. In addition, reset the check timestamp, so that if the
306 * service has a period, a status request will be forced in the next period.
308 struct rproc *old_rp, *new_rp, *exiting_rp, *surviving_rp;
309 struct rproc **rps;
310 int nr_rps, i;
312 old_rp = rupdate.rp;
313 new_rp = old_rp->r_new_rp;
315 if(rs_verbose)
316 printf("RS: ending update from %s to %s with result: %d\n",
317 srv_to_string(old_rp), srv_to_string(new_rp), result);
319 /* Decide which version has to die out and which version has to survive. */
320 surviving_rp = (result == OK ? new_rp : old_rp);
321 exiting_rp = (result == OK ? old_rp : new_rp);
323 /* End update. */
324 rupdate.flags &= ~RS_UPDATING;
325 rupdate.rp = NULL;
326 old_rp->r_new_rp = NULL;
327 new_rp->r_old_rp = NULL;
328 old_rp->r_check_tm = 0;
330 /* Send a late reply if necessary. */
331 late_reply(old_rp, result);
333 /* Mark the version that has to survive as no longer updating and
334 * reply when asked to.
336 surviving_rp->r_flags &= ~RS_UPDATING;
337 if(reply_flag == RS_REPLY) {
338 message m;
339 m.m_type = result;
340 reply(surviving_rp->r_pub->endpoint, surviving_rp, &m);
343 /* Cleanup the version that has to die out. */
344 get_service_instances(exiting_rp, &rps, &nr_rps);
345 for(i=0;i<nr_rps;i++) {
346 cleanup_service(rps[i]);
349 if(rs_verbose)
350 printf("RS: %s ended the update\n", srv_to_string(surviving_rp));
353 /*===========================================================================*
354 * kill_service_debug *
355 *===========================================================================*/
356 int kill_service_debug(file, line, rp, errstr, err)
357 char *file;
358 int line;
359 struct rproc *rp;
360 char *errstr;
361 int err;
363 /* Crash a system service and don't let it restart. */
364 if(errstr && !shutting_down) {
365 printf("RS: %s (error %d)\n", errstr, err);
367 rp->r_flags |= RS_EXITING; /* expect exit */
368 crash_service_debug(file, line, rp); /* simulate crash */
370 return err;
373 /*===========================================================================*
374 * crash_service_debug *
375 *===========================================================================*/
376 int crash_service_debug(file, line, rp)
377 char *file;
378 int line;
379 struct rproc *rp;
381 /* Simluate a crash in a system service. */
382 struct rprocpub *rpub;
384 rpub = rp->r_pub;
386 if(rs_verbose)
387 printf("RS: %s %skilled at %s:%d\n", srv_to_string(rp),
388 rp->r_flags & RS_EXITING ? "lethally " : "", file, line);
390 /* RS should simply exit() directly. */
391 if(rpub->endpoint == RS_PROC_NR) {
392 exit(1);
395 return sys_kill(rpub->endpoint, SIGKILL);
398 /*===========================================================================*
399 * cleanup_service_debug *
400 *===========================================================================*/
401 void cleanup_service_debug(file, line, rp)
402 char *file;
403 int line;
404 struct rproc *rp;
406 struct rprocpub *rpub;
407 int s;
409 rpub = rp->r_pub;
411 if(rs_verbose)
412 printf("RS: %s cleaned up at %s:%d\n", srv_to_string(rp),
413 file, line);
415 /* Tell scheduler this process is finished */
416 if ((s = sched_stop(rp->r_scheduler, rpub->endpoint)) != OK) {
417 printf("RS: warning: scheduler won't give up process: %d\n", s);
420 /* Ask PM to exit the service */
421 if(rp->r_pid == -1) {
422 printf("RS: warning: attempt to kill pid -1!\n");
424 else {
425 srv_kill(rp->r_pid, SIGKILL);
428 /* Free slot, unless we're about to reuse it */
429 if (!(rp->r_flags & RS_REINCARNATE))
430 free_slot(rp);
433 /*===========================================================================*
434 * create_service *
435 *===========================================================================*/
436 int create_service(rp)
437 struct rproc *rp;
439 /* Create the given system service. */
440 int child_proc_nr_e, child_proc_nr_n; /* child process slot */
441 pid_t child_pid; /* child's process id */
442 int s, use_copy, has_replica;
443 extern char **environ;
444 struct rprocpub *rpub;
446 rpub = rp->r_pub;
447 use_copy= (rpub->sys_flags & SF_USE_COPY);
448 has_replica= (rp->r_old_rp
449 || (rp->r_prev_rp && !(rp->r_prev_rp->r_flags & RS_TERMINATED)));
451 /* Do we need an existing replica to create the service? */
452 if(!has_replica && (rpub->sys_flags & SF_NEED_REPL)) {
453 printf("RS: unable to create service '%s' without a replica\n",
454 rpub->label);
455 free_slot(rp);
456 return(EPERM);
459 /* Do we need an in-memory copy to create the service? */
460 if(!use_copy && (rpub->sys_flags & SF_NEED_COPY)) {
461 printf("RS: unable to create service '%s' without an in-memory copy\n",
462 rpub->label);
463 free_slot(rp);
464 return(EPERM);
467 /* Do we have a copy or a command to create the service? */
468 if(!use_copy && !strcmp(rp->r_cmd, "")) {
469 printf("RS: unable to create service '%s' without a copy or command\n",
470 rpub->label);
471 free_slot(rp);
472 return(EPERM);
475 /* Now fork and branch for parent and child process (and check for error).
476 * After fork()ing, we need to pin RS memory again or pagefaults will occur
477 * on future writes.
479 if(rs_verbose)
480 printf("RS: forking child with srv_fork()...\n");
481 child_pid= srv_fork(rp->r_uid, 0); /* Force group to operator for now */
482 if(child_pid == -1) {
483 printf("RS: srv_fork() failed (error %d)\n", errno);
484 free_slot(rp);
485 return(errno);
488 /* Get endpoint of the child. */
489 child_proc_nr_e = getnprocnr(child_pid);
491 /* There is now a child process. Update the system process table. */
492 child_proc_nr_n = _ENDPOINT_P(child_proc_nr_e);
493 rp->r_flags = RS_IN_USE; /* mark slot in use */
494 rpub->endpoint = child_proc_nr_e; /* set child endpoint */
495 rp->r_pid = child_pid; /* set child pid */
496 rp->r_check_tm = 0; /* not checked yet */
497 getuptime(&rp->r_alive_tm); /* currently alive */
498 rp->r_stop_tm = 0; /* not exiting yet */
499 rp->r_backoff = 0; /* not to be restarted */
500 rproc_ptr[child_proc_nr_n] = rp; /* mapping for fast access */
501 rpub->in_use = TRUE; /* public entry is now in use */
503 /* Set and synch the privilege structure for the new service. */
504 if ((s = sys_privctl(child_proc_nr_e, SYS_PRIV_SET_SYS, &rp->r_priv)) != OK
505 || (s = sys_getpriv(&rp->r_priv, child_proc_nr_e)) != OK) {
506 printf("RS: unable to set privilege structure: %d\n", s);
507 cleanup_service(rp);
508 vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
509 return ENOMEM;
512 /* Set the scheduler for this process */
513 if ((s = sched_init_proc(rp)) != OK) {
514 printf("RS: unable to start scheduling: %d\n", s);
515 cleanup_service(rp);
516 vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
517 return s;
520 /* Copy the executable image into the child process. If no copy exists,
521 * allocate one and free it right after exec completes.
523 if(use_copy) {
524 if(rs_verbose)
525 printf("RS: %s uses an in-memory copy\n",
526 srv_to_string(rp));
528 else {
529 if ((s = read_exec(rp)) != OK) {
530 printf("RS: read_exec failed: %d\n", s);
531 cleanup_service(rp);
532 vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
533 return s;
536 if(rs_verbose)
537 printf("RS: execing child with srv_execve()...\n");
538 s = srv_execve(child_proc_nr_e, rp->r_exec, rp->r_exec_len, rp->r_argv,
539 environ);
540 vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
541 if (s != OK) {
542 printf("RS: srv_execve failed: %d\n", s);
543 cleanup_service(rp);
544 return s;
546 if(!use_copy) {
547 free_exec(rp);
550 /* If this is a VM instance, let VM know now. */
551 if(rp->r_priv.s_flags & VM_SYS_PROC) {
552 if(rs_verbose)
553 printf("RS: informing VM of instance %s\n", srv_to_string(rp));
555 s = vm_memctl(rpub->endpoint, VM_RS_MEM_MAKE_VM);
556 if(s != OK) {
557 printf("vm_memctl failed: %d\n", s);
558 cleanup_service(rp);
559 return s;
563 /* Tell VM about allowed calls. */
564 if ((s = vm_set_priv(rpub->endpoint, &rpub->vm_call_mask[0])) != OK) {
565 printf("RS: vm_set_priv failed: %d\n", s);
566 cleanup_service(rp);
567 return s;
570 if(rs_verbose)
571 printf("RS: %s created\n", srv_to_string(rp));
573 return OK;
576 /*===========================================================================*
577 * clone_service *
578 *===========================================================================*/
579 int clone_service(rp, instance_flag)
580 struct rproc *rp;
581 int instance_flag;
583 /* Clone the given system service instance. */
584 struct rproc *replica_rp;
585 struct rprocpub *replica_rpub;
586 struct rproc **rp_link;
587 struct rproc **replica_link;
588 struct rproc *rs_rp;
589 int rs_flags;
590 int r;
592 if(rs_verbose)
593 printf("RS: creating a replica for %s\n", srv_to_string(rp));
595 /* Clone slot. */
596 if((r = clone_slot(rp, &replica_rp)) != OK) {
597 return r;
599 replica_rpub = replica_rp->r_pub;
601 /* Clone is a live updated or restarted service instance? */
602 if(instance_flag == LU_SYS_PROC) {
603 rp_link = &rp->r_new_rp;
604 replica_link = &replica_rp->r_old_rp;
606 else {
607 rp_link = &rp->r_next_rp;
608 replica_link = &replica_rp->r_prev_rp;
610 replica_rp->r_priv.s_flags |= instance_flag;
612 /* Link the two slots. */
613 *rp_link = replica_rp;
614 *replica_link = rp;
616 /* Create a new replica of the service. */
617 r = create_service(replica_rp);
618 if(r != OK) {
619 *rp_link = NULL;
620 return r;
623 /* If this instance is for restarting RS, set up a backup signal manager. */
624 rs_flags = (ROOT_SYS_PROC | RST_SYS_PROC);
625 if((replica_rp->r_priv.s_flags & rs_flags) == rs_flags) {
626 rs_rp = rproc_ptr[_ENDPOINT_P(RS_PROC_NR)];
628 /* Update signal managers. */
629 r = update_sig_mgrs(rs_rp, SELF, replica_rpub->endpoint);
630 if(r == OK) {
631 r = update_sig_mgrs(replica_rp, SELF, NONE);
633 if(r != OK) {
634 *rp_link = NULL;
635 return kill_service(replica_rp, "update_sig_mgrs failed", r);
639 return OK;
642 /*===========================================================================*
643 * publish_service *
644 *===========================================================================*/
645 int publish_service(rp)
646 struct rproc *rp; /* pointer to service slot */
648 /* Publish a service. */
649 int r;
650 struct rprocpub *rpub;
651 struct rs_pci pci_acl;
652 message m;
653 endpoint_t ep;
655 rpub = rp->r_pub;
657 /* Register label with DS. */
658 r = ds_publish_label(rpub->label, rpub->endpoint, DSF_OVERWRITE);
659 if (r != OK) {
660 return kill_service(rp, "ds_publish_label call failed", r);
663 /* If the service is a driver, map it. */
664 if (rpub->dev_nr > 0) {
665 /* The purpose of non-blocking forks is to avoid involving VFS in the
666 * forking process, because VFS may be blocked on a sendrec() to a MFS
667 * that is waiting for a endpoint update for a dead driver. We have just
668 * published that update, but VFS may still be blocked. As a result, VFS
669 * may not yet have received PM's fork message. Hence, if we call
670 * mapdriver() immediately, VFS may not know about the process and thus
671 * refuse to add the driver entry. The following temporary hack works
672 * around this by forcing blocking communication from PM to VFS. Once VFS
673 * has been made non-blocking towards MFS instances, this hack and the
674 * big part of srv_fork() can go.
676 setuid(0);
678 if (mapdriver(rpub->label, rpub->dev_nr, rpub->dev_style,
679 rpub->dev_flags) != OK) {
680 return kill_service(rp, "couldn't map driver", errno);
684 #if USE_PCI
685 /* If PCI properties are set, inform the PCI driver about the new service. */
686 if(rpub->pci_acl.rsp_nr_device || rpub->pci_acl.rsp_nr_class) {
687 pci_acl = rpub->pci_acl;
688 strcpy(pci_acl.rsp_label, rpub->label);
689 pci_acl.rsp_endpoint= rpub->endpoint;
691 r = pci_set_acl(&pci_acl);
692 if (r != OK) {
693 return kill_service(rp, "pci_set_acl call failed", r);
696 #endif /* USE_PCI */
698 if (rpub->devman_id != 0) {
699 r = ds_retrieve_label_endpt("devman",&ep);
701 if (r != OK) {
702 return kill_service(rp, "devman not running?", r);
704 m.m_type = DEVMAN_BIND;
705 m.DEVMAN_ENDPOINT = rpub->endpoint;
706 m.DEVMAN_DEVICE_ID = rpub->devman_id;
707 r = sendrec(ep, &m);
708 if (r != OK || m.DEVMAN_RESULT != OK) {
709 return kill_service(rp, "devman bind device failed", r);
713 if(rs_verbose)
714 printf("RS: %s published\n", srv_to_string(rp));
716 return OK;
719 /*===========================================================================*
720 * unpublish_service *
721 *===========================================================================*/
722 int unpublish_service(rp)
723 struct rproc *rp; /* pointer to service slot */
725 /* Unpublish a service. */
726 struct rprocpub *rpub;
727 int r, result;
728 message m;
729 endpoint_t ep;
732 rpub = rp->r_pub;
733 result = OK;
735 /* Unregister label with DS. */
736 r = ds_delete_label(rpub->label);
737 if (r != OK && !shutting_down) {
738 printf("RS: ds_delete_label call failed (error %d)\n", r);
739 result = r;
742 /* No need to inform VFS and VM, cleanup is done on exit automatically. */
744 #if USE_PCI
745 /* If PCI properties are set, inform the PCI driver. */
746 if(rpub->pci_acl.rsp_nr_device || rpub->pci_acl.rsp_nr_class) {
747 r = pci_del_acl(rpub->endpoint);
748 if (r != OK && !shutting_down) {
749 printf("RS: pci_del_acl call failed (error %d)\n", r);
750 result = r;
753 #endif /* USE_PCI */
755 if (rpub->devman_id != 0) {
756 r = ds_retrieve_label_endpt("devman",&ep);
758 if (r != OK) {
759 printf("RS: devman not running?");
760 } else {
761 m.m_type = DEVMAN_UNBIND;
762 m.DEVMAN_ENDPOINT = rpub->endpoint;
763 m.DEVMAN_DEVICE_ID = rpub->devman_id;
764 r = sendrec(ep, &m);
766 if (r != OK || m.DEVMAN_RESULT != OK) {
767 printf("RS: devman unbind device failed");
772 if(rs_verbose)
773 printf("RS: %s unpublished\n", srv_to_string(rp));
775 return result;
778 /*===========================================================================*
779 * run_service *
780 *===========================================================================*/
781 int run_service(rp, init_type)
782 struct rproc *rp;
783 int init_type;
785 /* Let a newly created service run. */
786 struct rprocpub *rpub;
787 int s;
789 rpub = rp->r_pub;
791 /* Allow the service to run. */
792 if ((s = sys_privctl(rpub->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
793 return kill_service(rp, "unable to allow the service to run",s);
796 /* Initialize service. */
797 if((s = init_service(rp, init_type)) != OK) {
798 return kill_service(rp, "unable to initialize service", s);
801 if(rs_verbose)
802 printf("RS: %s allowed to run\n", srv_to_string(rp));
804 return OK;
807 /*===========================================================================*
808 * start_service *
809 *===========================================================================*/
810 int start_service(rp)
811 struct rproc *rp;
813 /* Start a system service. */
814 int r, init_type;
815 struct rprocpub *rpub;
817 rpub = rp->r_pub;
819 /* Create and make active. */
820 r = create_service(rp);
821 if(r != OK) {
822 return r;
824 activate_service(rp, NULL);
826 /* Publish service properties. */
827 r = publish_service(rp);
828 if (r != OK) {
829 return r;
832 /* Run. */
833 init_type = SEF_INIT_FRESH;
834 r = run_service(rp, init_type);
835 if(r != OK) {
836 return r;
839 if(rs_verbose)
840 printf("RS: %s started with major %d\n", srv_to_string(rp),
841 rpub->dev_nr);
843 return OK;
846 /*===========================================================================*
847 * stop_service *
848 *===========================================================================*/
849 void stop_service(struct rproc *rp,int how)
851 struct rprocpub *rpub;
852 int signo;
854 rpub = rp->r_pub;
856 /* Try to stop the system service. First send a SIGTERM signal to ask the
857 * system service to terminate. If the service didn't install a signal
858 * handler, it will be killed. If it did and ignores the signal, we'll
859 * find out because we record the time here and send a SIGKILL.
861 if(rs_verbose)
862 printf("RS: %s signaled with SIGTERM\n", srv_to_string(rp));
864 signo = rpub->endpoint != RS_PROC_NR ? SIGTERM : SIGHUP; /* SIGHUP for RS. */
866 rp->r_flags |= how; /* what to on exit? */
867 sys_kill(rpub->endpoint, signo); /* first try friendly */
868 getuptime(&rp->r_stop_tm); /* record current time */
871 /*===========================================================================*
872 * update_service *
873 *===========================================================================*/
874 int update_service(src_rpp, dst_rpp, swap_flag)
875 struct rproc **src_rpp;
876 struct rproc **dst_rpp;
877 int swap_flag;
879 /* Update an existing service. */
880 int r;
881 struct rproc *src_rp;
882 struct rproc *dst_rp;
883 struct rprocpub *src_rpub;
884 struct rprocpub *dst_rpub;
885 int pid;
886 endpoint_t endpoint;
888 src_rp = *src_rpp;
889 dst_rp = *dst_rpp;
890 src_rpub = src_rp->r_pub;
891 dst_rpub = dst_rp->r_pub;
893 if(rs_verbose)
894 printf("RS: %s updating into %s\n",
895 srv_to_string(src_rp), srv_to_string(dst_rp));
897 /* Swap the slots of the two processes when asked to. */
898 if(swap_flag == RS_SWAP) {
899 if((r = srv_update(src_rpub->endpoint, dst_rpub->endpoint)) != OK) {
900 return r;
904 /* Swap slots here as well. */
905 pid = src_rp->r_pid;
906 endpoint = src_rpub->endpoint;
907 swap_slot(&src_rp, &dst_rp);
909 /* Reassign pids and endpoints. */
910 src_rp->r_pid = dst_rp->r_pid;
911 src_rp->r_pub->endpoint = dst_rp->r_pub->endpoint;
912 rproc_ptr[_ENDPOINT_P(src_rp->r_pub->endpoint)] = src_rp;
913 dst_rp->r_pid = pid;
914 dst_rp->r_pub->endpoint = endpoint;
915 rproc_ptr[_ENDPOINT_P(dst_rp->r_pub->endpoint)] = dst_rp;
917 /* Adjust input pointers. */
918 *src_rpp = src_rp;
919 *dst_rpp = dst_rp;
921 /* Make the new version active. */
922 activate_service(dst_rp, src_rp);
924 if(rs_verbose)
925 printf("RS: %s updated into %s\n",
926 srv_to_string(src_rp), srv_to_string(dst_rp));
928 return OK;
931 /*===========================================================================*
932 * activate_service *
933 *===========================================================================*/
934 void activate_service(struct rproc *rp, struct rproc *ex_rp)
936 /* Activate a service instance and deactivate another one if requested. */
938 if(ex_rp && (ex_rp->r_flags & RS_ACTIVE) ) {
939 ex_rp->r_flags &= ~RS_ACTIVE;
940 if(rs_verbose)
941 printf("RS: %s becomes inactive\n", srv_to_string(ex_rp));
944 if(! (rp->r_flags & RS_ACTIVE) ) {
945 rp->r_flags |= RS_ACTIVE;
946 if(rs_verbose)
947 printf("RS: %s becomes active\n", srv_to_string(rp));
951 /*===========================================================================*
952 * reincarnate_service *
953 *===========================================================================*/
954 void reincarnate_service(struct rproc *rp)
956 /* Restart a service as if it were never started before. */
957 struct rprocpub *rpub;
958 int i;
960 rpub = rp->r_pub;
962 rp->r_flags &= RS_IN_USE;
963 rp->r_pid = -1;
964 rproc_ptr[_ENDPOINT_P(rpub->endpoint)] = NULL;
966 /* Restore original IRQ and I/O range tables in the priv struct. This is the
967 * only part of the privilege structure that can be modified by processes
968 * other than RS itself.
970 rp->r_priv.s_nr_irq = rp->r_nr_irq;
971 for (i = 0; i < rp->r_nr_irq; i++)
972 rp->r_priv.s_irq_tab[i] = rp->r_irq_tab[i];
973 rp->r_priv.s_nr_io_range = rp->r_nr_io_range;
974 for (i = 0; i < rp->r_nr_io_range; i++)
975 rp->r_priv.s_io_tab[i] = rp->r_io_tab[i];
977 rp->r_old_rp = NULL;
978 rp->r_new_rp = NULL;
979 rp->r_prev_rp = NULL;
980 rp->r_next_rp = NULL;
982 start_service(rp);
985 /*===========================================================================*
986 * terminate_service *
987 *===========================================================================*/
988 void terminate_service(struct rproc *rp)
990 /* Handle a termination event for a system service. */
991 struct rproc **rps;
992 struct rprocpub *rpub;
993 int nr_rps;
994 int i, r;
996 rpub = rp->r_pub;
998 if(rs_verbose)
999 printf("RS: %s terminated\n", srv_to_string(rp));
1001 /* Deal with failures during initialization. */
1002 if(rp->r_flags & RS_INITIALIZING) {
1003 if(rs_verbose)
1004 printf("RS: service '%s' exited during initialization\n",
1005 rpub->label);
1006 rp->r_flags |= RS_EXITING; /* don't restart. */
1008 /* If updating, rollback. */
1009 if(rp->r_flags & RS_UPDATING) {
1010 struct rproc *old_rp, *new_rp;
1011 printf("RS: update failed: state transfer failed. Rolling back...\n");
1012 new_rp = rp;
1013 old_rp = new_rp->r_old_rp;
1014 new_rp->r_flags &= ~RS_INITIALIZING;
1015 r = update_service(&new_rp, &old_rp, RS_SWAP);
1016 assert(r == OK); /* can't fail */
1017 end_update(ERESTART, RS_REPLY);
1018 return;
1022 if (rp->r_flags & RS_EXITING) {
1023 /* If a core system service is exiting, we are in trouble. */
1024 if (rp->r_pub->sys_flags & SF_CORE_SRV && !shutting_down) {
1025 printf("core system service died: %s\n", srv_to_string(rp));
1026 _exit(1);
1029 /* See if a late reply has to be sent. */
1030 r = (rp->r_caller_request == RS_DOWN ? OK : EDEADEPT);
1031 late_reply(rp, r);
1033 /* Unpublish the service. */
1034 unpublish_service(rp);
1036 /* Cleanup all the instances of the service. */
1037 get_service_instances(rp, &rps, &nr_rps);
1038 for(i=0;i<nr_rps;i++) {
1039 cleanup_service(rps[i]);
1042 /* If the service is reincarnating, its slot has not been cleaned up.
1043 * Check for this flag now, and attempt to start the service again.
1044 * If this fails, start_service() itself will perform cleanup.
1046 if (rp->r_flags & RS_REINCARNATE) {
1047 reincarnate_service(rp);
1050 else if(rp->r_flags & RS_REFRESHING) {
1051 /* Restart service. */
1052 restart_service(rp);
1054 else {
1055 /* If an update is in progress, end it. The old version
1056 * that just exited will continue executing.
1058 if(rp->r_flags & RS_UPDATING) {
1059 end_update(ERESTART, RS_DONTREPLY);
1062 /* Determine what to do. If this is the first unexpected
1063 * exit, immediately restart this service. Otherwise use
1064 * a binary exponential backoff.
1066 if (rp->r_restarts > 0) {
1067 rp->r_backoff = 1 << MIN(rp->r_restarts,(BACKOFF_BITS-2));
1068 rp->r_backoff = MIN(rp->r_backoff,MAX_BACKOFF);
1069 if ((rpub->sys_flags & SF_USE_COPY) && rp->r_backoff > 1)
1070 rp->r_backoff= 1;
1071 return;
1074 /* Restart service. */
1075 restart_service(rp);
1079 /*===========================================================================*
1080 * run_script *
1081 *===========================================================================*/
1082 static int run_script(struct rproc *rp)
1084 int r, endpoint;
1085 pid_t pid;
1086 char *reason;
1087 char incarnation_str[20]; /* Enough for a counter? */
1088 char *envp[1] = { NULL };
1089 struct rprocpub *rpub;
1091 rpub = rp->r_pub;
1092 if (rp->r_flags & RS_REFRESHING)
1093 reason= "restart";
1094 else if (rp->r_flags & RS_NOPINGREPLY)
1095 reason= "no-heartbeat";
1096 else reason= "terminated";
1097 sprintf(incarnation_str, "%d", rp->r_restarts);
1099 if(rs_verbose) {
1100 printf("RS: %s:\n", srv_to_string(rp));
1101 printf("RS: calling script '%s'\n", rp->r_script);
1102 printf("RS: reason: '%s'\n", reason);
1103 printf("RS: incarnation: '%s'\n", incarnation_str);
1106 pid= fork();
1107 switch(pid)
1109 case -1:
1110 return kill_service(rp, "unable to fork script", errno);
1111 case 0:
1112 execle(rp->r_script, rp->r_script, rpub->label, reason,
1113 incarnation_str, (char*) NULL, envp);
1114 printf("RS: run_script: execl '%s' failed: %s\n",
1115 rp->r_script, strerror(errno));
1116 exit(1);
1117 default:
1118 /* Set the privilege structure for the child process. */
1119 endpoint = getnprocnr(pid);
1120 if ((r = sys_privctl(endpoint, SYS_PRIV_SET_USER, NULL))
1121 != OK) {
1122 return kill_service(rp,"can't set script privileges",r);
1124 /* Allow the script to run. */
1125 if ((r = sys_privctl(endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
1126 return kill_service(rp,"can't let the script run",r);
1128 /* Pin RS memory again after fork()ing. */
1129 vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
1131 return OK;
1134 /*===========================================================================*
1135 * restart_service *
1136 *===========================================================================*/
1137 void restart_service(struct rproc *rp)
1139 /* Restart service via a recovery script or directly. */
1140 struct rproc *replica_rp;
1141 int r;
1143 /* See if a late reply has to be sent. */
1144 late_reply(rp, OK);
1146 /* This hack disables restarting of file servers, which at the moment always
1147 * cause VFS to hang indefinitely. As soon as VFS no longer blocks on calls
1148 * to file servers, this exception can be removed again.
1150 if (!strncmp(rp->r_pub->label, "fs_", 3)) {
1151 kill_service(rp, "file servers cannot be restarted yet", ENOSYS);
1152 return;
1155 /* Run a recovery script if available. */
1156 if (rp->r_script[0] != '\0') {
1157 run_script(rp);
1158 return;
1161 /* Restart directly. We need a replica if not already available. */
1162 if(rp->r_next_rp == NULL) {
1163 /* Create the replica. */
1164 r = clone_service(rp, RST_SYS_PROC);
1165 if(r != OK) {
1166 kill_service(rp, "unable to clone service", r);
1167 return;
1170 replica_rp = rp->r_next_rp;
1172 /* Update the service into the replica. */
1173 r = update_service(&rp, &replica_rp, RS_SWAP);
1174 if(r != OK) {
1175 kill_service(rp, "unable to update into new replica", r);
1176 return;
1179 /* Let the new replica run. */
1180 r = run_service(replica_rp, SEF_INIT_RESTART);
1181 if(r != OK) {
1182 kill_service(rp, "unable to let the replica run", r);
1183 return;
1186 if(rs_verbose)
1187 printf("RS: %s restarted into %s\n",
1188 srv_to_string(rp), srv_to_string(replica_rp));
1191 /*===========================================================================*
1192 * inherit_service_defaults *
1193 *===========================================================================*/
1194 void inherit_service_defaults(def_rp, rp)
1195 struct rproc *def_rp;
1196 struct rproc *rp;
1198 struct rprocpub *def_rpub;
1199 struct rprocpub *rpub;
1201 def_rpub = def_rp->r_pub;
1202 rpub = rp->r_pub;
1204 /* Device and PCI settings. These properties cannot change. */
1205 rpub->dev_flags = def_rpub->dev_flags;
1206 rpub->dev_nr = def_rpub->dev_nr;
1207 rpub->dev_style = def_rpub->dev_style;
1208 rpub->dev_style2 = def_rpub->dev_style2;
1209 rpub->pci_acl = def_rpub->pci_acl;
1211 /* Immutable system and privilege flags. */
1212 rpub->sys_flags &= ~IMM_SF;
1213 rpub->sys_flags |= (def_rpub->sys_flags & IMM_SF);
1214 rp->r_priv.s_flags &= ~IMM_F;
1215 rp->r_priv.s_flags |= (def_rp->r_priv.s_flags & IMM_F);
1217 /* Allowed traps. They cannot change. */
1218 rp->r_priv.s_trap_mask = def_rp->r_priv.s_trap_mask;
1221 /*===========================================================================*
1222 * get_service_instances *
1223 *===========================================================================*/
1224 void get_service_instances(rp, rps, length)
1225 struct rproc *rp;
1226 struct rproc ***rps;
1227 int *length;
1229 /* Retrieve all the service instances of a given service. */
1230 static struct rproc *instances[5];
1231 int nr_instances;
1233 nr_instances = 0;
1234 instances[nr_instances++] = rp;
1235 if(rp->r_prev_rp) instances[nr_instances++] = rp->r_prev_rp;
1236 if(rp->r_next_rp) instances[nr_instances++] = rp->r_next_rp;
1237 if(rp->r_old_rp) instances[nr_instances++] = rp->r_old_rp;
1238 if(rp->r_new_rp) instances[nr_instances++] = rp->r_new_rp;
1240 *rps = instances;
1241 *length = nr_instances;
1244 /*===========================================================================*
1245 * share_exec *
1246 *===========================================================================*/
1247 void share_exec(rp_dst, rp_src)
1248 struct rproc *rp_dst, *rp_src;
1250 if(rs_verbose)
1251 printf("RS: %s shares exec image with %s\n",
1252 srv_to_string(rp_dst), srv_to_string(rp_src));
1254 /* Share exec image from rp_src to rp_dst. */
1255 rp_dst->r_exec_len = rp_src->r_exec_len;
1256 rp_dst->r_exec = rp_src->r_exec;
1259 /*===========================================================================*
1260 * read_exec *
1261 *===========================================================================*/
1262 int read_exec(rp)
1263 struct rproc *rp;
1265 int e, r, fd;
1266 char *e_name;
1267 struct stat sb;
1269 e_name= rp->r_argv[0];
1270 if(rs_verbose)
1271 printf("RS: service '%s' reads exec image from: %s\n", rp->r_pub->label,
1272 e_name);
1274 r= stat(e_name, &sb);
1275 if (r != 0)
1276 return -errno;
1278 fd= open(e_name, O_RDONLY);
1279 if (fd == -1)
1280 return -errno;
1282 rp->r_exec_len= sb.st_size;
1283 rp->r_exec= malloc(rp->r_exec_len);
1284 if (rp->r_exec == NULL)
1286 printf("RS: read_exec: unable to allocate %d bytes\n",
1287 rp->r_exec_len);
1288 close(fd);
1289 return ENOMEM;
1292 r= read(fd, rp->r_exec, rp->r_exec_len);
1293 e= errno;
1294 close(fd);
1295 if (r == rp->r_exec_len)
1296 return OK;
1298 printf("RS: read_exec: read failed %d, errno %d\n", r, e);
1300 free_exec(rp);
1302 if (r >= 0)
1303 return EIO;
1304 else
1305 return -e;
1308 /*===========================================================================*
1309 * free_exec *
1310 *===========================================================================*/
1311 void free_exec(rp)
1312 struct rproc *rp;
1314 /* Free an exec image. */
1315 int slot_nr, has_shared_exec;
1316 struct rproc *other_rp;
1318 /* Search for some other slot sharing the same exec image. */
1319 has_shared_exec = FALSE;
1320 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
1321 other_rp = &rproc[slot_nr]; /* get pointer to slot */
1322 if (other_rp->r_flags & RS_IN_USE && other_rp != rp
1323 && other_rp->r_exec == rp->r_exec) { /* found! */
1324 has_shared_exec = TRUE;
1325 break;
1329 /* If nobody uses our copy of the exec image, we can try to get rid of it. */
1330 if(!has_shared_exec) {
1331 if(rs_verbose)
1332 printf("RS: %s frees exec image\n", srv_to_string(rp));
1333 free(rp->r_exec);
1335 else {
1336 if(rs_verbose)
1337 printf("RS: %s no longer sharing exec image with %s\n",
1338 srv_to_string(rp), srv_to_string(other_rp));
1340 rp->r_exec = NULL;
1341 rp->r_exec_len = 0;
1344 /*===========================================================================*
1345 * edit_slot *
1346 *===========================================================================*/
1347 int edit_slot(rp, rs_start, source)
1348 struct rproc *rp;
1349 struct rs_start *rs_start;
1350 endpoint_t source;
1352 /* Edit a given slot to override existing settings. */
1353 struct rprocpub *rpub;
1354 char *label;
1355 int len;
1356 int s, i;
1357 int basic_kc[] = { SYS_BASIC_CALLS, NULL_C };
1358 int basic_vmc[] = { VM_BASIC_CALLS, NULL_C };
1360 rpub = rp->r_pub;
1362 /* Update IPC target list. */
1363 if (rs_start->rss_ipclen==0 || rs_start->rss_ipclen+1>sizeof(rp->r_ipc_list)){
1364 printf("RS: edit_slot: ipc list empty or long for '%s'\n", rpub->label);
1365 return EINVAL;
1367 s=sys_datacopy(source, (vir_bytes) rs_start->rss_ipc,
1368 SELF, (vir_bytes) rp->r_ipc_list, rs_start->rss_ipclen);
1369 if (s != OK) return(s);
1370 rp->r_ipc_list[rs_start->rss_ipclen]= '\0';
1372 /* Update IRQs. */
1373 if(rs_start->rss_nr_irq == RSS_IRQ_ALL) {
1374 rs_start->rss_nr_irq = 0;
1376 else {
1377 rp->r_priv.s_flags |= CHECK_IRQ;
1379 if (rs_start->rss_nr_irq > NR_IRQ) {
1380 printf("RS: edit_slot: too many IRQs requested\n");
1381 return EINVAL;
1383 rp->r_nr_irq= rp->r_priv.s_nr_irq= rs_start->rss_nr_irq;
1384 for (i= 0; i<rp->r_priv.s_nr_irq; i++) {
1385 rp->r_irq_tab[i]= rp->r_priv.s_irq_tab[i]= rs_start->rss_irq[i];
1386 if(rs_verbose)
1387 printf("RS: edit_slot: IRQ %d\n", rp->r_priv.s_irq_tab[i]);
1390 /* Update I/O ranges. */
1391 if(rs_start->rss_nr_io == RSS_IO_ALL) {
1392 rs_start->rss_nr_io = 0;
1394 else {
1395 rp->r_priv.s_flags |= CHECK_IO_PORT;
1397 if (rs_start->rss_nr_io > NR_IO_RANGE) {
1398 printf("RS: edit_slot: too many I/O ranges requested\n");
1399 return EINVAL;
1401 rp->r_nr_io_range= rp->r_priv.s_nr_io_range= rs_start->rss_nr_io;
1402 for (i= 0; i<rp->r_priv.s_nr_io_range; i++) {
1403 rp->r_priv.s_io_tab[i].ior_base= rs_start->rss_io[i].base;
1404 rp->r_priv.s_io_tab[i].ior_limit=
1405 rs_start->rss_io[i].base+rs_start->rss_io[i].len-1;
1406 rp->r_io_tab[i] = rp->r_priv.s_io_tab[i];
1407 if(rs_verbose)
1408 printf("RS: edit_slot: I/O [%x..%x]\n",
1409 rp->r_priv.s_io_tab[i].ior_base,
1410 rp->r_priv.s_io_tab[i].ior_limit);
1413 /* Update kernel call mask. Inherit basic kernel calls when asked to. */
1414 memcpy(rp->r_priv.s_k_call_mask, rs_start->rss_system,
1415 sizeof(rp->r_priv.s_k_call_mask));
1416 if(rs_start->rss_flags & RSS_SYS_BASIC_CALLS) {
1417 fill_call_mask(basic_kc, NR_SYS_CALLS,
1418 rp->r_priv.s_k_call_mask, KERNEL_CALL, FALSE);
1421 /* Update VM call mask. Inherit basic VM calls. */
1422 memcpy(rpub->vm_call_mask, rs_start->rss_vm,
1423 sizeof(rpub->vm_call_mask));
1424 if(rs_start->rss_flags & RSS_VM_BASIC_CALLS) {
1425 fill_call_mask(basic_vmc, NR_VM_CALLS,
1426 rpub->vm_call_mask, VM_RQ_BASE, FALSE);
1429 /* Update control labels. */
1430 if(rs_start->rss_nr_control > 0) {
1431 int i, s;
1432 if (rs_start->rss_nr_control > RS_NR_CONTROL) {
1433 printf("RS: edit_slot: too many control labels\n");
1434 return EINVAL;
1436 for (i=0; i<rs_start->rss_nr_control; i++) {
1437 s = copy_label(source, rs_start->rss_control[i].l_addr,
1438 rs_start->rss_control[i].l_len, rp->r_control[i],
1439 sizeof(rp->r_control[i]));
1440 if(s != OK)
1441 return s;
1443 rp->r_nr_control = rs_start->rss_nr_control;
1445 if (rs_verbose) {
1446 printf("RS: edit_slot: control labels:");
1447 for (i=0; i<rp->r_nr_control; i++)
1448 printf(" %s", rp->r_control[i]);
1449 printf("\n");
1453 /* Update signal manager. */
1454 rp->r_priv.s_sig_mgr = rs_start->rss_sigmgr;
1456 /* Update scheduling properties if possible. */
1457 if(rp->r_scheduler != NONE) {
1458 rp->r_scheduler = rs_start->rss_scheduler;
1459 rp->r_priority = rs_start->rss_priority;
1460 rp->r_quantum = rs_start->rss_quantum;
1461 rp->r_cpu = rs_start->rss_cpu;
1464 /* Update command and arguments. */
1465 if (rs_start->rss_cmdlen > MAX_COMMAND_LEN-1) return(E2BIG);
1466 s=sys_datacopy(source, (vir_bytes) rs_start->rss_cmd,
1467 SELF, (vir_bytes) rp->r_cmd, rs_start->rss_cmdlen);
1468 if (s != OK) return(s);
1469 rp->r_cmd[rs_start->rss_cmdlen] = '\0'; /* ensure it is terminated */
1470 if (rp->r_cmd[0] != '/') return(EINVAL); /* insist on absolute path */
1472 /* Build cmd dependencies: argv and program name. */
1473 build_cmd_dep(rp);
1475 /* Update label if not already set. */
1476 if(!strcmp(rpub->label, "")) {
1477 if(rs_start->rss_label.l_len > 0) {
1478 /* RS_UP caller has supplied a custom label for this service. */
1479 int s = copy_label(source, rs_start->rss_label.l_addr,
1480 rs_start->rss_label.l_len, rpub->label, sizeof(rpub->label));
1481 if(s != OK)
1482 return s;
1483 if(rs_verbose)
1484 printf("RS: edit_slot: using label (custom) '%s'\n", rpub->label);
1485 } else {
1486 /* Default label for the service. */
1487 label = rpub->proc_name;
1488 len= strlen(label);
1489 memcpy(rpub->label, label, len);
1490 rpub->label[len]= '\0';
1491 if(rs_verbose)
1492 printf("RS: edit_slot: using label (from proc_name) '%s'\n",
1493 rpub->label);
1497 /* Update recovery script. */
1498 if (rs_start->rss_scriptlen > MAX_SCRIPT_LEN-1) return(E2BIG);
1499 if (rs_start->rss_script != NULL && !(rpub->sys_flags & SF_CORE_SRV)) {
1500 s=sys_datacopy(source, (vir_bytes) rs_start->rss_script,
1501 SELF, (vir_bytes) rp->r_script, rs_start->rss_scriptlen);
1502 if (s != OK) return(s);
1503 rp->r_script[rs_start->rss_scriptlen] = '\0';
1506 /* Update system flags and in-memory copy. */
1507 if ((rs_start->rss_flags & RSS_COPY) && !(rpub->sys_flags & SF_USE_COPY)) {
1508 int exst_cpy;
1509 struct rproc *rp2;
1510 struct rprocpub *rpub2;
1511 exst_cpy = 0;
1513 if(rs_start->rss_flags & RSS_REUSE) {
1514 int i;
1516 for(i = 0; i < NR_SYS_PROCS; i++) {
1517 rp2 = &rproc[i];
1518 if (!(rp2->r_flags & RS_IN_USE)) {
1519 continue;
1521 rpub2 = rproc[i].r_pub;
1522 if(strcmp(rpub->proc_name, rpub2->proc_name) == 0 &&
1523 (rpub2->sys_flags & SF_USE_COPY)) {
1524 /* We have found the same binary that's
1525 * already been copied */
1526 exst_cpy = 1;
1527 break;
1532 s = OK;
1533 if(!exst_cpy)
1534 s = read_exec(rp);
1535 else
1536 share_exec(rp, rp2);
1538 if (s != OK)
1539 return s;
1541 rpub->sys_flags |= SF_USE_COPY;
1543 if (rs_start->rss_flags & RSS_REPLICA) {
1544 rpub->sys_flags |= SF_USE_REPL;
1547 /* Update period. */
1548 if(rpub->endpoint != RS_PROC_NR) {
1549 rp->r_period = rs_start->rss_period;
1552 /* (Re)initialize privilege settings. */
1553 init_privs(rp, &rp->r_priv);
1555 return OK;
1558 /*===========================================================================*
1559 * init_slot *
1560 *===========================================================================*/
1561 int init_slot(rp, rs_start, source)
1562 struct rproc *rp;
1563 struct rs_start *rs_start;
1564 endpoint_t source;
1566 /* Initialize a slot as requested by the client. */
1567 struct rprocpub *rpub;
1568 int i;
1570 rpub = rp->r_pub;
1572 /* All dynamically created services get the same sys and privilege flags, and
1573 * allowed traps. Other privilege settings can be specified at runtime. The
1574 * privilege id is dynamically allocated by the kernel.
1576 rpub->sys_flags = DSRV_SF; /* system flags */
1577 rp->r_priv.s_flags = DSRV_F; /* privilege flags */
1578 rp->r_priv.s_trap_mask = DSRV_T; /* allowed traps */
1579 rp->r_priv.s_bak_sig_mgr = NONE; /* backup signal manager */
1581 /* Initialize uid. */
1582 rp->r_uid= rs_start->rss_uid;
1584 /* Initialize device driver settings. */
1585 rpub->dev_flags = DSRV_DF;
1586 rpub->dev_nr = rs_start->rss_major;
1587 rpub->dev_style = rs_start->rss_dev_style;
1588 rpub->devman_id = rs_start->devman_id;
1589 if(rpub->dev_nr && !IS_DEV_STYLE(rs_start->rss_dev_style)) {
1590 printf("RS: init_slot: bad device style\n");
1591 return EINVAL;
1593 rpub->dev_style2 = STYLE_NDEV;
1595 /* Initialize pci settings. */
1596 if (rs_start->rss_nr_pci_id > RS_NR_PCI_DEVICE) {
1597 printf("RS: init_slot: too many PCI device IDs\n");
1598 return EINVAL;
1600 rpub->pci_acl.rsp_nr_device = rs_start->rss_nr_pci_id;
1601 for (i= 0; i<rpub->pci_acl.rsp_nr_device; i++) {
1602 rpub->pci_acl.rsp_device[i].vid= rs_start->rss_pci_id[i].vid;
1603 rpub->pci_acl.rsp_device[i].did= rs_start->rss_pci_id[i].did;
1604 if(rs_verbose)
1605 printf("RS: init_slot: PCI %04x/%04x\n",
1606 rpub->pci_acl.rsp_device[i].vid,
1607 rpub->pci_acl.rsp_device[i].did);
1609 if (rs_start->rss_nr_pci_class > RS_NR_PCI_CLASS) {
1610 printf("RS: init_slot: too many PCI class IDs\n");
1611 return EINVAL;
1613 rpub->pci_acl.rsp_nr_class= rs_start->rss_nr_pci_class;
1614 for (i= 0; i<rpub->pci_acl.rsp_nr_class; i++) {
1615 rpub->pci_acl.rsp_class[i].pciclass=rs_start->rss_pci_class[i].pciclass;
1616 rpub->pci_acl.rsp_class[i].mask= rs_start->rss_pci_class[i].mask;
1617 if(rs_verbose)
1618 printf("RS: init_slot: PCI class %06x mask %06x\n",
1619 (unsigned int) rpub->pci_acl.rsp_class[i].pciclass,
1620 (unsigned int) rpub->pci_acl.rsp_class[i].mask);
1623 /* Initialize some fields. */
1624 rp->r_restarts = 0; /* no restarts yet */
1625 rp->r_old_rp = NULL; /* no old version yet */
1626 rp->r_new_rp = NULL; /* no new version yet */
1627 rp->r_prev_rp = NULL; /* no prev replica yet */
1628 rp->r_next_rp = NULL; /* no next replica yet */
1629 rp->r_exec = NULL; /* no in-memory copy yet */
1630 rp->r_exec_len = 0;
1631 rp->r_script[0]= '\0'; /* no recovery script yet */
1632 rpub->label[0]= '\0'; /* no label yet */
1633 rp->r_scheduler = -1; /* no scheduler yet */
1634 rp->r_priv.s_sig_mgr = -1; /* no signal manager yet */
1636 /* Initialize editable slot settings. */
1637 return edit_slot(rp, rs_start, source);
1640 /*===========================================================================*
1641 * clone_slot *
1642 *===========================================================================*/
1643 int clone_slot(rp, clone_rpp)
1644 struct rproc *rp;
1645 struct rproc **clone_rpp;
1647 int r;
1648 struct rproc *clone_rp;
1649 struct rprocpub *rpub, *clone_rpub;
1651 /* Allocate a system service slot for the clone. */
1652 r = alloc_slot(&clone_rp);
1653 if(r != OK) {
1654 printf("RS: clone_slot: unable to allocate a new slot: %d\n", r);
1655 return r;
1658 rpub = rp->r_pub;
1659 clone_rpub = clone_rp->r_pub;
1661 /* Synch the privilege structure of the source with the kernel. */
1662 if ((r = sys_getpriv(&(rp->r_priv), rpub->endpoint)) != OK) {
1663 panic("unable to synch privilege structure: %d", r);
1666 /* Shallow copy. */
1667 *clone_rp = *rp;
1668 *clone_rpub = *rpub;
1670 /* Deep copy. */
1671 clone_rp->r_flags &= ~RS_ACTIVE; /* the clone is not active yet */
1672 clone_rp->r_pid = -1; /* no pid yet */
1673 clone_rpub->endpoint = -1; /* no endpoint yet */
1674 clone_rp->r_pub = clone_rpub; /* restore pointer to public entry */
1675 build_cmd_dep(clone_rp); /* rebuild cmd dependencies */
1676 if(clone_rpub->sys_flags & SF_USE_COPY) {
1677 share_exec(clone_rp, rp); /* share exec image */
1679 clone_rp->r_old_rp = NULL; /* no old version yet */
1680 clone_rp->r_new_rp = NULL; /* no new version yet */
1681 clone_rp->r_prev_rp = NULL; /* no prev replica yet */
1682 clone_rp->r_next_rp = NULL; /* no next replica yet */
1684 /* Force dynamic privilege id. */
1685 clone_rp->r_priv.s_flags |= DYN_PRIV_ID;
1687 /* Clear instance flags. */
1688 clone_rp->r_priv.s_flags &= ~(LU_SYS_PROC | RST_SYS_PROC);
1690 *clone_rpp = clone_rp;
1691 return OK;
1694 /*===========================================================================*
1695 * swap_slot_pointer *
1696 *===========================================================================*/
1697 static void swap_slot_pointer(struct rproc **rpp, struct rproc *src_rp,
1698 struct rproc *dst_rp)
1700 if(*rpp == src_rp) {
1701 *rpp = dst_rp;
1703 else if(*rpp == dst_rp) {
1704 *rpp = src_rp;
1708 /*===========================================================================*
1709 * swap_slot *
1710 *===========================================================================*/
1711 void swap_slot(src_rpp, dst_rpp)
1712 struct rproc **src_rpp;
1713 struct rproc **dst_rpp;
1715 /* Swap two service slots. */
1716 struct rproc *src_rp;
1717 struct rproc *dst_rp;
1718 struct rprocpub *src_rpub;
1719 struct rprocpub *dst_rpub;
1720 struct rproc orig_src_rproc, orig_dst_rproc;
1721 struct rprocpub orig_src_rprocpub, orig_dst_rprocpub;
1723 src_rp = *src_rpp;
1724 dst_rp = *dst_rpp;
1725 src_rpub = src_rp->r_pub;
1726 dst_rpub = dst_rp->r_pub;
1728 /* Save existing data first. */
1729 orig_src_rproc = *src_rp;
1730 orig_src_rprocpub = *src_rpub;
1731 orig_dst_rproc = *dst_rp;
1732 orig_dst_rprocpub = *dst_rpub;
1734 /* Swap slots. */
1735 *src_rp = orig_dst_rproc;
1736 *src_rpub = orig_dst_rprocpub;
1737 *dst_rp = orig_src_rproc;
1738 *dst_rpub = orig_src_rprocpub;
1740 /* Restore public entries. */
1741 src_rp->r_pub = orig_src_rproc.r_pub;
1742 dst_rp->r_pub = orig_dst_rproc.r_pub;
1744 /* Rebuild command dependencies. */
1745 build_cmd_dep(src_rp);
1746 build_cmd_dep(dst_rp);
1748 /* Swap local slot pointers. */
1749 swap_slot_pointer(&src_rp->r_prev_rp, src_rp, dst_rp);
1750 swap_slot_pointer(&src_rp->r_next_rp, src_rp, dst_rp);
1751 swap_slot_pointer(&src_rp->r_old_rp, src_rp, dst_rp);
1752 swap_slot_pointer(&src_rp->r_new_rp, src_rp, dst_rp);
1753 swap_slot_pointer(&dst_rp->r_prev_rp, src_rp, dst_rp);
1754 swap_slot_pointer(&dst_rp->r_next_rp, src_rp, dst_rp);
1755 swap_slot_pointer(&dst_rp->r_old_rp, src_rp, dst_rp);
1756 swap_slot_pointer(&dst_rp->r_new_rp, src_rp, dst_rp);
1758 /* Swap global slot pointers. */
1759 swap_slot_pointer(&rupdate.rp, src_rp, dst_rp);
1760 swap_slot_pointer(&rproc_ptr[_ENDPOINT_P(src_rp->r_pub->endpoint)],
1761 src_rp, dst_rp);
1762 swap_slot_pointer(&rproc_ptr[_ENDPOINT_P(dst_rp->r_pub->endpoint)],
1763 src_rp, dst_rp);
1765 /* Adjust input pointers. */
1766 *src_rpp = dst_rp;
1767 *dst_rpp = src_rp;
1770 /*===========================================================================*
1771 * lookup_slot_by_label *
1772 *===========================================================================*/
1773 struct rproc* lookup_slot_by_label(char *label)
1775 /* Lookup a service slot matching the given label. */
1776 int slot_nr;
1777 struct rproc *rp;
1778 struct rprocpub *rpub;
1780 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
1781 rp = &rproc[slot_nr];
1782 if (!(rp->r_flags & RS_ACTIVE)) {
1783 continue;
1785 rpub = rp->r_pub;
1786 if (strcmp(rpub->label, label) == 0) {
1787 return rp;
1791 return NULL;
1794 /*===========================================================================*
1795 * lookup_slot_by_pid *
1796 *===========================================================================*/
1797 struct rproc* lookup_slot_by_pid(pid_t pid)
1799 /* Lookup a service slot matching the given pid. */
1800 int slot_nr;
1801 struct rproc *rp;
1803 if(pid < 0) {
1804 return NULL;
1807 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
1808 rp = &rproc[slot_nr];
1809 if (!(rp->r_flags & RS_IN_USE)) {
1810 continue;
1812 if (rp->r_pid == pid) {
1813 return rp;
1817 return NULL;
1820 /*===========================================================================*
1821 * lookup_slot_by_dev_nr *
1822 *===========================================================================*/
1823 struct rproc* lookup_slot_by_dev_nr(dev_t dev_nr)
1825 /* Lookup a service slot matching the given device number. */
1826 int slot_nr;
1827 struct rproc *rp;
1828 struct rprocpub *rpub;
1830 if(dev_nr <= 0) {
1831 return NULL;
1834 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
1835 rp = &rproc[slot_nr];
1836 rpub = rp->r_pub;
1837 if (!(rp->r_flags & RS_IN_USE)) {
1838 continue;
1840 if (rpub->dev_nr == dev_nr) {
1841 return rp;
1845 return NULL;
1848 /*===========================================================================*
1849 * lookup_slot_by_flags *
1850 *===========================================================================*/
1851 struct rproc* lookup_slot_by_flags(int flags)
1853 /* Lookup a service slot matching the given flags. */
1854 int slot_nr;
1855 struct rproc *rp;
1857 if(!flags) {
1858 return NULL;
1861 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
1862 rp = &rproc[slot_nr];
1863 if (!(rp->r_flags & RS_IN_USE)) {
1864 continue;
1866 if (rp->r_flags & flags) {
1867 return rp;
1871 return NULL;
1874 /*===========================================================================*
1875 * alloc_slot *
1876 *===========================================================================*/
1877 int alloc_slot(rpp)
1878 struct rproc **rpp;
1880 /* Alloc a new system service slot. */
1881 int slot_nr;
1883 for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
1884 *rpp = &rproc[slot_nr]; /* get pointer to slot */
1885 if (!((*rpp)->r_flags & RS_IN_USE)) /* check if available */
1886 break;
1888 if (slot_nr >= NR_SYS_PROCS) {
1889 return ENOMEM;
1892 return OK;
1895 /*===========================================================================*
1896 * free_slot *
1897 *===========================================================================*/
1898 void free_slot(rp)
1899 struct rproc *rp;
1901 /* Free a system service slot. */
1902 struct rprocpub *rpub;
1904 rpub = rp->r_pub;
1906 /* Send a late reply if there is any pending. */
1907 late_reply(rp, OK);
1909 /* Free memory if necessary. */
1910 if(rpub->sys_flags & SF_USE_COPY) {
1911 free_exec(rp);
1914 /* Mark slot as no longer in use.. */
1915 rp->r_flags = 0;
1916 rp->r_pid = -1;
1917 rpub->in_use = FALSE;
1918 rproc_ptr[_ENDPOINT_P(rpub->endpoint)] = NULL;
1922 /*===========================================================================*
1923 * get_next_name *
1924 *===========================================================================*/
1925 static char *get_next_name(ptr, name, caller_label)
1926 char *ptr;
1927 char *name;
1928 char *caller_label;
1930 /* Get the next name from the list of (IPC) program names.
1932 char *p, *q;
1933 size_t len;
1935 for (p= ptr; p[0] != '\0'; p= q)
1937 /* Skip leading space */
1938 while (p[0] != '\0' && isspace((unsigned char)p[0]))
1939 p++;
1941 /* Find start of next word */
1942 q= p;
1943 while (q[0] != '\0' && !isspace((unsigned char)q[0]))
1944 q++;
1945 if (q == p)
1946 continue;
1947 len= q-p;
1948 if (len > RS_MAX_LABEL_LEN)
1950 printf(
1951 "rs:get_next_name: bad ipc list entry '%.*s' for %s: too long\n",
1952 len, p, caller_label);
1953 continue;
1955 memcpy(name, p, len);
1956 name[len]= '\0';
1958 return q; /* found another */
1961 return NULL; /* done */
1964 /*===========================================================================*
1965 * add_forward_ipc *
1966 *===========================================================================*/
1967 void add_forward_ipc(rp, privp)
1968 struct rproc *rp;
1969 struct priv *privp;
1971 /* Add IPC send permissions to a process based on that process's IPC
1972 * list.
1974 char name[RS_MAX_LABEL_LEN+1], *p;
1975 struct rproc *rrp;
1976 endpoint_t endpoint;
1977 int r;
1978 int priv_id;
1979 struct priv priv;
1980 struct rprocpub *rpub;
1982 rpub = rp->r_pub;
1983 p = rp->r_ipc_list;
1985 while ((p = get_next_name(p, name, rpub->label)) != NULL) {
1987 if (strcmp(name, "SYSTEM") == 0)
1988 endpoint= SYSTEM;
1989 else if (strcmp(name, "USER") == 0)
1990 endpoint= INIT_PROC_NR; /* all user procs */
1991 else
1993 /* Set a privilege bit for every process matching the
1994 * given process name. It is perfectly fine if this
1995 * loop does not find any matches, as the target
1996 * process(es) may not have been started yet. See
1997 * add_backward_ipc() below.
1999 for (rrp=BEG_RPROC_ADDR; rrp<END_RPROC_ADDR; rrp++) {
2000 if (!(rrp->r_flags & RS_IN_USE))
2001 continue;
2003 if (!strcmp(rrp->r_pub->proc_name, name)) {
2004 #if PRIV_DEBUG
2005 printf(" RS: add_forward_ipc: setting"
2006 " sendto bit for %d...\n",
2007 rrp->r_pub->endpoint);
2008 #endif
2010 priv_id= rrp->r_priv.s_id;
2011 set_sys_bit(privp->s_ipc_to, priv_id);
2015 continue;
2018 /* This code only applies to the exception cases. */
2019 if ((r = sys_getpriv(&priv, endpoint)) < 0)
2021 printf(
2022 "add_forward_ipc: unable to get priv_id for '%s': %d\n",
2023 name, r);
2024 continue;
2027 #if PRIV_DEBUG
2028 printf(" RS: add_forward_ipc: setting sendto bit for %d...\n",
2029 endpoint);
2030 #endif
2031 priv_id= priv.s_id;
2032 set_sys_bit(privp->s_ipc_to, priv_id);
2037 /*===========================================================================*
2038 * add_backward_ipc *
2039 *===========================================================================*/
2040 void add_backward_ipc(rp, privp)
2041 struct rproc *rp;
2042 struct priv *privp;
2044 /* Add IPC send permissions to a process based on other processes' IPC
2045 * lists. This is enough to allow each such two processes to talk to
2046 * each other, as the kernel guarantees send mask symmetry. We need to
2047 * add these permissions now because the current process may not yet
2048 * have existed at the time that the other process was initialized.
2050 char name[RS_MAX_LABEL_LEN+1], *p;
2051 struct rproc *rrp;
2052 struct rprocpub *rrpub;
2053 char *proc_name;
2054 int priv_id, is_ipc_all, is_ipc_all_sys;
2056 proc_name = rp->r_pub->proc_name;
2058 for (rrp=BEG_RPROC_ADDR; rrp<END_RPROC_ADDR; rrp++) {
2059 if (!(rrp->r_flags & RS_IN_USE))
2060 continue;
2062 if (!rrp->r_ipc_list[0])
2063 continue;
2065 /* If the process being checked is set to allow IPC to all
2066 * other processes, or for all other system processes and the
2067 * target process is a system process, add a permission bit.
2069 rrpub = rrp->r_pub;
2071 is_ipc_all = !strcmp(rrp->r_ipc_list, RSS_IPC_ALL);
2072 is_ipc_all_sys = !strcmp(rrp->r_ipc_list, RSS_IPC_ALL_SYS);
2074 if (is_ipc_all ||
2075 (is_ipc_all_sys && (privp->s_flags & SYS_PROC))) {
2076 #if PRIV_DEBUG
2077 printf(" RS: add_backward_ipc: setting sendto bit "
2078 "for %d...\n", rrpub->endpoint);
2079 #endif
2080 priv_id= rrp->r_priv.s_id;
2081 set_sys_bit(privp->s_ipc_to, priv_id);
2083 continue;
2086 /* An IPC target list was provided for the process being
2087 * checked here. Make sure that the name of the new process
2088 * is in that process's list. There may be multiple matches.
2090 p = rrp->r_ipc_list;
2092 while ((p = get_next_name(p, name, rrpub->label)) != NULL) {
2093 if (!strcmp(proc_name, name)) {
2094 #if PRIV_DEBUG
2095 printf(" RS: add_backward_ipc: setting sendto"
2096 " bit for %d...\n",
2097 rrpub->endpoint);
2098 #endif
2099 priv_id= rrp->r_priv.s_id;
2100 set_sys_bit(privp->s_ipc_to, priv_id);
2107 /*===========================================================================*
2108 * init_privs *
2109 *===========================================================================*/
2110 void init_privs(rp, privp)
2111 struct rproc *rp;
2112 struct priv *privp;
2114 int i;
2115 int is_ipc_all, is_ipc_all_sys;
2117 /* Clear s_ipc_to */
2118 fill_send_mask(&privp->s_ipc_to, FALSE);
2120 is_ipc_all = !strcmp(rp->r_ipc_list, RSS_IPC_ALL);
2121 is_ipc_all_sys = !strcmp(rp->r_ipc_list, RSS_IPC_ALL_SYS);
2123 #if PRIV_DEBUG
2124 printf(" RS: init_privs: ipc list is '%s'...\n", rp->r_ipc_list);
2125 #endif
2127 if (!is_ipc_all && !is_ipc_all_sys)
2129 add_forward_ipc(rp, privp);
2130 add_backward_ipc(rp, privp);
2133 else
2135 for (i= 0; i<NR_SYS_PROCS; i++)
2137 if (is_ipc_all || i != USER_PRIV_ID)
2138 set_sys_bit(privp->s_ipc_to, i);