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)
10 #include <sys/exec_elf.h>
14 #include "kernel/proc.h"
16 static int run_script(struct rproc
*rp
);
18 /*===========================================================================*
20 *===========================================================================*/
21 static int caller_is_root(endpoint
)
22 endpoint_t endpoint
; /* caller endpoint */
26 /* Check if caller has root user ID. */
27 euid
= getnuid(endpoint
);
28 if (rs_verbose
&& euid
!= 0)
30 printf("RS: got unauthorized request from endpoint %d\n", endpoint
);
36 /*===========================================================================*
37 * caller_can_control *
38 *===========================================================================*/
39 static int caller_can_control(endpoint
, target_rp
)
41 struct rproc
*target_rp
;
43 int control_allowed
= 0;
44 register struct rproc
*rp
;
45 register struct rprocpub
*rpub
;
49 proc_name
= target_rp
->r_pub
->proc_name
;
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
))
57 if (rpub
->endpoint
== endpoint
) {
61 if (rp
== END_RPROC_ADDR
) return 0;
63 for (c
= 0; c
< rp
->r_nr_control
; c
++) {
64 if (strcmp(rp
->r_control
[c
], proc_name
) == 0) {
71 printf("RS: allowing %u control over %s via policy: %s\n",
72 endpoint
, target_rp
->r_pub
->label
,
73 control_allowed
? "yes" : "no");
75 return control_allowed
;
78 /*===========================================================================*
79 * check_call_permission *
80 *===========================================================================*/
81 int check_call_permission(caller
, call
, rp
)
86 /* Check if the caller has permission to execute a particular call. */
87 struct rprocpub
*rpub
;
90 /* Caller should be either root or have control privileges. */
91 call_allowed
= caller_is_root(caller
);
93 call_allowed
|= caller_can_control(caller
, rp
);
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
;
107 /* Disallow the call if an update is in progress. */
108 if(RUPDATE_IS_UPDATING()) {
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
)) {
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
;
123 /* Disallow RS_DOWN for core system services. */
124 if (rpub
->sys_flags
& SF_CORE_SRV
) {
125 if(call
== RS_DOWN
) return EPERM
;
132 /*===========================================================================*
134 *===========================================================================*/
135 int copy_rs_start(src_e
, src_rs_start
, dst_rs_start
)
138 struct rs_start
*dst_rs_start
;
142 r
= sys_datacopy(src_e
, (vir_bytes
) src_rs_start
,
143 SELF
, (vir_bytes
) dst_rs_start
, sizeof(struct rs_start
));
148 /*===========================================================================*
150 *===========================================================================*/
151 int copy_label(src_e
, src_label
, src_len
, dst_label
, dst_len
)
160 len
= MIN(dst_len
-1, src_len
);
162 s
= sys_datacopy(src_e
, (vir_bytes
) src_label
,
163 SELF
, (vir_bytes
) dst_label
, len
);
164 if (s
!= OK
) return s
;
171 /*===========================================================================*
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
)
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
;
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
)) {
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
) {
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
) {
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
);
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
;
214 /* Initialize ipc filters. */
215 if(src_rs_state_data
->ipcf_els_size
% rs_ipc_filter_size
) {
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
) {
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
;
228 ipcf_els_buff
= malloc(ipcf_els_buff_size
);
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
);
239 for(j
=0;j
<IPCF_MAX_ELEMENTS
&& rs_ipc_filter
[j
].flags
;j
++) {
240 endpoint_t m_source
= 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
;
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 */
250 if(!strcmp("ANY_USR", rs_ipc_filter
[j
].m_label
)) {
253 else if(!strcmp("ANY_SYS", rs_ipc_filter
[j
].m_label
)) {
256 else if(!strcmp("ANY_TSK", rs_ipc_filter
[j
].m_label
)) {
261 m_source
= strtol(rs_ipc_filter
[j
].m_label
, &buff
, 10);
262 if(errno
|| strcmp(buff
, "")) {
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
;
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
;
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
;
286 /*===========================================================================*
288 *===========================================================================*/
289 void build_cmd_dep(struct rproc
*rp
)
291 struct rprocpub
*rpub
;
298 /* Build argument vector to be passed to execute call. The format of the
299 * arguments vector is: path, arguments, NULL.
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");
315 assert(arg_count
< ARGV_ELEMENTS
);
316 rp
->r_argv
[arg_count
++] = cmd_ptr
; /* add to arg vector */
318 cmd_ptr
++; /* continue parsing */
320 assert(arg_count
< ARGV_ELEMENTS
);
321 rp
->r_argv
[arg_count
] = NULL
; /* end with NULL pointer */
322 rp
->r_argc
= arg_count
;
325 /*===========================================================================*
327 *===========================================================================*/
328 void end_srv_init(struct rproc
*rp
)
330 struct rprocpub
*rpub
;
335 /* See if a late reply has to be sent. */
338 /* If the service has completed initialization after a crash
339 * make the new instance active and cleanup the old replica.
340 * If the service was part of a scheduled update, schedule the new
341 * replica for the same update.
344 if(SRV_IS_UPD_SCHEDULED(rp
->r_prev_rp
)) {
345 rupdate_upd_move(rp
->r_prev_rp
, rp
);
347 cleanup_service(rp
->r_prev_rp
);
348 rp
->r_prev_rp
= NULL
;
352 printf("RS: %s completed restart\n", srv_to_string(rp
));
354 rp
->r_next_rp
= NULL
;
357 /*===========================================================================*
358 * kill_service_debug *
359 *===========================================================================*/
360 int kill_service_debug(file
, line
, rp
, errstr
, err
)
367 /* Crash a system service and don't let it restart. */
368 if(errstr
&& !shutting_down
) {
369 printf("RS: %s (error %d)\n", errstr
, err
);
371 rp
->r_flags
|= RS_EXITING
; /* expect exit */
372 crash_service_debug(file
, line
, rp
); /* simulate crash */
377 /*===========================================================================*
378 * crash_service_debug *
379 *===========================================================================*/
380 int crash_service_debug(file
, line
, rp
)
385 /* Simluate a crash in a system service. */
386 struct rprocpub
*rpub
;
391 printf("RS: %s %skilled at %s:%d\n", srv_to_string(rp
),
392 rp
->r_flags
& RS_EXITING
? "lethally " : "", file
, line
);
394 /* RS should simply exit() directly. */
395 if(rpub
->endpoint
== RS_PROC_NR
) {
399 return sys_kill(rpub
->endpoint
, SIGKILL
);
402 /*===========================================================================*
403 * cleanup_service_debug *
404 *===========================================================================*/
405 void cleanup_service_debug(file
, line
, rp
)
410 struct rprocpub
*rpub
;
411 int detach
, cleanup_script
;
416 if(!(rp
->r_flags
& RS_DEAD
)) {
418 printf("RS: %s marked for cleanup at %s:%d\n", srv_to_string(rp
),
421 /* Unlink service the first time. */
423 rp
->r_next_rp
->r_prev_rp
= NULL
;
424 rp
->r_next_rp
= NULL
;
427 rp
->r_prev_rp
->r_next_rp
= NULL
;
428 rp
->r_prev_rp
= NULL
;
431 rp
->r_new_rp
->r_old_rp
= NULL
;
435 rp
->r_old_rp
->r_new_rp
= NULL
;
438 rp
->r_flags
|= RS_DEAD
;
440 /* Make sure the service can no longer run and unblock IPC callers. */
441 sys_privctl(rpub
->endpoint
, SYS_PRIV_DISALLOW
, NULL
);
442 sys_privctl(rpub
->endpoint
, SYS_PRIV_CLEAR_IPC_REFS
, NULL
);
443 rp
->r_flags
&= ~RS_ACTIVE
;
445 /* Send a late reply if there is any pending. */
451 cleanup_script
= rp
->r_flags
& RS_CLEANUP_SCRIPT
;
452 detach
= rp
->r_flags
& RS_CLEANUP_DETACH
;
454 /* Cleanup the service when not detaching. */
457 printf("RS: %s cleaned up at %s:%d\n", srv_to_string(rp
),
460 /* Tell scheduler this process is finished */
461 if ((s
= sched_stop(rp
->r_scheduler
, rpub
->endpoint
)) != OK
) {
462 printf("RS: warning: scheduler won't give up process: %d\n", s
);
465 /* Ask PM to exit the service */
466 if(rp
->r_pid
== -1) {
467 printf("RS: warning: attempt to kill pid -1!\n");
470 srv_kill(rp
->r_pid
, SIGKILL
);
474 /* See if we need to run a script now. */
476 rp
->r_flags
&= ~RS_CLEANUP_SCRIPT
;
479 printf("RS: warning: cannot run cleanup script: %d\n", s
);
484 /* Detach service when asked to. */
488 /* Free slot otherwise, unless we're about to reuse it */
489 if (!(rp
->r_flags
& RS_REINCARNATE
))
494 /*===========================================================================*
495 * detach_service_debug *
496 *===========================================================================*/
497 void detach_service_debug(file
, line
, rp
)
502 /* Detach the given system service. */
503 static unsigned long detach_counter
= 0;
504 char label
[RS_MAX_LABEL_LEN
];
505 struct rprocpub
*rpub
;
509 /* Publish a new unique label for the system service. */
510 rpub
->label
[RS_MAX_LABEL_LEN
-1] = '\0';
511 strcpy(label
, rpub
->label
);
512 snprintf(rpub
->label
, RS_MAX_LABEL_LEN
, "%lu.%s", ++detach_counter
, label
);
513 ds_publish_label(rpub
->label
, rpub
->endpoint
, DSF_OVERWRITE
);
516 printf("RS: %s detached at %s:%d\n", srv_to_string(rp
),
519 /* Allow the service to run. */
520 rp
->r_flags
= RS_IN_USE
| RS_ACTIVE
;
521 rpub
->sys_flags
&= ~(SF_CORE_SRV
|SF_DET_RESTART
);
525 sys_privctl(rpub
->endpoint
, SYS_PRIV_ALLOW
, NULL
);
528 /*===========================================================================*
530 *===========================================================================*/
531 int create_service(rp
)
534 /* Create the given system service. */
535 int child_proc_nr_e
, child_proc_nr_n
; /* child process slot */
536 pid_t child_pid
; /* child's process id */
537 int s
, use_copy
, has_replica
;
538 extern char **environ
;
539 struct rprocpub
*rpub
;
542 use_copy
= (rpub
->sys_flags
& SF_USE_COPY
);
543 has_replica
= (rp
->r_old_rp
544 || (rp
->r_prev_rp
&& !(rp
->r_prev_rp
->r_flags
& RS_TERMINATED
)));
546 /* Do we need an existing replica to create the service? */
547 if(!has_replica
&& (rpub
->sys_flags
& SF_NEED_REPL
)) {
548 printf("RS: unable to create service '%s' without a replica\n",
554 /* Do we need an in-memory copy to create the service? */
555 if(!use_copy
&& (rpub
->sys_flags
& SF_NEED_COPY
)) {
556 printf("RS: unable to create service '%s' without an in-memory copy\n",
562 /* Do we have a copy or a command to create the service? */
563 if(!use_copy
&& !strcmp(rp
->r_cmd
, "")) {
564 printf("RS: unable to create service '%s' without a copy or command\n",
570 /* Now fork and branch for parent and child process (and check for error).
571 * After fork()ing, we need to pin RS memory again or pagefaults will occur
575 printf("RS: forking child with srv_fork()...\n");
576 child_pid
= srv_fork(rp
->r_uid
, 0); /* Force group to wheel for now */
578 printf("RS: srv_fork() failed (error %d)\n", child_pid
);
583 /* Get endpoint of the child. */
584 if ((s
= getprocnr(child_pid
, &child_proc_nr_e
)) != 0)
585 panic("unable to get child endpoint: %d", s
);
587 /* There is now a child process. Update the system process table. */
588 child_proc_nr_n
= _ENDPOINT_P(child_proc_nr_e
);
589 rp
->r_flags
= RS_IN_USE
; /* mark slot in use */
590 rpub
->endpoint
= child_proc_nr_e
; /* set child endpoint */
591 rp
->r_pid
= child_pid
; /* set child pid */
592 rp
->r_check_tm
= 0; /* not checked yet */
593 rp
->r_alive_tm
= getticks(); /* currently alive */
594 rp
->r_stop_tm
= 0; /* not exiting yet */
595 rp
->r_backoff
= 0; /* not to be restarted */
596 rproc_ptr
[child_proc_nr_n
] = rp
; /* mapping for fast access */
597 rpub
->in_use
= TRUE
; /* public entry is now in use */
599 /* Set and synch the privilege structure for the new service. */
600 if ((s
= sys_privctl(child_proc_nr_e
, SYS_PRIV_SET_SYS
, &rp
->r_priv
)) != OK
601 || (s
= sys_getpriv(&rp
->r_priv
, child_proc_nr_e
)) != OK
) {
602 printf("RS: unable to set privilege structure: %d\n", s
);
604 vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0);
608 /* Set the scheduler for this process */
609 if ((s
= sched_init_proc(rp
)) != OK
) {
610 printf("RS: unable to start scheduling: %d\n", s
);
612 vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0);
616 /* Copy the executable image into the child process. If no copy exists,
617 * allocate one and free it right after exec completes.
621 printf("RS: %s uses an in-memory copy\n",
625 if ((s
= read_exec(rp
)) != OK
) {
626 printf("RS: read_exec failed: %d\n", s
);
628 vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0);
633 printf("RS: execing child with srv_execve()...\n");
634 s
= srv_execve(child_proc_nr_e
, rp
->r_exec
, rp
->r_exec_len
, rpub
->proc_name
,
635 rp
->r_argv
, environ
);
636 vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0);
638 printf("RS: srv_execve failed: %d\n", s
);
646 /* The purpose of non-blocking forks is to avoid involving VFS in the forking
647 * process, because VFS may be blocked on a sendrec() to a MFS that is
648 * waiting for a endpoint update for a dead driver. We have just published
649 * that update, but VFS may still be blocked. As a result, VFS may not yet
650 * have received PM's fork message. Hence, if we call mapdriver()
651 * immediately, VFS may not know about the process and thus refuse to add the
652 * driver entry. The following temporary hack works around this by forcing
653 * blocking communication from PM to VFS. Once VFS has been made non-blocking
654 * towards MFS instances, this hack and the big part of srv_fork() can go.
658 /* If this is a RS instance, pin memory. */
659 if(rp
->r_priv
.s_flags
& ROOT_SYS_PROC
) {
661 printf("RS: pinning memory of RS instance %s\n", srv_to_string(rp
));
663 s
= vm_memctl(rpub
->endpoint
, VM_RS_MEM_PIN
, 0, 0);
665 printf("vm_memctl failed: %d\n", s
);
671 /* If this is a VM instance, let VM know now. */
672 if(rp
->r_priv
.s_flags
& VM_SYS_PROC
) {
674 struct rproc
**rs_rps
;
678 printf("RS: informing VM of instance %s\n", srv_to_string(rp
));
680 s
= vm_memctl(rpub
->endpoint
, VM_RS_MEM_MAKE_VM
, 0, 0);
682 printf("vm_memctl failed: %d\n", s
);
687 /* VM may start actually pinning memory for us only now.
688 * Ask again for all our instances.
690 rs_rp
= rproc_ptr
[_ENDPOINT_P(RS_PROC_NR
)];
691 get_service_instances(rs_rp
, &rs_rps
, &nr_rs_rps
);
692 for(i
=0;i
<nr_rs_rps
;i
++) {
693 vm_memctl(rs_rps
[i
]->r_pub
->endpoint
, VM_RS_MEM_PIN
, 0, 0);
697 /* Tell VM about allowed calls. */
698 if ((s
= vm_set_priv(rpub
->endpoint
, &rpub
->vm_call_mask
[0], TRUE
)) != OK
) {
699 printf("RS: vm_set_priv failed: %d\n", s
);
705 printf("RS: %s created\n", srv_to_string(rp
));
710 /*===========================================================================*
712 *===========================================================================*/
713 int clone_service(struct rproc
*rp
, int instance_flag
, int init_flags
)
715 /* Clone the given system service instance. */
716 struct rproc
*replica_rp
;
717 struct rprocpub
*replica_rpub
;
718 struct rproc
**rp_link
;
719 struct rproc
**replica_link
;
725 printf("RS: %s creating a replica\n", srv_to_string(rp
));
727 /* VM can only reliably support one replica at the time for now.
728 * XXX TO-DO: Fix VM's rs_memctl_make_vm_instance to allow multiple replicas.
730 if(rp
->r_pub
->endpoint
== VM_PROC_NR
&& instance_flag
== LU_SYS_PROC
732 cleanup_service_now(rp
->r_next_rp
);
733 rp
->r_next_rp
= NULL
;
737 if((r
= clone_slot(rp
, &replica_rp
)) != OK
) {
740 replica_rpub
= replica_rp
->r_pub
;
742 /* Clone is a live updated or restarted service instance? */
743 if(instance_flag
== LU_SYS_PROC
) {
744 rp_link
= &rp
->r_new_rp
;
745 replica_link
= &replica_rp
->r_old_rp
;
748 rp_link
= &rp
->r_next_rp
;
749 replica_link
= &replica_rp
->r_prev_rp
;
751 replica_rp
->r_priv
.s_flags
|= instance_flag
;
752 replica_rp
->r_priv
.s_init_flags
|= init_flags
;
754 /* Link the two slots. */
755 *rp_link
= replica_rp
;
758 /* Create a new replica of the service. */
759 r
= create_service(replica_rp
);
765 /* If this instance is for restarting RS, set up a backup signal manager. */
766 rs_flags
= (ROOT_SYS_PROC
| RST_SYS_PROC
);
767 if((replica_rp
->r_priv
.s_flags
& rs_flags
) == rs_flags
) {
768 rs_rp
= rproc_ptr
[_ENDPOINT_P(RS_PROC_NR
)];
770 /* Update signal managers. */
771 r
= update_sig_mgrs(rs_rp
, SELF
, replica_rpub
->endpoint
);
773 r
= update_sig_mgrs(replica_rp
, SELF
, NONE
);
777 return kill_service(replica_rp
, "update_sig_mgrs failed", r
);
784 /*===========================================================================*
786 *===========================================================================*/
787 int publish_service(rp
)
788 struct rproc
*rp
; /* pointer to service slot */
790 /* Publish a service. */
792 struct rprocpub
*rpub
;
793 struct rs_pci pci_acl
;
799 /* Register label with DS. */
800 r
= ds_publish_label(rpub
->label
, rpub
->endpoint
, DSF_OVERWRITE
);
802 return kill_service(rp
, "ds_publish_label call failed", r
);
805 /* If the service is a driver, map it. */
806 if (rpub
->dev_nr
> 0 || rpub
->nr_domain
> 0) {
807 /* The purpose of non-blocking forks is to avoid involving VFS in the
808 * forking process, because VFS may be blocked on a ipc_sendrec() to a MFS
809 * that is waiting for a endpoint update for a dead driver. We have just
810 * published that update, but VFS may still be blocked. As a result, VFS
811 * may not yet have received PM's fork message. Hence, if we call
812 * mapdriver() immediately, VFS may not know about the process and thus
813 * refuse to add the driver entry. The following temporary hack works
814 * around this by forcing blocking communication from PM to VFS. Once VFS
815 * has been made non-blocking towards MFS instances, this hack and the
816 * big part of srv_fork() can go.
820 if ((r
= mapdriver(rpub
->label
, rpub
->dev_nr
, rpub
->domain
,
821 rpub
->nr_domain
)) != OK
) {
822 return kill_service(rp
, "couldn't map driver", r
);
827 /* If PCI properties are set, inform the PCI driver about the new service. */
828 if(rpub
->pci_acl
.rsp_nr_device
|| rpub
->pci_acl
.rsp_nr_class
) {
829 pci_acl
= rpub
->pci_acl
;
830 strcpy(pci_acl
.rsp_label
, rpub
->label
);
831 pci_acl
.rsp_endpoint
= rpub
->endpoint
;
833 r
= pci_set_acl(&pci_acl
);
835 return kill_service(rp
, "pci_set_acl call failed", r
);
840 if (rpub
->devman_id
!= 0) {
841 r
= ds_retrieve_label_endpt("devman",&ep
);
844 return kill_service(rp
, "devman not running?", r
);
846 m
.m_type
= DEVMAN_BIND
;
847 m
.DEVMAN_ENDPOINT
= rpub
->endpoint
;
848 m
.DEVMAN_DEVICE_ID
= rpub
->devman_id
;
849 r
= ipc_sendrec(ep
, &m
);
850 if (r
!= OK
|| m
.DEVMAN_RESULT
!= OK
) {
851 return kill_service(rp
, "devman bind device failed", r
);
856 printf("RS: %s published\n", srv_to_string(rp
));
861 /*===========================================================================*
862 * unpublish_service *
863 *===========================================================================*/
864 int unpublish_service(rp
)
865 struct rproc
*rp
; /* pointer to service slot */
867 /* Unpublish a service. */
868 struct rprocpub
*rpub
;
877 /* Unregister label with DS. */
878 r
= ds_delete_label(rpub
->label
);
879 if (r
!= OK
&& !shutting_down
) {
880 printf("RS: ds_delete_label call failed (error %d)\n", r
);
884 /* No need to inform VFS and VM, cleanup is done on exit automatically. */
887 /* If PCI properties are set, inform the PCI driver. */
888 if(rpub
->pci_acl
.rsp_nr_device
|| rpub
->pci_acl
.rsp_nr_class
) {
889 r
= pci_del_acl(rpub
->endpoint
);
890 if (r
!= OK
&& !shutting_down
) {
891 printf("RS: pci_del_acl call failed (error %d)\n", r
);
897 if (rpub
->devman_id
!= 0) {
898 r
= ds_retrieve_label_endpt("devman",&ep
);
901 printf("RS: devman not running?");
903 m
.m_type
= DEVMAN_UNBIND
;
904 m
.DEVMAN_ENDPOINT
= rpub
->endpoint
;
905 m
.DEVMAN_DEVICE_ID
= rpub
->devman_id
;
906 r
= ipc_sendrec(ep
, &m
);
908 if (r
!= OK
|| m
.DEVMAN_RESULT
!= OK
) {
909 printf("RS: devman unbind device failed");
915 printf("RS: %s unpublished\n", srv_to_string(rp
));
920 /*===========================================================================*
922 *===========================================================================*/
923 int run_service(struct rproc
*rp
, int init_type
, int init_flags
)
925 /* Let a newly created service run. */
926 struct rprocpub
*rpub
;
931 /* Allow the service to run. */
932 if ((s
= sys_privctl(rpub
->endpoint
, SYS_PRIV_ALLOW
, NULL
)) != OK
) {
933 return kill_service(rp
, "unable to allow the service to run",s
);
936 /* Initialize service. */
937 if((s
= init_service(rp
, init_type
, init_flags
)) != OK
) {
938 return kill_service(rp
, "unable to initialize service", s
);
942 printf("RS: %s allowed to run\n", srv_to_string(rp
));
947 /*===========================================================================*
949 *===========================================================================*/
950 int start_service(struct rproc
*rp
, int init_flags
)
952 /* Start a system service. */
954 struct rprocpub
*rpub
;
958 /* Create and make active. */
959 rp
->r_priv
.s_init_flags
|= init_flags
;
960 r
= create_service(rp
);
964 activate_service(rp
, NULL
);
966 /* Publish service properties. */
967 r
= publish_service(rp
);
973 r
= run_service(rp
, SEF_INIT_FRESH
, init_flags
);
979 printf("RS: %s started with major %d\n", srv_to_string(rp
),
985 /*===========================================================================*
987 *===========================================================================*/
988 void stop_service(struct rproc
*rp
,int how
)
990 struct rprocpub
*rpub
;
995 /* Try to stop the system service. First send a SIGTERM signal to ask the
996 * system service to terminate. If the service didn't install a signal
997 * handler, it will be killed. If it did and ignores the signal, we'll
998 * find out because we record the time here and send a SIGKILL.
1001 printf("RS: %s signaled with SIGTERM\n", srv_to_string(rp
));
1003 signo
= rpub
->endpoint
!= RS_PROC_NR
? SIGTERM
: SIGHUP
; /* SIGHUP for RS. */
1005 rp
->r_flags
|= how
; /* what to on exit? */
1006 sys_kill(rpub
->endpoint
, signo
); /* first try friendly */
1007 rp
->r_stop_tm
= getticks(); /* record current time */
1010 /*===========================================================================*
1011 * activate_service *
1012 *===========================================================================*/
1013 void activate_service(struct rproc
*rp
, struct rproc
*ex_rp
)
1015 /* Activate a service instance and deactivate another one if requested. */
1017 if(ex_rp
&& (ex_rp
->r_flags
& RS_ACTIVE
) ) {
1018 ex_rp
->r_flags
&= ~RS_ACTIVE
;
1020 printf("RS: %s becomes inactive\n", srv_to_string(ex_rp
));
1023 if(! (rp
->r_flags
& RS_ACTIVE
) ) {
1024 rp
->r_flags
|= RS_ACTIVE
;
1026 printf("RS: %s becomes active\n", srv_to_string(rp
));
1030 /*===========================================================================*
1031 * reincarnate_service *
1032 *===========================================================================*/
1033 void reincarnate_service(struct rproc
*old_rp
)
1035 /* Restart a service as if it were never started before. */
1039 if ((r
= clone_slot(old_rp
, &rp
)) != OK
) {
1040 printf("RS: Failed to clone the slot: %d\n", r
);
1044 rp
->r_flags
= RS_IN_USE
;
1045 rproc_ptr
[_ENDPOINT_P(rp
->r_pub
->endpoint
)] = NULL
;
1047 restarts
= rp
->r_restarts
;
1048 start_service(rp
, SEF_INIT_FRESH
);
1049 rp
->r_restarts
= restarts
+ 1;
1052 /*===========================================================================*
1053 * terminate_service *
1054 *===========================================================================*/
1055 void terminate_service(struct rproc
*rp
)
1057 /* Handle a termination event for a system service. */
1059 struct rprocpub
*rpub
;
1060 int nr_rps
, norestart
;
1066 printf("RS: %s terminated\n", srv_to_string(rp
));
1068 /* Deal with failures during initialization. */
1069 if(rp
->r_flags
& RS_INITIALIZING
) {
1070 /* If updating, rollback. */
1071 if(SRV_IS_UPDATING(rp
)) {
1072 printf("RS: update failed: state transfer failed. Rolling back...\n");
1073 end_update(rp
->r_init_err
, RS_REPLY
);
1074 rp
->r_init_err
= ERESTART
;
1078 if (rpub
->sys_flags
& SF_NO_BIN_EXP
) {
1079 /* If service was deliberately started with binary exponential offset
1080 * disabled, we're going to assume we want to refresh a service upon
1084 printf("RS: service '%s' exited during initialization; "
1085 "refreshing\n", rpub
->label
);
1086 rp
->r_flags
|= RS_REFRESHING
; /* restart initialization. */
1089 printf("RS: service '%s' exited during initialization; "
1090 "exiting\n", rpub
->label
);
1091 rp
->r_flags
|= RS_EXITING
; /* don't restart. */
1095 /* If an update process is in progress, end it before doing anything else.
1096 * This is to be on the safe side, since there may be some weird dependencies
1097 * with services under update, while we perform recovery actions.
1099 if(RUPDATE_IS_UPDATING()) {
1100 printf("RS: aborting the update after a crash...\n");
1101 abort_update_proc(ERESTART
);
1104 /* Force exit when no restart is requested. */
1105 norestart
= !(rp
->r_flags
& RS_EXITING
) && (rp
->r_pub
->sys_flags
& SF_NORESTART
);
1107 rp
->r_flags
|= RS_EXITING
;
1108 if((rp
->r_pub
->sys_flags
& SF_DET_RESTART
)
1109 && (rp
->r_restarts
< MAX_DET_RESTART
)) {
1110 /* Detach at cleanup time. */
1111 rp
->r_flags
|= RS_CLEANUP_DETACH
;
1113 if(rp
->r_script
[0] != '\0') {
1114 /* Run script at cleanup time. */
1115 rp
->r_flags
|= RS_CLEANUP_SCRIPT
;
1119 if (rp
->r_flags
& RS_EXITING
) {
1120 /* If a core system service is exiting, we are in trouble. */
1121 if ((rp
->r_pub
->sys_flags
& SF_CORE_SRV
) && !shutting_down
) {
1122 printf("core system service died: %s\n", srv_to_string(rp
));
1126 /* If this service was scheduled for the update, abort the update now. */
1127 if(SRV_IS_UPD_SCHEDULED(rp
)) {
1128 printf("RS: aborting the scheduled update, one of the services part of it is exiting...\n");
1129 abort_update_proc(EDEADSRCDST
);
1132 /* See if a late reply has to be sent. */
1133 r
= (rp
->r_caller_request
== RS_DOWN
1134 || (rp
->r_caller_request
== RS_REFRESH
&& norestart
) ? OK
: EDEADEPT
);
1137 /* Unpublish the service. */
1138 unpublish_service(rp
);
1140 /* Cleanup all the instances of the service. */
1141 get_service_instances(rp
, &rps
, &nr_rps
);
1142 for(i
=0;i
<nr_rps
;i
++) {
1143 cleanup_service(rps
[i
]);
1146 /* If the service is reincarnating, its slot has not been cleaned up.
1147 * Check for this flag now, and attempt to start the service again.
1148 * If this fails, start_service() itself will perform cleanup.
1150 if (rp
->r_flags
& RS_REINCARNATE
) {
1151 rp
->r_flags
&= ~RS_REINCARNATE
;
1152 reincarnate_service(rp
);
1155 else if(rp
->r_flags
& RS_REFRESHING
) {
1156 /* Restart service. */
1157 restart_service(rp
);
1160 /* Determine what to do. If this is the first unexpected
1161 * exit, immediately restart this service. Otherwise use
1162 * a binary exponential backoff.
1164 if (rp
->r_restarts
> 0) {
1165 if (!(rpub
->sys_flags
& SF_NO_BIN_EXP
)) {
1166 rp
->r_backoff
= 1 << MIN(rp
->r_restarts
,(BACKOFF_BITS
-2));
1167 rp
->r_backoff
= MIN(rp
->r_backoff
,MAX_BACKOFF
);
1168 if ((rpub
->sys_flags
& SF_USE_COPY
) && rp
->r_backoff
> 1)
1177 /* Restart service. */
1178 restart_service(rp
);
1182 /*===========================================================================*
1184 *===========================================================================*/
1185 static int run_script(struct rproc
*rp
)
1190 char incarnation_str
[20]; /* Enough for a counter? */
1191 char *envp
[1] = { NULL
};
1192 struct rprocpub
*rpub
;
1195 if (rp
->r_flags
& RS_REFRESHING
)
1197 else if (rp
->r_flags
& RS_NOPINGREPLY
)
1198 reason
= "no-heartbeat";
1199 else reason
= "terminated";
1200 snprintf(incarnation_str
, sizeof(incarnation_str
), "%d", rp
->r_restarts
);
1203 printf("RS: %s:\n", srv_to_string(rp
));
1204 printf("RS: calling script '%s'\n", rp
->r_script
);
1205 printf("RS: reason: '%s'\n", reason
);
1206 printf("RS: incarnation: '%s'\n", incarnation_str
);
1215 execle(_PATH_BSHELL
, "sh", rp
->r_script
, rpub
->label
, reason
,
1216 incarnation_str
, (char*) NULL
, envp
);
1217 printf("RS: run_script: execl '%s' failed: %s\n",
1218 rp
->r_script
, strerror(errno
));
1221 /* Set the privilege structure for the child process. */
1222 if ((r
= getprocnr(pid
, &endpoint
)) != 0)
1223 panic("unable to get child endpoint: %d", r
);
1224 if ((r
= sys_privctl(endpoint
, SYS_PRIV_SET_USER
, NULL
))
1226 return kill_service(rp
,"can't set script privileges",r
);
1228 /* Set the script's privileges on other servers. */
1229 vm_set_priv(endpoint
, NULL
, FALSE
);
1230 if ((r
= vm_set_priv(endpoint
, NULL
, FALSE
)) != OK
) {
1231 return kill_service(rp
,"can't set script VM privs",r
);
1233 /* Allow the script to run. */
1234 if ((r
= sys_privctl(endpoint
, SYS_PRIV_ALLOW
, NULL
)) != OK
) {
1235 return kill_service(rp
,"can't let the script run",r
);
1237 /* Pin RS memory again after fork()ing. */
1238 vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0);
1243 /*===========================================================================*
1245 *===========================================================================*/
1246 void restart_service(struct rproc
*rp
)
1248 /* Restart service via a recovery script or directly. */
1249 struct rproc
*replica_rp
;
1252 /* See if a late reply has to be sent. */
1255 /* Run a recovery script if available. */
1256 if (rp
->r_script
[0] != '\0') {
1259 kill_service(rp
, "unable to run script", errno
);
1264 /* Restart directly. We need a replica if not already available. */
1265 if(rp
->r_next_rp
== NULL
) {
1266 /* Create the replica. */
1267 r
= clone_service(rp
, RST_SYS_PROC
, 0);
1269 kill_service(rp
, "unable to clone service", r
);
1273 replica_rp
= rp
->r_next_rp
;
1275 /* Update the service into the replica. */
1276 r
= update_service(&rp
, &replica_rp
, RS_SWAP
, 0);
1278 kill_service(rp
, "unable to update into new replica", r
);
1282 /* Let the new replica run. */
1283 r
= run_service(replica_rp
, SEF_INIT_RESTART
, 0);
1285 kill_service(rp
, "unable to let the replica run", r
);
1289 /* See if the old version needs to be detached. */
1290 if((rp
->r_pub
->sys_flags
& SF_DET_RESTART
)
1291 && (rp
->r_restarts
< MAX_DET_RESTART
)) {
1292 rp
->r_flags
|= RS_CLEANUP_DETACH
;
1296 printf("RS: %s restarted into %s\n",
1297 srv_to_string(rp
), srv_to_string(replica_rp
));
1300 /*===========================================================================*
1301 * inherit_service_defaults *
1302 *===========================================================================*/
1303 void inherit_service_defaults(def_rp
, rp
)
1304 struct rproc
*def_rp
;
1307 struct rprocpub
*def_rpub
;
1308 struct rprocpub
*rpub
;
1311 def_rpub
= def_rp
->r_pub
;
1314 /* Device, domain, and PCI settings. These properties cannot change. */
1315 rpub
->dev_nr
= def_rpub
->dev_nr
;
1316 rpub
->nr_domain
= def_rpub
->nr_domain
;
1317 for (i
= 0; i
< def_rpub
->nr_domain
; i
++)
1318 rpub
->domain
[i
] = def_rpub
->domain
[i
];
1319 rpub
->pci_acl
= def_rpub
->pci_acl
;
1321 /* Immutable system and privilege flags. */
1322 rpub
->sys_flags
&= ~IMM_SF
;
1323 rpub
->sys_flags
|= (def_rpub
->sys_flags
& IMM_SF
);
1324 rp
->r_priv
.s_flags
&= ~IMM_F
;
1325 rp
->r_priv
.s_flags
|= (def_rp
->r_priv
.s_flags
& IMM_F
);
1327 /* Allowed traps. They cannot change. */
1328 rp
->r_priv
.s_trap_mask
= def_rp
->r_priv
.s_trap_mask
;
1331 /*===========================================================================*
1332 * get_service_instances *
1333 *===========================================================================*/
1334 void get_service_instances(rp
, rps
, length
)
1336 struct rproc
***rps
;
1339 /* Retrieve all the service instances of a given service. */
1340 static struct rproc
*instances
[5];
1344 instances
[nr_instances
++] = rp
;
1345 if(rp
->r_prev_rp
) instances
[nr_instances
++] = rp
->r_prev_rp
;
1346 if(rp
->r_next_rp
) instances
[nr_instances
++] = rp
->r_next_rp
;
1347 if(rp
->r_old_rp
) instances
[nr_instances
++] = rp
->r_old_rp
;
1348 if(rp
->r_new_rp
) instances
[nr_instances
++] = rp
->r_new_rp
;
1351 *length
= nr_instances
;
1354 /*===========================================================================*
1356 *===========================================================================*/
1357 void share_exec(rp_dst
, rp_src
)
1358 struct rproc
*rp_dst
, *rp_src
;
1361 printf("RS: %s shares exec image with %s\n",
1362 srv_to_string(rp_dst
), srv_to_string(rp_src
));
1364 /* Share exec image from rp_src to rp_dst. */
1365 rp_dst
->r_exec_len
= rp_src
->r_exec_len
;
1366 rp_dst
->r_exec
= rp_src
->r_exec
;
1369 /*===========================================================================*
1371 *===========================================================================*/
1379 e_name
= rp
->r_argv
[0];
1381 printf("RS: service '%s' reads exec image from: %s\n", rp
->r_pub
->label
,
1384 r
= stat(e_name
, &sb
);
1388 if (sb
.st_size
< sizeof(Elf_Ehdr
))
1391 fd
= open(e_name
, O_RDONLY
);
1395 rp
->r_exec_len
= sb
.st_size
;
1396 rp
->r_exec
= malloc(rp
->r_exec_len
);
1397 if (rp
->r_exec
== NULL
)
1399 printf("RS: read_exec: unable to allocate %zu bytes\n",
1405 r
= read(fd
, rp
->r_exec
, rp
->r_exec_len
);
1408 if (r
== rp
->r_exec_len
)
1411 printf("RS: read_exec: read failed %d, errno %d\n", r
, e
);
1421 /*===========================================================================*
1423 *===========================================================================*/
1427 /* Free an exec image. */
1428 int slot_nr
, has_shared_exec
;
1429 struct rproc
*other_rp
;
1431 /* Search for some other slot sharing the same exec image. */
1432 has_shared_exec
= FALSE
;
1433 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
1434 other_rp
= &rproc
[slot_nr
]; /* get pointer to slot */
1435 if (other_rp
->r_flags
& RS_IN_USE
&& other_rp
!= rp
1436 && other_rp
->r_exec
== rp
->r_exec
) { /* found! */
1437 has_shared_exec
= TRUE
;
1442 /* If nobody uses our copy of the exec image, we can try to get rid of it. */
1443 if(!has_shared_exec
) {
1445 printf("RS: %s frees exec image\n", srv_to_string(rp
));
1450 printf("RS: %s no longer sharing exec image with %s\n",
1451 srv_to_string(rp
), srv_to_string(other_rp
));
1457 /*===========================================================================*
1459 *===========================================================================*/
1460 int edit_slot(rp
, rs_start
, source
)
1462 struct rs_start
*rs_start
;
1465 /* Edit a given slot to override existing settings. */
1466 struct rprocpub
*rpub
;
1470 int basic_kc
[] = { SYS_BASIC_CALLS
, NULL_C
};
1471 int basic_vmc
[] = { VM_BASIC_CALLS
, NULL_C
};
1475 /* Update IPC target list. */
1476 if (rs_start
->rss_ipclen
==0 || rs_start
->rss_ipclen
+1>sizeof(rp
->r_ipc_list
)){
1477 printf("RS: edit_slot: ipc list empty or long for '%s'\n", rpub
->label
);
1480 s
=sys_datacopy(source
, (vir_bytes
) rs_start
->rss_ipc
,
1481 SELF
, (vir_bytes
) rp
->r_ipc_list
, rs_start
->rss_ipclen
);
1482 if (s
!= OK
) return(s
);
1483 rp
->r_ipc_list
[rs_start
->rss_ipclen
]= '\0';
1486 if(rs_start
->rss_nr_irq
== RSS_IRQ_ALL
) {
1487 rs_start
->rss_nr_irq
= 0;
1490 rp
->r_priv
.s_flags
|= CHECK_IRQ
;
1492 if (rs_start
->rss_nr_irq
> NR_IRQ
) {
1493 printf("RS: edit_slot: too many IRQs requested\n");
1496 rp
->r_nr_irq
= rp
->r_priv
.s_nr_irq
= rs_start
->rss_nr_irq
;
1497 for (i
= 0; i
<rp
->r_priv
.s_nr_irq
; i
++) {
1498 rp
->r_irq_tab
[i
]= rp
->r_priv
.s_irq_tab
[i
]= rs_start
->rss_irq
[i
];
1500 printf("RS: edit_slot: IRQ %d\n", rp
->r_priv
.s_irq_tab
[i
]);
1503 /* Update I/O ranges. */
1504 if(rs_start
->rss_nr_io
== RSS_IO_ALL
) {
1505 rs_start
->rss_nr_io
= 0;
1508 rp
->r_priv
.s_flags
|= CHECK_IO_PORT
;
1510 if (rs_start
->rss_nr_io
> NR_IO_RANGE
) {
1511 printf("RS: edit_slot: too many I/O ranges requested\n");
1514 rp
->r_nr_io_range
= rp
->r_priv
.s_nr_io_range
= rs_start
->rss_nr_io
;
1515 for (i
= 0; i
<rp
->r_priv
.s_nr_io_range
; i
++) {
1516 rp
->r_priv
.s_io_tab
[i
].ior_base
= rs_start
->rss_io
[i
].base
;
1517 rp
->r_priv
.s_io_tab
[i
].ior_limit
=
1518 rs_start
->rss_io
[i
].base
+rs_start
->rss_io
[i
].len
-1;
1519 rp
->r_io_tab
[i
] = rp
->r_priv
.s_io_tab
[i
];
1521 printf("RS: edit_slot: I/O [%x..%x]\n",
1522 rp
->r_priv
.s_io_tab
[i
].ior_base
,
1523 rp
->r_priv
.s_io_tab
[i
].ior_limit
);
1526 /* Update kernel call mask. Inherit basic kernel calls when asked to. */
1527 memcpy(rp
->r_priv
.s_k_call_mask
, rs_start
->rss_system
,
1528 sizeof(rp
->r_priv
.s_k_call_mask
));
1529 if(rs_start
->rss_flags
& RSS_SYS_BASIC_CALLS
) {
1530 fill_call_mask(basic_kc
, NR_SYS_CALLS
,
1531 rp
->r_priv
.s_k_call_mask
, KERNEL_CALL
, FALSE
);
1534 /* Update VM call mask. Inherit basic VM calls. */
1535 memcpy(rpub
->vm_call_mask
, rs_start
->rss_vm
,
1536 sizeof(rpub
->vm_call_mask
));
1537 if(rs_start
->rss_flags
& RSS_VM_BASIC_CALLS
) {
1538 fill_call_mask(basic_vmc
, NR_VM_CALLS
,
1539 rpub
->vm_call_mask
, VM_RQ_BASE
, FALSE
);
1542 /* Update control labels. */
1543 if(rs_start
->rss_nr_control
> 0) {
1545 if (rs_start
->rss_nr_control
> RS_NR_CONTROL
) {
1546 printf("RS: edit_slot: too many control labels\n");
1549 for (i
=0; i
<rs_start
->rss_nr_control
; i
++) {
1550 s
= copy_label(source
, rs_start
->rss_control
[i
].l_addr
,
1551 rs_start
->rss_control
[i
].l_len
, rp
->r_control
[i
],
1552 sizeof(rp
->r_control
[i
]));
1556 rp
->r_nr_control
= rs_start
->rss_nr_control
;
1559 printf("RS: edit_slot: control labels:");
1560 for (i
=0; i
<rp
->r_nr_control
; i
++)
1561 printf(" %s", rp
->r_control
[i
]);
1566 /* Update signal manager. */
1567 rp
->r_priv
.s_sig_mgr
= rs_start
->rss_sigmgr
;
1569 /* Update scheduling properties if possible. */
1570 if(rp
->r_scheduler
!= NONE
) {
1571 rp
->r_scheduler
= rs_start
->rss_scheduler
;
1572 rp
->r_priority
= rs_start
->rss_priority
;
1573 rp
->r_quantum
= rs_start
->rss_quantum
;
1574 rp
->r_cpu
= rs_start
->rss_cpu
;
1577 /* Update command and arguments. */
1578 if (rs_start
->rss_cmdlen
> MAX_COMMAND_LEN
-1) return(E2BIG
);
1579 s
=sys_datacopy(source
, (vir_bytes
) rs_start
->rss_cmd
,
1580 SELF
, (vir_bytes
) rp
->r_cmd
, rs_start
->rss_cmdlen
);
1581 if (s
!= OK
) return(s
);
1582 rp
->r_cmd
[rs_start
->rss_cmdlen
] = '\0'; /* ensure it is terminated */
1583 if (rp
->r_cmd
[0] != '/') return(EINVAL
); /* insist on absolute path */
1585 /* Build cmd dependencies (argv). */
1588 /* Copy in the program name. */
1589 if (rs_start
->rss_prognamelen
> sizeof(rpub
->proc_name
)-1) return(E2BIG
);
1590 s
=sys_datacopy(source
, (vir_bytes
) rs_start
->rss_progname
,
1591 SELF
, (vir_bytes
) rpub
->proc_name
, rs_start
->rss_prognamelen
);
1592 if (s
!= OK
) return(s
);
1593 rpub
->proc_name
[rs_start
->rss_prognamelen
] = '\0';
1595 /* Update label if not already set. */
1596 if(!strcmp(rpub
->label
, "")) {
1597 if(rs_start
->rss_label
.l_len
> 0) {
1598 /* RS_UP caller has supplied a custom label for this service. */
1599 int s
= copy_label(source
, rs_start
->rss_label
.l_addr
,
1600 rs_start
->rss_label
.l_len
, rpub
->label
, sizeof(rpub
->label
));
1604 printf("RS: edit_slot: using label (custom) '%s'\n", rpub
->label
);
1606 /* Default label for the service. */
1607 label
= rpub
->proc_name
;
1609 memcpy(rpub
->label
, label
, len
);
1610 rpub
->label
[len
]= '\0';
1612 printf("RS: edit_slot: using label (from proc_name) '%s'\n",
1617 /* Update recovery script. */
1618 if (rs_start
->rss_scriptlen
> MAX_SCRIPT_LEN
-1) return(E2BIG
);
1619 if (rs_start
->rss_script
!= NULL
&& rs_start
->rss_scriptlen
> 0
1620 && !(rpub
->sys_flags
& SF_CORE_SRV
)) {
1621 s
=sys_datacopy(source
, (vir_bytes
) rs_start
->rss_script
,
1622 SELF
, (vir_bytes
) rp
->r_script
, rs_start
->rss_scriptlen
);
1623 if (s
!= OK
) return(s
);
1624 rp
->r_script
[rs_start
->rss_scriptlen
] = '\0';
1625 rpub
->sys_flags
|= SF_USE_SCRIPT
;
1628 /* Update system flags and in-memory copy. */
1629 if ((rs_start
->rss_flags
& RSS_COPY
) && !(rpub
->sys_flags
& SF_USE_COPY
)) {
1632 struct rprocpub
*rpub2
;
1635 if(rs_start
->rss_flags
& RSS_REUSE
) {
1638 for(i
= 0; i
< NR_SYS_PROCS
; i
++) {
1640 rpub2
= rproc
[i
].r_pub
;
1641 if(strcmp(rpub
->proc_name
, rpub2
->proc_name
) == 0 &&
1642 (rpub2
->sys_flags
& SF_USE_COPY
)) {
1643 /* We have found the same binary that's
1644 * already been copied */
1655 share_exec(rp
, rp2
);
1660 rpub
->sys_flags
|= SF_USE_COPY
;
1662 if (rs_start
->rss_flags
& RSS_REPLICA
) {
1663 rpub
->sys_flags
|= SF_USE_REPL
;
1665 if (rs_start
->rss_flags
& RSS_NO_BIN_EXP
) {
1666 rpub
->sys_flags
|= SF_NO_BIN_EXP
;
1668 if (rs_start
->rss_flags
& RSS_DETACH
) {
1669 rpub
->sys_flags
|= SF_DET_RESTART
;
1672 rpub
->sys_flags
&= ~SF_DET_RESTART
;
1674 if (rs_start
->rss_flags
& RSS_NORESTART
) {
1675 if(rpub
->sys_flags
& SF_CORE_SRV
) {
1678 rpub
->sys_flags
|= SF_NORESTART
;
1681 rpub
->sys_flags
&= ~SF_NORESTART
;
1684 /* Update period. */
1685 if(rpub
->endpoint
!= RS_PROC_NR
) {
1686 rp
->r_period
= rs_start
->rss_period
;
1689 /* Update restarts. */
1690 if(rs_start
->rss_restarts
) {
1691 rp
->r_restarts
= rs_start
->rss_restarts
;
1694 /* Update number of ASR live updates. */
1695 if(rs_start
->rss_asr_count
>= 0) {
1696 rp
->r_asr_count
= rs_start
->rss_asr_count
;
1699 /* (Re)initialize privilege settings. */
1700 init_privs(rp
, &rp
->r_priv
);
1705 /*===========================================================================*
1707 *===========================================================================*/
1708 int init_slot(rp
, rs_start
, source
)
1710 struct rs_start
*rs_start
;
1713 /* Initialize a slot as requested by the client. */
1714 struct rprocpub
*rpub
;
1719 /* All dynamically created services get the same sys and privilege flags, and
1720 * allowed traps. Other privilege settings can be specified at runtime. The
1721 * privilege id is dynamically allocated by the kernel.
1723 rpub
->sys_flags
= DSRV_SF
; /* system flags */
1724 rp
->r_priv
.s_flags
= DSRV_F
; /* privilege flags */
1725 rp
->r_priv
.s_init_flags
= DSRV_I
; /* init flags */
1726 rp
->r_priv
.s_trap_mask
= DSRV_T
; /* allowed traps */
1727 rp
->r_priv
.s_bak_sig_mgr
= NONE
; /* backup signal manager */
1729 /* Initialize uid. */
1730 rp
->r_uid
= rs_start
->rss_uid
;
1732 /* Initialize device driver settings. */
1733 if (rs_start
->rss_nr_domain
< 0 || rs_start
->rss_nr_domain
> NR_DOMAIN
) {
1734 printf("RS: init_slot: too many domains\n");
1738 rpub
->dev_nr
= rs_start
->rss_major
;
1739 rpub
->nr_domain
= rs_start
->rss_nr_domain
;
1740 for (i
= 0; i
< rs_start
->rss_nr_domain
; i
++)
1741 rpub
->domain
[i
] = rs_start
->rss_domain
[i
];
1742 rpub
->devman_id
= rs_start
->devman_id
;
1744 /* Initialize pci settings. */
1745 if (rs_start
->rss_nr_pci_id
> RS_NR_PCI_DEVICE
) {
1746 printf("RS: init_slot: too many PCI device IDs\n");
1749 rpub
->pci_acl
.rsp_nr_device
= rs_start
->rss_nr_pci_id
;
1750 for (i
= 0; i
<rpub
->pci_acl
.rsp_nr_device
; i
++) {
1751 rpub
->pci_acl
.rsp_device
[i
].vid
= rs_start
->rss_pci_id
[i
].vid
;
1752 rpub
->pci_acl
.rsp_device
[i
].did
= rs_start
->rss_pci_id
[i
].did
;
1753 rpub
->pci_acl
.rsp_device
[i
].sub_vid
= rs_start
->rss_pci_id
[i
].sub_vid
;
1754 rpub
->pci_acl
.rsp_device
[i
].sub_did
= rs_start
->rss_pci_id
[i
].sub_did
;
1756 printf("RS: init_slot: PCI %04x/%04x (sub %04x:%04x)\n",
1757 rpub
->pci_acl
.rsp_device
[i
].vid
,
1758 rpub
->pci_acl
.rsp_device
[i
].did
,
1759 rpub
->pci_acl
.rsp_device
[i
].sub_vid
,
1760 rpub
->pci_acl
.rsp_device
[i
].sub_did
);
1762 if (rs_start
->rss_nr_pci_class
> RS_NR_PCI_CLASS
) {
1763 printf("RS: init_slot: too many PCI class IDs\n");
1766 rpub
->pci_acl
.rsp_nr_class
= rs_start
->rss_nr_pci_class
;
1767 for (i
= 0; i
<rpub
->pci_acl
.rsp_nr_class
; i
++) {
1768 rpub
->pci_acl
.rsp_class
[i
].pciclass
=rs_start
->rss_pci_class
[i
].pciclass
;
1769 rpub
->pci_acl
.rsp_class
[i
].mask
= rs_start
->rss_pci_class
[i
].mask
;
1771 printf("RS: init_slot: PCI class %06x mask %06x\n",
1772 (unsigned int) rpub
->pci_acl
.rsp_class
[i
].pciclass
,
1773 (unsigned int) rpub
->pci_acl
.rsp_class
[i
].mask
);
1776 /* Initialize some fields. */
1777 rp
->r_asr_count
= 0; /* no ASR updates yet */
1778 rp
->r_restarts
= 0; /* no restarts yet */
1779 rp
->r_old_rp
= NULL
; /* no old version yet */
1780 rp
->r_new_rp
= NULL
; /* no new version yet */
1781 rp
->r_prev_rp
= NULL
; /* no prev replica yet */
1782 rp
->r_next_rp
= NULL
; /* no next replica yet */
1783 rp
->r_exec
= NULL
; /* no in-memory copy yet */
1785 rp
->r_script
[0]= '\0'; /* no recovery script yet */
1786 rpub
->label
[0]= '\0'; /* no label yet */
1787 rp
->r_scheduler
= -1; /* no scheduler yet */
1788 rp
->r_priv
.s_sig_mgr
= -1; /* no signal manager yet */
1789 rp
->r_map_prealloc_addr
= 0; /* no preallocated memory */
1790 rp
->r_map_prealloc_len
= 0;
1791 rp
->r_init_err
= ERESTART
; /* default init error `*/
1793 /* Initialize editable slot settings. */
1794 return edit_slot(rp
, rs_start
, source
);
1797 /*===========================================================================*
1799 *===========================================================================*/
1800 int clone_slot(rp
, clone_rpp
)
1802 struct rproc
**clone_rpp
;
1805 struct rproc
*clone_rp
;
1806 struct rprocpub
*rpub
, *clone_rpub
;
1808 /* Allocate a system service slot for the clone. */
1809 r
= alloc_slot(&clone_rp
);
1811 printf("RS: clone_slot: unable to allocate a new slot: %d\n", r
);
1816 clone_rpub
= clone_rp
->r_pub
;
1818 /* Synch the privilege structure of the source with the kernel. */
1819 if ((r
= sys_getpriv(&(rp
->r_priv
), rpub
->endpoint
)) != OK
) {
1820 panic("unable to synch privilege structure: %d", r
);
1825 *clone_rpub
= *rpub
;
1828 clone_rp
->r_init_err
= ERESTART
; /* default init error */
1829 clone_rp
->r_flags
&= ~RS_ACTIVE
; /* the clone is not active yet */
1830 clone_rp
->r_pid
= -1; /* no pid yet */
1831 clone_rpub
->endpoint
= -1; /* no endpoint yet */
1832 clone_rp
->r_pub
= clone_rpub
; /* restore pointer to public entry */
1833 build_cmd_dep(clone_rp
); /* rebuild cmd dependencies */
1834 if(clone_rpub
->sys_flags
& SF_USE_COPY
) {
1835 share_exec(clone_rp
, rp
); /* share exec image */
1837 clone_rp
->r_old_rp
= NULL
; /* no old version yet */
1838 clone_rp
->r_new_rp
= NULL
; /* no new version yet */
1839 clone_rp
->r_prev_rp
= NULL
; /* no prev replica yet */
1840 clone_rp
->r_next_rp
= NULL
; /* no next replica yet */
1842 /* Force dynamic privilege id. */
1843 clone_rp
->r_priv
.s_flags
|= DYN_PRIV_ID
;
1845 /* Clear instance flags. */
1846 clone_rp
->r_priv
.s_flags
&= ~(LU_SYS_PROC
| RST_SYS_PROC
);
1847 clone_rp
->r_priv
.s_init_flags
= 0;
1849 *clone_rpp
= clone_rp
;
1853 /*===========================================================================*
1854 * swap_slot_pointer *
1855 *===========================================================================*/
1856 static void swap_slot_pointer(struct rproc
**rpp
, struct rproc
*src_rp
,
1857 struct rproc
*dst_rp
)
1859 if(*rpp
== src_rp
) {
1862 else if(*rpp
== dst_rp
) {
1867 /*===========================================================================*
1869 *===========================================================================*/
1870 void swap_slot(src_rpp
, dst_rpp
)
1871 struct rproc
**src_rpp
;
1872 struct rproc
**dst_rpp
;
1874 /* Swap two service slots. */
1875 struct rproc
*src_rp
, *dst_rp
;
1876 struct rprocpub
*src_rpub
, *dst_rpub
;
1877 struct rproc orig_src_rproc
, orig_dst_rproc
;
1878 struct rprocpub orig_src_rprocpub
, orig_dst_rprocpub
;
1879 struct rprocupd
*prev_rpupd
, *rpupd
;
1883 src_rpub
= src_rp
->r_pub
;
1884 dst_rpub
= dst_rp
->r_pub
;
1886 /* Save existing data first. */
1887 orig_src_rproc
= *src_rp
;
1888 orig_src_rprocpub
= *src_rpub
;
1889 orig_dst_rproc
= *dst_rp
;
1890 orig_dst_rprocpub
= *dst_rpub
;
1893 *src_rp
= orig_dst_rproc
;
1894 *src_rpub
= orig_dst_rprocpub
;
1895 *dst_rp
= orig_src_rproc
;
1896 *dst_rpub
= orig_src_rprocpub
;
1898 /* Restore public entries and update descriptors. */
1899 src_rp
->r_pub
= orig_src_rproc
.r_pub
;
1900 dst_rp
->r_pub
= orig_dst_rproc
.r_pub
;
1901 src_rp
->r_upd
= orig_src_rproc
.r_upd
;
1902 dst_rp
->r_upd
= orig_dst_rproc
.r_upd
;
1904 /* Rebuild command dependencies. */
1905 build_cmd_dep(src_rp
);
1906 build_cmd_dep(dst_rp
);
1908 /* Swap local slot pointers. */
1909 swap_slot_pointer(&src_rp
->r_prev_rp
, src_rp
, dst_rp
);
1910 swap_slot_pointer(&src_rp
->r_next_rp
, src_rp
, dst_rp
);
1911 swap_slot_pointer(&src_rp
->r_old_rp
, src_rp
, dst_rp
);
1912 swap_slot_pointer(&src_rp
->r_new_rp
, src_rp
, dst_rp
);
1913 swap_slot_pointer(&dst_rp
->r_prev_rp
, src_rp
, dst_rp
);
1914 swap_slot_pointer(&dst_rp
->r_next_rp
, src_rp
, dst_rp
);
1915 swap_slot_pointer(&dst_rp
->r_old_rp
, src_rp
, dst_rp
);
1916 swap_slot_pointer(&dst_rp
->r_new_rp
, src_rp
, dst_rp
);
1918 /* Swap global slot pointers. */
1919 RUPDATE_ITER(rupdate
.first_rpupd
, prev_rpupd
, rpupd
,
1920 swap_slot_pointer(&rpupd
->rp
, src_rp
, dst_rp
);
1922 swap_slot_pointer(&rproc_ptr
[_ENDPOINT_P(src_rp
->r_pub
->endpoint
)],
1924 swap_slot_pointer(&rproc_ptr
[_ENDPOINT_P(dst_rp
->r_pub
->endpoint
)],
1927 /* Adjust input pointers. */
1932 /*===========================================================================*
1933 * lookup_slot_by_label *
1934 *===========================================================================*/
1935 struct rproc
* lookup_slot_by_label(char *label
)
1937 /* Lookup a service slot matching the given label. */
1940 struct rprocpub
*rpub
;
1942 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
1943 rp
= &rproc
[slot_nr
];
1944 if (!(rp
->r_flags
& RS_ACTIVE
)) {
1948 if (strcmp(rpub
->label
, label
) == 0) {
1956 /*===========================================================================*
1957 * lookup_slot_by_pid *
1958 *===========================================================================*/
1959 struct rproc
* lookup_slot_by_pid(pid_t pid
)
1961 /* Lookup a service slot matching the given pid. */
1969 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
1970 rp
= &rproc
[slot_nr
];
1971 if (!(rp
->r_flags
& RS_IN_USE
)) {
1974 if (rp
->r_pid
== pid
) {
1982 /*===========================================================================*
1983 * lookup_slot_by_dev_nr *
1984 *===========================================================================*/
1985 struct rproc
* lookup_slot_by_dev_nr(dev_t dev_nr
)
1987 /* Lookup a service slot matching the given device number. */
1990 struct rprocpub
*rpub
;
1996 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
1997 rp
= &rproc
[slot_nr
];
1999 if (!(rp
->r_flags
& RS_IN_USE
)) {
2002 if (rpub
->dev_nr
== dev_nr
) {
2010 /*===========================================================================*
2011 * lookup_slot_by_domain *
2012 *===========================================================================*/
2013 struct rproc
* lookup_slot_by_domain(int domain
)
2015 /* Lookup a service slot matching the given protocol family. */
2018 struct rprocpub
*rpub
;
2024 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
2025 rp
= &rproc
[slot_nr
];
2027 if (!(rp
->r_flags
& RS_IN_USE
)) {
2030 for (i
= 0; i
< rpub
->nr_domain
; i
++)
2031 if (rpub
->domain
[i
] == domain
)
2038 /*===========================================================================*
2039 * lookup_slot_by_flags *
2040 *===========================================================================*/
2041 struct rproc
* lookup_slot_by_flags(int flags
)
2043 /* Lookup a service slot matching the given flags. */
2051 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
2052 rp
= &rproc
[slot_nr
];
2053 if (!(rp
->r_flags
& RS_IN_USE
)) {
2056 if (rp
->r_flags
& flags
) {
2064 /*===========================================================================*
2066 *===========================================================================*/
2070 /* Alloc a new system service slot. */
2073 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
2074 *rpp
= &rproc
[slot_nr
]; /* get pointer to slot */
2075 if (!((*rpp
)->r_flags
& RS_IN_USE
)) /* check if available */
2078 if (slot_nr
>= NR_SYS_PROCS
) {
2085 /*===========================================================================*
2087 *===========================================================================*/
2091 /* Free a system service slot. */
2092 struct rprocpub
*rpub
;
2096 /* Send a late reply if there is any pending. */
2099 /* Free memory if necessary. */
2100 if(rpub
->sys_flags
& SF_USE_COPY
) {
2104 /* Mark slot as no longer in use.. */
2107 rpub
->in_use
= FALSE
;
2108 rproc_ptr
[_ENDPOINT_P(rpub
->endpoint
)] = NULL
;
2112 /*===========================================================================*
2114 *===========================================================================*/
2115 static char *get_next_name(ptr
, name
, caller_label
)
2120 /* Get the next name from the list of (IPC) program names.
2125 for (p
= ptr
; p
[0] != '\0'; p
= q
)
2127 /* Skip leading space */
2128 while (p
[0] != '\0' && isspace((unsigned char)p
[0]))
2131 /* Find start of next word */
2133 while (q
[0] != '\0' && !isspace((unsigned char)q
[0]))
2138 if (len
> RS_MAX_LABEL_LEN
)
2141 "rs:get_next_name: bad ipc list entry '%.*s' for %s: too long\n",
2142 (int) len
, p
, caller_label
);
2145 memcpy(name
, p
, len
);
2148 return q
; /* found another */
2151 return NULL
; /* done */
2154 /*===========================================================================*
2156 *===========================================================================*/
2157 void add_forward_ipc(rp
, privp
)
2161 /* Add IPC send permissions to a process based on that process's IPC
2164 char name
[RS_MAX_LABEL_LEN
+1], *p
;
2166 endpoint_t endpoint
;
2170 struct rprocpub
*rpub
;
2175 while ((p
= get_next_name(p
, name
, rpub
->label
)) != NULL
) {
2177 if (strcmp(name
, "SYSTEM") == 0)
2179 else if (strcmp(name
, "USER") == 0)
2180 endpoint
= INIT_PROC_NR
; /* all user procs */
2183 /* Set a privilege bit for every process matching the
2184 * given process name. It is perfectly fine if this
2185 * loop does not find any matches, as the target
2186 * process(es) may not have been started yet. See
2187 * add_backward_ipc() below.
2189 for (rrp
=BEG_RPROC_ADDR
; rrp
<END_RPROC_ADDR
; rrp
++) {
2190 if (!(rrp
->r_flags
& RS_IN_USE
))
2193 if (!strcmp(rrp
->r_pub
->proc_name
, name
)) {
2195 printf(" RS: add_forward_ipc: setting"
2196 " sendto bit for %d...\n",
2197 rrp
->r_pub
->endpoint
);
2200 priv_id
= rrp
->r_priv
.s_id
;
2201 set_sys_bit(privp
->s_ipc_to
, priv_id
);
2208 /* This code only applies to the exception cases. */
2209 if ((r
= sys_getpriv(&priv
, endpoint
)) < 0)
2212 "add_forward_ipc: unable to get priv_id for '%s': %d\n",
2218 printf(" RS: add_forward_ipc: setting sendto bit for %d...\n",
2222 set_sys_bit(privp
->s_ipc_to
, priv_id
);
2227 /*===========================================================================*
2228 * add_backward_ipc *
2229 *===========================================================================*/
2230 void add_backward_ipc(rp
, privp
)
2234 /* Add IPC send permissions to a process based on other processes' IPC
2235 * lists. This is enough to allow each such two processes to talk to
2236 * each other, as the kernel guarantees send mask symmetry. We need to
2237 * add these permissions now because the current process may not yet
2238 * have existed at the time that the other process was initialized.
2240 char name
[RS_MAX_LABEL_LEN
+1], *p
;
2242 struct rprocpub
*rrpub
;
2244 int priv_id
, is_ipc_all
, is_ipc_all_sys
;
2246 proc_name
= rp
->r_pub
->proc_name
;
2248 for (rrp
=BEG_RPROC_ADDR
; rrp
<END_RPROC_ADDR
; rrp
++) {
2249 if (!(rrp
->r_flags
& RS_IN_USE
))
2252 if (!rrp
->r_ipc_list
[0])
2255 /* If the process being checked is set to allow IPC to all
2256 * other processes, or for all other system processes and the
2257 * target process is a system process, add a permission bit.
2261 is_ipc_all
= !strcmp(rrp
->r_ipc_list
, RSS_IPC_ALL
);
2262 is_ipc_all_sys
= !strcmp(rrp
->r_ipc_list
, RSS_IPC_ALL_SYS
);
2265 (is_ipc_all_sys
&& (privp
->s_flags
& SYS_PROC
))) {
2267 printf(" RS: add_backward_ipc: setting sendto bit "
2268 "for %d...\n", rrpub
->endpoint
);
2270 priv_id
= rrp
->r_priv
.s_id
;
2271 set_sys_bit(privp
->s_ipc_to
, priv_id
);
2276 /* An IPC target list was provided for the process being
2277 * checked here. Make sure that the name of the new process
2278 * is in that process's list. There may be multiple matches.
2280 p
= rrp
->r_ipc_list
;
2282 while ((p
= get_next_name(p
, name
, rrpub
->label
)) != NULL
) {
2283 if (!strcmp(proc_name
, name
)) {
2285 printf(" RS: add_backward_ipc: setting sendto"
2289 priv_id
= rrp
->r_priv
.s_id
;
2290 set_sys_bit(privp
->s_ipc_to
, priv_id
);
2297 /*===========================================================================*
2299 *===========================================================================*/
2300 void init_privs(rp
, privp
)
2305 int is_ipc_all
, is_ipc_all_sys
;
2307 /* Clear s_ipc_to */
2308 fill_send_mask(&privp
->s_ipc_to
, FALSE
);
2310 is_ipc_all
= !strcmp(rp
->r_ipc_list
, RSS_IPC_ALL
);
2311 is_ipc_all_sys
= !strcmp(rp
->r_ipc_list
, RSS_IPC_ALL_SYS
);
2314 printf(" RS: init_privs: ipc list is '%s'...\n", rp
->r_ipc_list
);
2317 if (!is_ipc_all
&& !is_ipc_all_sys
)
2319 add_forward_ipc(rp
, privp
);
2320 add_backward_ipc(rp
, privp
);
2325 for (i
= 0; i
<NR_SYS_PROCS
; i
++)
2327 if (is_ipc_all
|| i
!= USER_PRIV_ID
)
2328 set_sys_bit(privp
->s_ipc_to
, i
);