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