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