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
);
524 sys_privctl(rpub
->endpoint
, SYS_PRIV_ALLOW
, NULL
);
527 /*===========================================================================*
529 *===========================================================================*/
530 int create_service(rp
)
533 /* Create the given system service. */
534 int child_proc_nr_e
, child_proc_nr_n
; /* child process slot */
535 pid_t child_pid
; /* child's process id */
536 int s
, use_copy
, has_replica
;
537 extern char **environ
;
538 struct rprocpub
*rpub
;
541 use_copy
= (rpub
->sys_flags
& SF_USE_COPY
);
542 has_replica
= (rp
->r_old_rp
543 || (rp
->r_prev_rp
&& !(rp
->r_prev_rp
->r_flags
& RS_TERMINATED
)));
545 /* Do we need an existing replica to create the service? */
546 if(!has_replica
&& (rpub
->sys_flags
& SF_NEED_REPL
)) {
547 printf("RS: unable to create service '%s' without a replica\n",
553 /* Do we need an in-memory copy to create the service? */
554 if(!use_copy
&& (rpub
->sys_flags
& SF_NEED_COPY
)) {
555 printf("RS: unable to create service '%s' without an in-memory copy\n",
561 /* Do we have a copy or a command to create the service? */
562 if(!use_copy
&& !strcmp(rp
->r_cmd
, "")) {
563 printf("RS: unable to create service '%s' without a copy or command\n",
569 /* Now fork and branch for parent and child process (and check for error).
570 * After fork()ing, we need to pin RS memory again or pagefaults will occur
574 printf("RS: forking child with srv_fork()...\n");
575 child_pid
= srv_fork(rp
->r_uid
, 0); /* Force group to operator for now */
577 printf("RS: srv_fork() failed (error %d)\n", child_pid
);
582 /* Get endpoint of the child. */
583 if ((s
= getprocnr(child_pid
, &child_proc_nr_e
)) != 0)
584 panic("unable to get child endpoint: %d", s
);
586 /* There is now a child process. Update the system process table. */
587 child_proc_nr_n
= _ENDPOINT_P(child_proc_nr_e
);
588 rp
->r_flags
= RS_IN_USE
; /* mark slot in use */
589 rpub
->endpoint
= child_proc_nr_e
; /* set child endpoint */
590 rp
->r_pid
= child_pid
; /* set child pid */
591 rp
->r_check_tm
= 0; /* not checked yet */
592 rp
->r_alive_tm
= getticks(); /* currently alive */
593 rp
->r_stop_tm
= 0; /* not exiting yet */
594 rp
->r_backoff
= 0; /* not to be restarted */
595 rproc_ptr
[child_proc_nr_n
] = rp
; /* mapping for fast access */
596 rpub
->in_use
= TRUE
; /* public entry is now in use */
598 /* Set and synch the privilege structure for the new service. */
599 if ((s
= sys_privctl(child_proc_nr_e
, SYS_PRIV_SET_SYS
, &rp
->r_priv
)) != OK
600 || (s
= sys_getpriv(&rp
->r_priv
, child_proc_nr_e
)) != OK
) {
601 printf("RS: unable to set privilege structure: %d\n", s
);
603 vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0);
607 /* Set the scheduler for this process */
608 if ((s
= sched_init_proc(rp
)) != OK
) {
609 printf("RS: unable to start scheduling: %d\n", s
);
611 vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0);
615 /* Copy the executable image into the child process. If no copy exists,
616 * allocate one and free it right after exec completes.
620 printf("RS: %s uses an in-memory copy\n",
624 if ((s
= read_exec(rp
)) != OK
) {
625 printf("RS: read_exec failed: %d\n", s
);
627 vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0);
632 printf("RS: execing child with srv_execve()...\n");
633 s
= srv_execve(child_proc_nr_e
, rp
->r_exec
, rp
->r_exec_len
, rpub
->proc_name
,
634 rp
->r_argv
, environ
);
635 vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0);
637 printf("RS: srv_execve failed: %d\n", s
);
645 /* The purpose of non-blocking forks is to avoid involving VFS in the forking
646 * process, because VFS may be blocked on a sendrec() to a MFS that is
647 * waiting for a endpoint update for a dead driver. We have just published
648 * that update, but VFS may still be blocked. As a result, VFS may not yet
649 * have received PM's fork message. Hence, if we call mapdriver()
650 * immediately, VFS may not know about the process and thus refuse to add the
651 * driver entry. The following temporary hack works around this by forcing
652 * blocking communication from PM to VFS. Once VFS has been made non-blocking
653 * towards MFS instances, this hack and the big part of srv_fork() can go.
657 /* If this is a RS instance, pin memory. */
658 if(rp
->r_priv
.s_flags
& ROOT_SYS_PROC
) {
660 printf("RS: pinning memory of RS instance %s\n", srv_to_string(rp
));
662 s
= vm_memctl(rpub
->endpoint
, VM_RS_MEM_PIN
, 0, 0);
664 printf("vm_memctl failed: %d\n", s
);
670 /* If this is a VM instance, let VM know now. */
671 if(rp
->r_priv
.s_flags
& VM_SYS_PROC
) {
673 struct rproc
**rs_rps
;
677 printf("RS: informing VM of instance %s\n", srv_to_string(rp
));
679 s
= vm_memctl(rpub
->endpoint
, VM_RS_MEM_MAKE_VM
, 0, 0);
681 printf("vm_memctl failed: %d\n", s
);
686 /* VM may start actually pinning memory for us only now.
687 * Ask again for all our instances.
689 rs_rp
= rproc_ptr
[_ENDPOINT_P(RS_PROC_NR
)];
690 get_service_instances(rs_rp
, &rs_rps
, &nr_rs_rps
);
691 for(i
=0;i
<nr_rs_rps
;i
++) {
692 vm_memctl(rs_rps
[i
]->r_pub
->endpoint
, VM_RS_MEM_PIN
, 0, 0);
696 /* Tell VM about allowed calls. */
697 if ((s
= vm_set_priv(rpub
->endpoint
, &rpub
->vm_call_mask
[0], TRUE
)) != OK
) {
698 printf("RS: vm_set_priv failed: %d\n", s
);
704 printf("RS: %s created\n", srv_to_string(rp
));
709 /*===========================================================================*
711 *===========================================================================*/
712 int clone_service(struct rproc
*rp
, int instance_flag
, int init_flags
)
714 /* Clone the given system service instance. */
715 struct rproc
*replica_rp
;
716 struct rprocpub
*replica_rpub
;
717 struct rproc
**rp_link
;
718 struct rproc
**replica_link
;
724 printf("RS: %s creating a replica\n", srv_to_string(rp
));
726 /* VM can only reliably support one replica at the time for now.
727 * XXX TO-DO: Fix VM's rs_memctl_make_vm_instance to allow multiple replicas.
729 if(rp
->r_pub
->endpoint
== VM_PROC_NR
&& instance_flag
== LU_SYS_PROC
731 cleanup_service_now(rp
->r_next_rp
);
732 rp
->r_next_rp
= NULL
;
736 if((r
= clone_slot(rp
, &replica_rp
)) != OK
) {
739 replica_rpub
= replica_rp
->r_pub
;
741 /* Clone is a live updated or restarted service instance? */
742 if(instance_flag
== LU_SYS_PROC
) {
743 rp_link
= &rp
->r_new_rp
;
744 replica_link
= &replica_rp
->r_old_rp
;
747 rp_link
= &rp
->r_next_rp
;
748 replica_link
= &replica_rp
->r_prev_rp
;
750 replica_rp
->r_priv
.s_flags
|= instance_flag
;
751 replica_rp
->r_priv
.s_init_flags
|= init_flags
;
753 /* Link the two slots. */
754 *rp_link
= replica_rp
;
757 /* Create a new replica of the service. */
758 r
= create_service(replica_rp
);
764 /* If this instance is for restarting RS, set up a backup signal manager. */
765 rs_flags
= (ROOT_SYS_PROC
| RST_SYS_PROC
);
766 if((replica_rp
->r_priv
.s_flags
& rs_flags
) == rs_flags
) {
767 rs_rp
= rproc_ptr
[_ENDPOINT_P(RS_PROC_NR
)];
769 /* Update signal managers. */
770 r
= update_sig_mgrs(rs_rp
, SELF
, replica_rpub
->endpoint
);
772 r
= update_sig_mgrs(replica_rp
, SELF
, NONE
);
776 return kill_service(replica_rp
, "update_sig_mgrs failed", r
);
783 /*===========================================================================*
785 *===========================================================================*/
786 int publish_service(rp
)
787 struct rproc
*rp
; /* pointer to service slot */
789 /* Publish a service. */
791 struct rprocpub
*rpub
;
792 struct rs_pci pci_acl
;
798 /* Register label with DS. */
799 r
= ds_publish_label(rpub
->label
, rpub
->endpoint
, DSF_OVERWRITE
);
801 return kill_service(rp
, "ds_publish_label call failed", r
);
804 /* If the service is a driver, map it. */
805 if (rpub
->dev_nr
> 0) {
806 /* The purpose of non-blocking forks is to avoid involving VFS in the
807 * forking process, because VFS may be blocked on a ipc_sendrec() to a MFS
808 * that is waiting for a endpoint update for a dead driver. We have just
809 * published that update, but VFS may still be blocked. As a result, VFS
810 * may not yet have received PM's fork message. Hence, if we call
811 * mapdriver() immediately, VFS may not know about the process and thus
812 * refuse to add the driver entry. The following temporary hack works
813 * around this by forcing blocking communication from PM to VFS. Once VFS
814 * has been made non-blocking towards MFS instances, this hack and the
815 * big part of srv_fork() can go.
819 if ((r
= mapdriver(rpub
->label
, rpub
->dev_nr
)) != OK
) {
820 return kill_service(rp
, "couldn't map driver", r
);
825 /* If PCI properties are set, inform the PCI driver about the new service. */
826 if(rpub
->pci_acl
.rsp_nr_device
|| rpub
->pci_acl
.rsp_nr_class
) {
827 pci_acl
= rpub
->pci_acl
;
828 strcpy(pci_acl
.rsp_label
, rpub
->label
);
829 pci_acl
.rsp_endpoint
= rpub
->endpoint
;
831 r
= pci_set_acl(&pci_acl
);
833 return kill_service(rp
, "pci_set_acl call failed", r
);
838 if (rpub
->devman_id
!= 0) {
839 r
= ds_retrieve_label_endpt("devman",&ep
);
842 return kill_service(rp
, "devman not running?", r
);
844 m
.m_type
= DEVMAN_BIND
;
845 m
.DEVMAN_ENDPOINT
= rpub
->endpoint
;
846 m
.DEVMAN_DEVICE_ID
= rpub
->devman_id
;
847 r
= ipc_sendrec(ep
, &m
);
848 if (r
!= OK
|| m
.DEVMAN_RESULT
!= OK
) {
849 return kill_service(rp
, "devman bind device failed", r
);
854 printf("RS: %s published\n", srv_to_string(rp
));
859 /*===========================================================================*
860 * unpublish_service *
861 *===========================================================================*/
862 int unpublish_service(rp
)
863 struct rproc
*rp
; /* pointer to service slot */
865 /* Unpublish a service. */
866 struct rprocpub
*rpub
;
875 /* Unregister label with DS. */
876 r
= ds_delete_label(rpub
->label
);
877 if (r
!= OK
&& !shutting_down
) {
878 printf("RS: ds_delete_label call failed (error %d)\n", r
);
882 /* No need to inform VFS and VM, cleanup is done on exit automatically. */
885 /* If PCI properties are set, inform the PCI driver. */
886 if(rpub
->pci_acl
.rsp_nr_device
|| rpub
->pci_acl
.rsp_nr_class
) {
887 r
= pci_del_acl(rpub
->endpoint
);
888 if (r
!= OK
&& !shutting_down
) {
889 printf("RS: pci_del_acl call failed (error %d)\n", r
);
895 if (rpub
->devman_id
!= 0) {
896 r
= ds_retrieve_label_endpt("devman",&ep
);
899 printf("RS: devman not running?");
901 m
.m_type
= DEVMAN_UNBIND
;
902 m
.DEVMAN_ENDPOINT
= rpub
->endpoint
;
903 m
.DEVMAN_DEVICE_ID
= rpub
->devman_id
;
904 r
= ipc_sendrec(ep
, &m
);
906 if (r
!= OK
|| m
.DEVMAN_RESULT
!= OK
) {
907 printf("RS: devman unbind device failed");
913 printf("RS: %s unpublished\n", srv_to_string(rp
));
918 /*===========================================================================*
920 *===========================================================================*/
921 int run_service(struct rproc
*rp
, int init_type
, int init_flags
)
923 /* Let a newly created service run. */
924 struct rprocpub
*rpub
;
929 /* Allow the service to run. */
930 if ((s
= sys_privctl(rpub
->endpoint
, SYS_PRIV_ALLOW
, NULL
)) != OK
) {
931 return kill_service(rp
, "unable to allow the service to run",s
);
934 /* Initialize service. */
935 if((s
= init_service(rp
, init_type
, init_flags
)) != OK
) {
936 return kill_service(rp
, "unable to initialize service", s
);
940 printf("RS: %s allowed to run\n", srv_to_string(rp
));
945 /*===========================================================================*
947 *===========================================================================*/
948 int start_service(struct rproc
*rp
, int init_flags
)
950 /* Start a system service. */
952 struct rprocpub
*rpub
;
956 /* Create and make active. */
957 rp
->r_priv
.s_init_flags
|= init_flags
;
958 r
= create_service(rp
);
962 activate_service(rp
, NULL
);
964 /* Publish service properties. */
965 r
= publish_service(rp
);
971 r
= run_service(rp
, SEF_INIT_FRESH
, init_flags
);
977 printf("RS: %s started with major %d\n", srv_to_string(rp
),
983 /*===========================================================================*
985 *===========================================================================*/
986 void stop_service(struct rproc
*rp
,int how
)
988 struct rprocpub
*rpub
;
993 /* Try to stop the system service. First send a SIGTERM signal to ask the
994 * system service to terminate. If the service didn't install a signal
995 * handler, it will be killed. If it did and ignores the signal, we'll
996 * find out because we record the time here and send a SIGKILL.
999 printf("RS: %s signaled with SIGTERM\n", srv_to_string(rp
));
1001 signo
= rpub
->endpoint
!= RS_PROC_NR
? SIGTERM
: SIGHUP
; /* SIGHUP for RS. */
1003 rp
->r_flags
|= how
; /* what to on exit? */
1004 sys_kill(rpub
->endpoint
, signo
); /* first try friendly */
1005 rp
->r_stop_tm
= getticks(); /* record current time */
1008 /*===========================================================================*
1009 * activate_service *
1010 *===========================================================================*/
1011 void activate_service(struct rproc
*rp
, struct rproc
*ex_rp
)
1013 /* Activate a service instance and deactivate another one if requested. */
1015 if(ex_rp
&& (ex_rp
->r_flags
& RS_ACTIVE
) ) {
1016 ex_rp
->r_flags
&= ~RS_ACTIVE
;
1018 printf("RS: %s becomes inactive\n", srv_to_string(ex_rp
));
1021 if(! (rp
->r_flags
& RS_ACTIVE
) ) {
1022 rp
->r_flags
|= RS_ACTIVE
;
1024 printf("RS: %s becomes active\n", srv_to_string(rp
));
1028 /*===========================================================================*
1029 * reincarnate_service *
1030 *===========================================================================*/
1031 void reincarnate_service(struct rproc
*old_rp
)
1033 /* Restart a service as if it were never started before. */
1037 if ((r
= clone_slot(old_rp
, &rp
)) != OK
) {
1038 printf("RS: Failed to clone the slot: %d\n", r
);
1042 rp
->r_flags
= RS_IN_USE
;
1043 rproc_ptr
[_ENDPOINT_P(rp
->r_pub
->endpoint
)] = NULL
;
1045 restarts
= rp
->r_restarts
;
1046 start_service(rp
, SEF_INIT_FRESH
);
1047 rp
->r_restarts
= restarts
+ 1;
1050 /*===========================================================================*
1051 * terminate_service *
1052 *===========================================================================*/
1053 void terminate_service(struct rproc
*rp
)
1055 /* Handle a termination event for a system service. */
1057 struct rprocpub
*rpub
;
1058 int nr_rps
, norestart
;
1064 printf("RS: %s terminated\n", srv_to_string(rp
));
1066 /* Deal with failures during initialization. */
1067 if(rp
->r_flags
& RS_INITIALIZING
) {
1068 /* If updating, rollback. */
1069 if(SRV_IS_UPDATING(rp
)) {
1070 printf("RS: update failed: state transfer failed. Rolling back...\n");
1071 end_update(rp
->r_init_err
, RS_REPLY
);
1072 rp
->r_init_err
= ERESTART
;
1076 if (rpub
->sys_flags
& SF_NO_BIN_EXP
) {
1077 /* If service was deliberately started with binary exponential offset
1078 * disabled, we're going to assume we want to refresh a service upon
1082 printf("RS: service '%s' exited during initialization; "
1083 "refreshing\n", rpub
->label
);
1084 rp
->r_flags
|= RS_REFRESHING
; /* restart initialization. */
1087 printf("RS: service '%s' exited during initialization; "
1088 "exiting\n", rpub
->label
);
1089 rp
->r_flags
|= RS_EXITING
; /* don't restart. */
1093 /* If an update process is in progress, end it before doing anything else.
1094 * This is to be on the safe side, since there may be some weird dependencies
1095 * with services under update, while we perform recovery actions.
1097 if(RUPDATE_IS_UPDATING()) {
1098 printf("RS: aborting the update after a crash...\n");
1099 abort_update_proc(ERESTART
);
1102 /* Force exit when no restart is requested. */
1103 norestart
= !(rp
->r_flags
& RS_EXITING
) && (rp
->r_pub
->sys_flags
& SF_NORESTART
);
1105 rp
->r_flags
|= RS_EXITING
;
1106 if((rp
->r_pub
->sys_flags
& SF_DET_RESTART
)
1107 && (rp
->r_restarts
< MAX_DET_RESTART
)) {
1108 /* Detach at cleanup time. */
1109 rp
->r_flags
|= RS_CLEANUP_DETACH
;
1111 if(rp
->r_script
[0] != '\0') {
1112 /* Run script at cleanup time. */
1113 rp
->r_flags
|= RS_CLEANUP_SCRIPT
;
1117 if (rp
->r_flags
& RS_EXITING
) {
1118 /* If a core system service is exiting, we are in trouble. */
1119 if ((rp
->r_pub
->sys_flags
& SF_CORE_SRV
) && !shutting_down
) {
1120 printf("core system service died: %s\n", srv_to_string(rp
));
1124 /* If this service was scheduled for the update, abort the update now. */
1125 if(SRV_IS_UPD_SCHEDULED(rp
)) {
1126 printf("RS: aborting the scheduled update, one of the services part of it is exiting...\n");
1127 abort_update_proc(EDEADSRCDST
);
1130 /* See if a late reply has to be sent. */
1131 r
= (rp
->r_caller_request
== RS_DOWN
1132 || (rp
->r_caller_request
== RS_REFRESH
&& norestart
) ? OK
: EDEADEPT
);
1135 /* Unpublish the service. */
1136 unpublish_service(rp
);
1138 /* Cleanup all the instances of the service. */
1139 get_service_instances(rp
, &rps
, &nr_rps
);
1140 for(i
=0;i
<nr_rps
;i
++) {
1141 cleanup_service(rps
[i
]);
1144 /* If the service is reincarnating, its slot has not been cleaned up.
1145 * Check for this flag now, and attempt to start the service again.
1146 * If this fails, start_service() itself will perform cleanup.
1148 if (rp
->r_flags
& RS_REINCARNATE
) {
1149 rp
->r_flags
&= ~RS_REINCARNATE
;
1150 reincarnate_service(rp
);
1153 else if(rp
->r_flags
& RS_REFRESHING
) {
1154 /* Restart service. */
1155 restart_service(rp
);
1158 /* Determine what to do. If this is the first unexpected
1159 * exit, immediately restart this service. Otherwise use
1160 * a binary exponential backoff.
1162 if (rp
->r_restarts
> 0) {
1163 if (!(rpub
->sys_flags
& SF_NO_BIN_EXP
)) {
1164 rp
->r_backoff
= 1 << MIN(rp
->r_restarts
,(BACKOFF_BITS
-2));
1165 rp
->r_backoff
= MIN(rp
->r_backoff
,MAX_BACKOFF
);
1166 if ((rpub
->sys_flags
& SF_USE_COPY
) && rp
->r_backoff
> 1)
1175 /* Restart service. */
1176 restart_service(rp
);
1180 /*===========================================================================*
1182 *===========================================================================*/
1183 static int run_script(struct rproc
*rp
)
1188 char incarnation_str
[20]; /* Enough for a counter? */
1189 char *envp
[1] = { NULL
};
1190 struct rprocpub
*rpub
;
1193 if (rp
->r_flags
& RS_REFRESHING
)
1195 else if (rp
->r_flags
& RS_NOPINGREPLY
)
1196 reason
= "no-heartbeat";
1197 else reason
= "terminated";
1198 snprintf(incarnation_str
, sizeof(incarnation_str
), "%d", rp
->r_restarts
);
1201 printf("RS: %s:\n", srv_to_string(rp
));
1202 printf("RS: calling script '%s'\n", rp
->r_script
);
1203 printf("RS: reason: '%s'\n", reason
);
1204 printf("RS: incarnation: '%s'\n", incarnation_str
);
1213 execle(_PATH_BSHELL
, "sh", rp
->r_script
, rpub
->label
, reason
,
1214 incarnation_str
, (char*) NULL
, envp
);
1215 printf("RS: run_script: execl '%s' failed: %s\n",
1216 rp
->r_script
, strerror(errno
));
1219 /* Set the privilege structure for the child process. */
1220 if ((r
= getprocnr(pid
, &endpoint
)) != 0)
1221 panic("unable to get child endpoint: %d", r
);
1222 if ((r
= sys_privctl(endpoint
, SYS_PRIV_SET_USER
, NULL
))
1224 return kill_service(rp
,"can't set script privileges",r
);
1226 /* Set the script's privileges on other servers. */
1227 vm_set_priv(endpoint
, NULL
, FALSE
);
1228 if ((r
= vm_set_priv(endpoint
, NULL
, FALSE
)) != OK
) {
1229 return kill_service(rp
,"can't set script VM privs",r
);
1231 /* Allow the script to run. */
1232 if ((r
= sys_privctl(endpoint
, SYS_PRIV_ALLOW
, NULL
)) != OK
) {
1233 return kill_service(rp
,"can't let the script run",r
);
1235 /* Pin RS memory again after fork()ing. */
1236 vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0);
1241 /*===========================================================================*
1243 *===========================================================================*/
1244 void restart_service(struct rproc
*rp
)
1246 /* Restart service via a recovery script or directly. */
1247 struct rproc
*replica_rp
;
1250 /* See if a late reply has to be sent. */
1253 /* Run a recovery script if available. */
1254 if (rp
->r_script
[0] != '\0') {
1257 kill_service(rp
, "unable to run script", errno
);
1262 /* Restart directly. We need a replica if not already available. */
1263 if(rp
->r_next_rp
== NULL
) {
1264 /* Create the replica. */
1265 r
= clone_service(rp
, RST_SYS_PROC
, 0);
1267 kill_service(rp
, "unable to clone service", r
);
1271 replica_rp
= rp
->r_next_rp
;
1273 /* Update the service into the replica. */
1274 r
= update_service(&rp
, &replica_rp
, RS_SWAP
, 0);
1276 kill_service(rp
, "unable to update into new replica", r
);
1280 /* Let the new replica run. */
1281 r
= run_service(replica_rp
, SEF_INIT_RESTART
, 0);
1283 kill_service(rp
, "unable to let the replica run", r
);
1287 /* See if the old version needs to be detached. */
1288 if((rp
->r_pub
->sys_flags
& SF_DET_RESTART
)
1289 && (rp
->r_restarts
< MAX_DET_RESTART
)) {
1290 rp
->r_flags
|= RS_CLEANUP_DETACH
;
1294 printf("RS: %s restarted into %s\n",
1295 srv_to_string(rp
), srv_to_string(replica_rp
));
1298 /*===========================================================================*
1299 * inherit_service_defaults *
1300 *===========================================================================*/
1301 void inherit_service_defaults(def_rp
, rp
)
1302 struct rproc
*def_rp
;
1305 struct rprocpub
*def_rpub
;
1306 struct rprocpub
*rpub
;
1308 def_rpub
= def_rp
->r_pub
;
1311 /* Device and PCI settings. These properties cannot change. */
1312 rpub
->dev_nr
= def_rpub
->dev_nr
;
1313 rpub
->pci_acl
= def_rpub
->pci_acl
;
1315 /* Immutable system and privilege flags. */
1316 rpub
->sys_flags
&= ~IMM_SF
;
1317 rpub
->sys_flags
|= (def_rpub
->sys_flags
& IMM_SF
);
1318 rp
->r_priv
.s_flags
&= ~IMM_F
;
1319 rp
->r_priv
.s_flags
|= (def_rp
->r_priv
.s_flags
& IMM_F
);
1321 /* Allowed traps. They cannot change. */
1322 rp
->r_priv
.s_trap_mask
= def_rp
->r_priv
.s_trap_mask
;
1325 /*===========================================================================*
1326 * get_service_instances *
1327 *===========================================================================*/
1328 void get_service_instances(rp
, rps
, length
)
1330 struct rproc
***rps
;
1333 /* Retrieve all the service instances of a given service. */
1334 static struct rproc
*instances
[5];
1338 instances
[nr_instances
++] = rp
;
1339 if(rp
->r_prev_rp
) instances
[nr_instances
++] = rp
->r_prev_rp
;
1340 if(rp
->r_next_rp
) instances
[nr_instances
++] = rp
->r_next_rp
;
1341 if(rp
->r_old_rp
) instances
[nr_instances
++] = rp
->r_old_rp
;
1342 if(rp
->r_new_rp
) instances
[nr_instances
++] = rp
->r_new_rp
;
1345 *length
= nr_instances
;
1348 /*===========================================================================*
1350 *===========================================================================*/
1351 void share_exec(rp_dst
, rp_src
)
1352 struct rproc
*rp_dst
, *rp_src
;
1355 printf("RS: %s shares exec image with %s\n",
1356 srv_to_string(rp_dst
), srv_to_string(rp_src
));
1358 /* Share exec image from rp_src to rp_dst. */
1359 rp_dst
->r_exec_len
= rp_src
->r_exec_len
;
1360 rp_dst
->r_exec
= rp_src
->r_exec
;
1363 /*===========================================================================*
1365 *===========================================================================*/
1373 e_name
= rp
->r_argv
[0];
1375 printf("RS: service '%s' reads exec image from: %s\n", rp
->r_pub
->label
,
1378 r
= stat(e_name
, &sb
);
1382 if (sb
.st_size
< sizeof(Elf_Ehdr
))
1385 fd
= open(e_name
, O_RDONLY
);
1389 rp
->r_exec_len
= sb
.st_size
;
1390 rp
->r_exec
= malloc(rp
->r_exec_len
);
1391 if (rp
->r_exec
== NULL
)
1393 printf("RS: read_exec: unable to allocate %zu bytes\n",
1399 r
= read(fd
, rp
->r_exec
, rp
->r_exec_len
);
1402 if (r
== rp
->r_exec_len
)
1405 printf("RS: read_exec: read failed %d, errno %d\n", r
, e
);
1415 /*===========================================================================*
1417 *===========================================================================*/
1421 /* Free an exec image. */
1422 int slot_nr
, has_shared_exec
;
1423 struct rproc
*other_rp
;
1425 /* Search for some other slot sharing the same exec image. */
1426 has_shared_exec
= FALSE
;
1427 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
1428 other_rp
= &rproc
[slot_nr
]; /* get pointer to slot */
1429 if (other_rp
->r_flags
& RS_IN_USE
&& other_rp
!= rp
1430 && other_rp
->r_exec
== rp
->r_exec
) { /* found! */
1431 has_shared_exec
= TRUE
;
1436 /* If nobody uses our copy of the exec image, we can try to get rid of it. */
1437 if(!has_shared_exec
) {
1439 printf("RS: %s frees exec image\n", srv_to_string(rp
));
1444 printf("RS: %s no longer sharing exec image with %s\n",
1445 srv_to_string(rp
), srv_to_string(other_rp
));
1451 /*===========================================================================*
1453 *===========================================================================*/
1454 int edit_slot(rp
, rs_start
, source
)
1456 struct rs_start
*rs_start
;
1459 /* Edit a given slot to override existing settings. */
1460 struct rprocpub
*rpub
;
1464 int basic_kc
[] = { SYS_BASIC_CALLS
, NULL_C
};
1465 int basic_vmc
[] = { VM_BASIC_CALLS
, NULL_C
};
1469 /* Update IPC target list. */
1470 if (rs_start
->rss_ipclen
==0 || rs_start
->rss_ipclen
+1>sizeof(rp
->r_ipc_list
)){
1471 printf("RS: edit_slot: ipc list empty or long for '%s'\n", rpub
->label
);
1474 s
=sys_datacopy(source
, (vir_bytes
) rs_start
->rss_ipc
,
1475 SELF
, (vir_bytes
) rp
->r_ipc_list
, rs_start
->rss_ipclen
);
1476 if (s
!= OK
) return(s
);
1477 rp
->r_ipc_list
[rs_start
->rss_ipclen
]= '\0';
1480 if(rs_start
->rss_nr_irq
== RSS_IRQ_ALL
) {
1481 rs_start
->rss_nr_irq
= 0;
1484 rp
->r_priv
.s_flags
|= CHECK_IRQ
;
1486 if (rs_start
->rss_nr_irq
> NR_IRQ
) {
1487 printf("RS: edit_slot: too many IRQs requested\n");
1490 rp
->r_nr_irq
= rp
->r_priv
.s_nr_irq
= rs_start
->rss_nr_irq
;
1491 for (i
= 0; i
<rp
->r_priv
.s_nr_irq
; i
++) {
1492 rp
->r_irq_tab
[i
]= rp
->r_priv
.s_irq_tab
[i
]= rs_start
->rss_irq
[i
];
1494 printf("RS: edit_slot: IRQ %d\n", rp
->r_priv
.s_irq_tab
[i
]);
1497 /* Update I/O ranges. */
1498 if(rs_start
->rss_nr_io
== RSS_IO_ALL
) {
1499 rs_start
->rss_nr_io
= 0;
1502 rp
->r_priv
.s_flags
|= CHECK_IO_PORT
;
1504 if (rs_start
->rss_nr_io
> NR_IO_RANGE
) {
1505 printf("RS: edit_slot: too many I/O ranges requested\n");
1508 rp
->r_nr_io_range
= rp
->r_priv
.s_nr_io_range
= rs_start
->rss_nr_io
;
1509 for (i
= 0; i
<rp
->r_priv
.s_nr_io_range
; i
++) {
1510 rp
->r_priv
.s_io_tab
[i
].ior_base
= rs_start
->rss_io
[i
].base
;
1511 rp
->r_priv
.s_io_tab
[i
].ior_limit
=
1512 rs_start
->rss_io
[i
].base
+rs_start
->rss_io
[i
].len
-1;
1513 rp
->r_io_tab
[i
] = rp
->r_priv
.s_io_tab
[i
];
1515 printf("RS: edit_slot: I/O [%x..%x]\n",
1516 rp
->r_priv
.s_io_tab
[i
].ior_base
,
1517 rp
->r_priv
.s_io_tab
[i
].ior_limit
);
1520 /* Update kernel call mask. Inherit basic kernel calls when asked to. */
1521 memcpy(rp
->r_priv
.s_k_call_mask
, rs_start
->rss_system
,
1522 sizeof(rp
->r_priv
.s_k_call_mask
));
1523 if(rs_start
->rss_flags
& RSS_SYS_BASIC_CALLS
) {
1524 fill_call_mask(basic_kc
, NR_SYS_CALLS
,
1525 rp
->r_priv
.s_k_call_mask
, KERNEL_CALL
, FALSE
);
1528 /* Update VM call mask. Inherit basic VM calls. */
1529 memcpy(rpub
->vm_call_mask
, rs_start
->rss_vm
,
1530 sizeof(rpub
->vm_call_mask
));
1531 if(rs_start
->rss_flags
& RSS_VM_BASIC_CALLS
) {
1532 fill_call_mask(basic_vmc
, NR_VM_CALLS
,
1533 rpub
->vm_call_mask
, VM_RQ_BASE
, FALSE
);
1536 /* Update control labels. */
1537 if(rs_start
->rss_nr_control
> 0) {
1539 if (rs_start
->rss_nr_control
> RS_NR_CONTROL
) {
1540 printf("RS: edit_slot: too many control labels\n");
1543 for (i
=0; i
<rs_start
->rss_nr_control
; i
++) {
1544 s
= copy_label(source
, rs_start
->rss_control
[i
].l_addr
,
1545 rs_start
->rss_control
[i
].l_len
, rp
->r_control
[i
],
1546 sizeof(rp
->r_control
[i
]));
1550 rp
->r_nr_control
= rs_start
->rss_nr_control
;
1553 printf("RS: edit_slot: control labels:");
1554 for (i
=0; i
<rp
->r_nr_control
; i
++)
1555 printf(" %s", rp
->r_control
[i
]);
1560 /* Update signal manager. */
1561 rp
->r_priv
.s_sig_mgr
= rs_start
->rss_sigmgr
;
1563 /* Update scheduling properties if possible. */
1564 if(rp
->r_scheduler
!= NONE
) {
1565 rp
->r_scheduler
= rs_start
->rss_scheduler
;
1566 rp
->r_priority
= rs_start
->rss_priority
;
1567 rp
->r_quantum
= rs_start
->rss_quantum
;
1568 rp
->r_cpu
= rs_start
->rss_cpu
;
1571 /* Update command and arguments. */
1572 if (rs_start
->rss_cmdlen
> MAX_COMMAND_LEN
-1) return(E2BIG
);
1573 s
=sys_datacopy(source
, (vir_bytes
) rs_start
->rss_cmd
,
1574 SELF
, (vir_bytes
) rp
->r_cmd
, rs_start
->rss_cmdlen
);
1575 if (s
!= OK
) return(s
);
1576 rp
->r_cmd
[rs_start
->rss_cmdlen
] = '\0'; /* ensure it is terminated */
1577 if (rp
->r_cmd
[0] != '/') return(EINVAL
); /* insist on absolute path */
1579 /* Build cmd dependencies (argv). */
1582 /* Copy in the program name. */
1583 if (rs_start
->rss_prognamelen
> sizeof(rpub
->proc_name
)-1) return(E2BIG
);
1584 s
=sys_datacopy(source
, (vir_bytes
) rs_start
->rss_progname
,
1585 SELF
, (vir_bytes
) rpub
->proc_name
, rs_start
->rss_prognamelen
);
1586 if (s
!= OK
) return(s
);
1587 rpub
->proc_name
[rs_start
->rss_prognamelen
] = '\0';
1589 /* Update label if not already set. */
1590 if(!strcmp(rpub
->label
, "")) {
1591 if(rs_start
->rss_label
.l_len
> 0) {
1592 /* RS_UP caller has supplied a custom label for this service. */
1593 int s
= copy_label(source
, rs_start
->rss_label
.l_addr
,
1594 rs_start
->rss_label
.l_len
, rpub
->label
, sizeof(rpub
->label
));
1598 printf("RS: edit_slot: using label (custom) '%s'\n", rpub
->label
);
1600 /* Default label for the service. */
1601 label
= rpub
->proc_name
;
1603 memcpy(rpub
->label
, label
, len
);
1604 rpub
->label
[len
]= '\0';
1606 printf("RS: edit_slot: using label (from proc_name) '%s'\n",
1611 /* Update recovery script. */
1612 if (rs_start
->rss_scriptlen
> MAX_SCRIPT_LEN
-1) return(E2BIG
);
1613 if (rs_start
->rss_script
!= NULL
&& rs_start
->rss_scriptlen
> 0
1614 && !(rpub
->sys_flags
& SF_CORE_SRV
)) {
1615 s
=sys_datacopy(source
, (vir_bytes
) rs_start
->rss_script
,
1616 SELF
, (vir_bytes
) rp
->r_script
, rs_start
->rss_scriptlen
);
1617 if (s
!= OK
) return(s
);
1618 rp
->r_script
[rs_start
->rss_scriptlen
] = '\0';
1619 rpub
->sys_flags
|= SF_USE_SCRIPT
;
1622 /* Update system flags and in-memory copy. */
1623 if ((rs_start
->rss_flags
& RSS_COPY
) && !(rpub
->sys_flags
& SF_USE_COPY
)) {
1626 struct rprocpub
*rpub2
;
1629 if(rs_start
->rss_flags
& RSS_REUSE
) {
1632 for(i
= 0; i
< NR_SYS_PROCS
; i
++) {
1634 rpub2
= rproc
[i
].r_pub
;
1635 if(strcmp(rpub
->proc_name
, rpub2
->proc_name
) == 0 &&
1636 (rpub2
->sys_flags
& SF_USE_COPY
)) {
1637 /* We have found the same binary that's
1638 * already been copied */
1649 share_exec(rp
, rp2
);
1654 rpub
->sys_flags
|= SF_USE_COPY
;
1656 if (rs_start
->rss_flags
& RSS_REPLICA
) {
1657 rpub
->sys_flags
|= SF_USE_REPL
;
1659 if (rs_start
->rss_flags
& RSS_NO_BIN_EXP
) {
1660 rpub
->sys_flags
|= SF_NO_BIN_EXP
;
1662 if (rs_start
->rss_flags
& RSS_DETACH
) {
1663 rpub
->sys_flags
|= SF_DET_RESTART
;
1666 rpub
->sys_flags
&= ~SF_DET_RESTART
;
1668 if (rs_start
->rss_flags
& RSS_NORESTART
) {
1669 if(rpub
->sys_flags
& SF_CORE_SRV
) {
1672 rpub
->sys_flags
|= SF_NORESTART
;
1675 rpub
->sys_flags
&= ~SF_NORESTART
;
1678 /* Update period. */
1679 if(rpub
->endpoint
!= RS_PROC_NR
) {
1680 rp
->r_period
= rs_start
->rss_period
;
1683 /* Update restarts. */
1684 if(rs_start
->rss_restarts
) {
1685 rp
->r_restarts
= rs_start
->rss_restarts
;
1688 /* Update number of ASR live updates. */
1689 if(rs_start
->rss_asr_count
>= 0) {
1690 rp
->r_asr_count
= rs_start
->rss_asr_count
;
1693 /* (Re)initialize privilege settings. */
1694 init_privs(rp
, &rp
->r_priv
);
1699 /*===========================================================================*
1701 *===========================================================================*/
1702 int init_slot(rp
, rs_start
, source
)
1704 struct rs_start
*rs_start
;
1707 /* Initialize a slot as requested by the client. */
1708 struct rprocpub
*rpub
;
1713 /* All dynamically created services get the same sys and privilege flags, and
1714 * allowed traps. Other privilege settings can be specified at runtime. The
1715 * privilege id is dynamically allocated by the kernel.
1717 rpub
->sys_flags
= DSRV_SF
; /* system flags */
1718 rp
->r_priv
.s_flags
= DSRV_F
; /* privilege flags */
1719 rp
->r_priv
.s_init_flags
= DSRV_I
; /* init flags */
1720 rp
->r_priv
.s_trap_mask
= DSRV_T
; /* allowed traps */
1721 rp
->r_priv
.s_bak_sig_mgr
= NONE
; /* backup signal manager */
1723 /* Initialize uid. */
1724 rp
->r_uid
= rs_start
->rss_uid
;
1726 /* Initialize device driver settings. */
1727 rpub
->dev_nr
= rs_start
->rss_major
;
1728 rpub
->devman_id
= rs_start
->devman_id
;
1730 /* Initialize pci settings. */
1731 if (rs_start
->rss_nr_pci_id
> RS_NR_PCI_DEVICE
) {
1732 printf("RS: init_slot: too many PCI device IDs\n");
1735 rpub
->pci_acl
.rsp_nr_device
= rs_start
->rss_nr_pci_id
;
1736 for (i
= 0; i
<rpub
->pci_acl
.rsp_nr_device
; i
++) {
1737 rpub
->pci_acl
.rsp_device
[i
].vid
= rs_start
->rss_pci_id
[i
].vid
;
1738 rpub
->pci_acl
.rsp_device
[i
].did
= rs_start
->rss_pci_id
[i
].did
;
1739 rpub
->pci_acl
.rsp_device
[i
].sub_vid
= rs_start
->rss_pci_id
[i
].sub_vid
;
1740 rpub
->pci_acl
.rsp_device
[i
].sub_did
= rs_start
->rss_pci_id
[i
].sub_did
;
1742 printf("RS: init_slot: PCI %04x/%04x (sub %04x:%04x)\n",
1743 rpub
->pci_acl
.rsp_device
[i
].vid
,
1744 rpub
->pci_acl
.rsp_device
[i
].did
,
1745 rpub
->pci_acl
.rsp_device
[i
].sub_vid
,
1746 rpub
->pci_acl
.rsp_device
[i
].sub_did
);
1748 if (rs_start
->rss_nr_pci_class
> RS_NR_PCI_CLASS
) {
1749 printf("RS: init_slot: too many PCI class IDs\n");
1752 rpub
->pci_acl
.rsp_nr_class
= rs_start
->rss_nr_pci_class
;
1753 for (i
= 0; i
<rpub
->pci_acl
.rsp_nr_class
; i
++) {
1754 rpub
->pci_acl
.rsp_class
[i
].pciclass
=rs_start
->rss_pci_class
[i
].pciclass
;
1755 rpub
->pci_acl
.rsp_class
[i
].mask
= rs_start
->rss_pci_class
[i
].mask
;
1757 printf("RS: init_slot: PCI class %06x mask %06x\n",
1758 (unsigned int) rpub
->pci_acl
.rsp_class
[i
].pciclass
,
1759 (unsigned int) rpub
->pci_acl
.rsp_class
[i
].mask
);
1762 /* Initialize some fields. */
1763 rp
->r_asr_count
= 0; /* no ASR updates yet */
1764 rp
->r_restarts
= 0; /* no restarts yet */
1765 rp
->r_old_rp
= NULL
; /* no old version yet */
1766 rp
->r_new_rp
= NULL
; /* no new version yet */
1767 rp
->r_prev_rp
= NULL
; /* no prev replica yet */
1768 rp
->r_next_rp
= NULL
; /* no next replica yet */
1769 rp
->r_exec
= NULL
; /* no in-memory copy yet */
1771 rp
->r_script
[0]= '\0'; /* no recovery script yet */
1772 rpub
->label
[0]= '\0'; /* no label yet */
1773 rp
->r_scheduler
= -1; /* no scheduler yet */
1774 rp
->r_priv
.s_sig_mgr
= -1; /* no signal manager yet */
1775 rp
->r_map_prealloc_addr
= 0; /* no preallocated memory */
1776 rp
->r_map_prealloc_len
= 0;
1777 rp
->r_init_err
= ERESTART
; /* default init error `*/
1779 /* Initialize editable slot settings. */
1780 return edit_slot(rp
, rs_start
, source
);
1783 /*===========================================================================*
1785 *===========================================================================*/
1786 int clone_slot(rp
, clone_rpp
)
1788 struct rproc
**clone_rpp
;
1791 struct rproc
*clone_rp
;
1792 struct rprocpub
*rpub
, *clone_rpub
;
1794 /* Allocate a system service slot for the clone. */
1795 r
= alloc_slot(&clone_rp
);
1797 printf("RS: clone_slot: unable to allocate a new slot: %d\n", r
);
1802 clone_rpub
= clone_rp
->r_pub
;
1804 /* Synch the privilege structure of the source with the kernel. */
1805 if ((r
= sys_getpriv(&(rp
->r_priv
), rpub
->endpoint
)) != OK
) {
1806 panic("unable to synch privilege structure: %d", r
);
1811 *clone_rpub
= *rpub
;
1814 clone_rp
->r_init_err
= ERESTART
; /* default init error */
1815 clone_rp
->r_flags
&= ~RS_ACTIVE
; /* the clone is not active yet */
1816 clone_rp
->r_pid
= -1; /* no pid yet */
1817 clone_rpub
->endpoint
= -1; /* no endpoint yet */
1818 clone_rp
->r_pub
= clone_rpub
; /* restore pointer to public entry */
1819 build_cmd_dep(clone_rp
); /* rebuild cmd dependencies */
1820 if(clone_rpub
->sys_flags
& SF_USE_COPY
) {
1821 share_exec(clone_rp
, rp
); /* share exec image */
1823 clone_rp
->r_old_rp
= NULL
; /* no old version yet */
1824 clone_rp
->r_new_rp
= NULL
; /* no new version yet */
1825 clone_rp
->r_prev_rp
= NULL
; /* no prev replica yet */
1826 clone_rp
->r_next_rp
= NULL
; /* no next replica yet */
1828 /* Force dynamic privilege id. */
1829 clone_rp
->r_priv
.s_flags
|= DYN_PRIV_ID
;
1831 /* Clear instance flags. */
1832 clone_rp
->r_priv
.s_flags
&= ~(LU_SYS_PROC
| RST_SYS_PROC
);
1833 clone_rp
->r_priv
.s_init_flags
= 0;
1835 *clone_rpp
= clone_rp
;
1839 /*===========================================================================*
1840 * swap_slot_pointer *
1841 *===========================================================================*/
1842 static void swap_slot_pointer(struct rproc
**rpp
, struct rproc
*src_rp
,
1843 struct rproc
*dst_rp
)
1845 if(*rpp
== src_rp
) {
1848 else if(*rpp
== dst_rp
) {
1853 /*===========================================================================*
1855 *===========================================================================*/
1856 void swap_slot(src_rpp
, dst_rpp
)
1857 struct rproc
**src_rpp
;
1858 struct rproc
**dst_rpp
;
1860 /* Swap two service slots. */
1861 struct rproc
*src_rp
, *dst_rp
;
1862 struct rprocpub
*src_rpub
, *dst_rpub
;
1863 struct rproc orig_src_rproc
, orig_dst_rproc
;
1864 struct rprocpub orig_src_rprocpub
, orig_dst_rprocpub
;
1865 struct rprocupd
*prev_rpupd
, *rpupd
;
1869 src_rpub
= src_rp
->r_pub
;
1870 dst_rpub
= dst_rp
->r_pub
;
1872 /* Save existing data first. */
1873 orig_src_rproc
= *src_rp
;
1874 orig_src_rprocpub
= *src_rpub
;
1875 orig_dst_rproc
= *dst_rp
;
1876 orig_dst_rprocpub
= *dst_rpub
;
1879 *src_rp
= orig_dst_rproc
;
1880 *src_rpub
= orig_dst_rprocpub
;
1881 *dst_rp
= orig_src_rproc
;
1882 *dst_rpub
= orig_src_rprocpub
;
1884 /* Restore public entries and update descriptors. */
1885 src_rp
->r_pub
= orig_src_rproc
.r_pub
;
1886 dst_rp
->r_pub
= orig_dst_rproc
.r_pub
;
1887 src_rp
->r_upd
= orig_src_rproc
.r_upd
;
1888 dst_rp
->r_upd
= orig_dst_rproc
.r_upd
;
1890 /* Rebuild command dependencies. */
1891 build_cmd_dep(src_rp
);
1892 build_cmd_dep(dst_rp
);
1894 /* Swap local slot pointers. */
1895 swap_slot_pointer(&src_rp
->r_prev_rp
, src_rp
, dst_rp
);
1896 swap_slot_pointer(&src_rp
->r_next_rp
, src_rp
, dst_rp
);
1897 swap_slot_pointer(&src_rp
->r_old_rp
, src_rp
, dst_rp
);
1898 swap_slot_pointer(&src_rp
->r_new_rp
, src_rp
, dst_rp
);
1899 swap_slot_pointer(&dst_rp
->r_prev_rp
, src_rp
, dst_rp
);
1900 swap_slot_pointer(&dst_rp
->r_next_rp
, src_rp
, dst_rp
);
1901 swap_slot_pointer(&dst_rp
->r_old_rp
, src_rp
, dst_rp
);
1902 swap_slot_pointer(&dst_rp
->r_new_rp
, src_rp
, dst_rp
);
1904 /* Swap global slot pointers. */
1905 RUPDATE_ITER(rupdate
.first_rpupd
, prev_rpupd
, rpupd
,
1906 swap_slot_pointer(&rpupd
->rp
, src_rp
, dst_rp
);
1908 swap_slot_pointer(&rproc_ptr
[_ENDPOINT_P(src_rp
->r_pub
->endpoint
)],
1910 swap_slot_pointer(&rproc_ptr
[_ENDPOINT_P(dst_rp
->r_pub
->endpoint
)],
1913 /* Adjust input pointers. */
1918 /*===========================================================================*
1919 * lookup_slot_by_label *
1920 *===========================================================================*/
1921 struct rproc
* lookup_slot_by_label(char *label
)
1923 /* Lookup a service slot matching the given label. */
1926 struct rprocpub
*rpub
;
1928 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
1929 rp
= &rproc
[slot_nr
];
1930 if (!(rp
->r_flags
& RS_ACTIVE
)) {
1934 if (strcmp(rpub
->label
, label
) == 0) {
1942 /*===========================================================================*
1943 * lookup_slot_by_pid *
1944 *===========================================================================*/
1945 struct rproc
* lookup_slot_by_pid(pid_t pid
)
1947 /* Lookup a service slot matching the given pid. */
1955 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
1956 rp
= &rproc
[slot_nr
];
1957 if (!(rp
->r_flags
& RS_IN_USE
)) {
1960 if (rp
->r_pid
== pid
) {
1968 /*===========================================================================*
1969 * lookup_slot_by_dev_nr *
1970 *===========================================================================*/
1971 struct rproc
* lookup_slot_by_dev_nr(dev_t dev_nr
)
1973 /* Lookup a service slot matching the given device number. */
1976 struct rprocpub
*rpub
;
1982 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
1983 rp
= &rproc
[slot_nr
];
1985 if (!(rp
->r_flags
& RS_IN_USE
)) {
1988 if (rpub
->dev_nr
== dev_nr
) {
1996 /*===========================================================================*
1997 * lookup_slot_by_flags *
1998 *===========================================================================*/
1999 struct rproc
* lookup_slot_by_flags(int flags
)
2001 /* Lookup a service slot matching the given flags. */
2009 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
2010 rp
= &rproc
[slot_nr
];
2011 if (!(rp
->r_flags
& RS_IN_USE
)) {
2014 if (rp
->r_flags
& flags
) {
2022 /*===========================================================================*
2024 *===========================================================================*/
2028 /* Alloc a new system service slot. */
2031 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
2032 *rpp
= &rproc
[slot_nr
]; /* get pointer to slot */
2033 if (!((*rpp
)->r_flags
& RS_IN_USE
)) /* check if available */
2036 if (slot_nr
>= NR_SYS_PROCS
) {
2043 /*===========================================================================*
2045 *===========================================================================*/
2049 /* Free a system service slot. */
2050 struct rprocpub
*rpub
;
2054 /* Send a late reply if there is any pending. */
2057 /* Free memory if necessary. */
2058 if(rpub
->sys_flags
& SF_USE_COPY
) {
2062 /* Mark slot as no longer in use.. */
2065 rpub
->in_use
= FALSE
;
2066 rproc_ptr
[_ENDPOINT_P(rpub
->endpoint
)] = NULL
;
2070 /*===========================================================================*
2072 *===========================================================================*/
2073 static char *get_next_name(ptr
, name
, caller_label
)
2078 /* Get the next name from the list of (IPC) program names.
2083 for (p
= ptr
; p
[0] != '\0'; p
= q
)
2085 /* Skip leading space */
2086 while (p
[0] != '\0' && isspace((unsigned char)p
[0]))
2089 /* Find start of next word */
2091 while (q
[0] != '\0' && !isspace((unsigned char)q
[0]))
2096 if (len
> RS_MAX_LABEL_LEN
)
2099 "rs:get_next_name: bad ipc list entry '%.*s' for %s: too long\n",
2100 (int) len
, p
, caller_label
);
2103 memcpy(name
, p
, len
);
2106 return q
; /* found another */
2109 return NULL
; /* done */
2112 /*===========================================================================*
2114 *===========================================================================*/
2115 void add_forward_ipc(rp
, privp
)
2119 /* Add IPC send permissions to a process based on that process's IPC
2122 char name
[RS_MAX_LABEL_LEN
+1], *p
;
2124 endpoint_t endpoint
;
2128 struct rprocpub
*rpub
;
2133 while ((p
= get_next_name(p
, name
, rpub
->label
)) != NULL
) {
2135 if (strcmp(name
, "SYSTEM") == 0)
2137 else if (strcmp(name
, "USER") == 0)
2138 endpoint
= INIT_PROC_NR
; /* all user procs */
2141 /* Set a privilege bit for every process matching the
2142 * given process name. It is perfectly fine if this
2143 * loop does not find any matches, as the target
2144 * process(es) may not have been started yet. See
2145 * add_backward_ipc() below.
2147 for (rrp
=BEG_RPROC_ADDR
; rrp
<END_RPROC_ADDR
; rrp
++) {
2148 if (!(rrp
->r_flags
& RS_IN_USE
))
2151 if (!strcmp(rrp
->r_pub
->proc_name
, name
)) {
2153 printf(" RS: add_forward_ipc: setting"
2154 " sendto bit for %d...\n",
2155 rrp
->r_pub
->endpoint
);
2158 priv_id
= rrp
->r_priv
.s_id
;
2159 set_sys_bit(privp
->s_ipc_to
, priv_id
);
2166 /* This code only applies to the exception cases. */
2167 if ((r
= sys_getpriv(&priv
, endpoint
)) < 0)
2170 "add_forward_ipc: unable to get priv_id for '%s': %d\n",
2176 printf(" RS: add_forward_ipc: setting sendto bit for %d...\n",
2180 set_sys_bit(privp
->s_ipc_to
, priv_id
);
2185 /*===========================================================================*
2186 * add_backward_ipc *
2187 *===========================================================================*/
2188 void add_backward_ipc(rp
, privp
)
2192 /* Add IPC send permissions to a process based on other processes' IPC
2193 * lists. This is enough to allow each such two processes to talk to
2194 * each other, as the kernel guarantees send mask symmetry. We need to
2195 * add these permissions now because the current process may not yet
2196 * have existed at the time that the other process was initialized.
2198 char name
[RS_MAX_LABEL_LEN
+1], *p
;
2200 struct rprocpub
*rrpub
;
2202 int priv_id
, is_ipc_all
, is_ipc_all_sys
;
2204 proc_name
= rp
->r_pub
->proc_name
;
2206 for (rrp
=BEG_RPROC_ADDR
; rrp
<END_RPROC_ADDR
; rrp
++) {
2207 if (!(rrp
->r_flags
& RS_IN_USE
))
2210 if (!rrp
->r_ipc_list
[0])
2213 /* If the process being checked is set to allow IPC to all
2214 * other processes, or for all other system processes and the
2215 * target process is a system process, add a permission bit.
2219 is_ipc_all
= !strcmp(rrp
->r_ipc_list
, RSS_IPC_ALL
);
2220 is_ipc_all_sys
= !strcmp(rrp
->r_ipc_list
, RSS_IPC_ALL_SYS
);
2223 (is_ipc_all_sys
&& (privp
->s_flags
& SYS_PROC
))) {
2225 printf(" RS: add_backward_ipc: setting sendto bit "
2226 "for %d...\n", rrpub
->endpoint
);
2228 priv_id
= rrp
->r_priv
.s_id
;
2229 set_sys_bit(privp
->s_ipc_to
, priv_id
);
2234 /* An IPC target list was provided for the process being
2235 * checked here. Make sure that the name of the new process
2236 * is in that process's list. There may be multiple matches.
2238 p
= rrp
->r_ipc_list
;
2240 while ((p
= get_next_name(p
, name
, rrpub
->label
)) != NULL
) {
2241 if (!strcmp(proc_name
, name
)) {
2243 printf(" RS: add_backward_ipc: setting sendto"
2247 priv_id
= rrp
->r_priv
.s_id
;
2248 set_sys_bit(privp
->s_ipc_to
, priv_id
);
2255 /*===========================================================================*
2257 *===========================================================================*/
2258 void init_privs(rp
, privp
)
2263 int is_ipc_all
, is_ipc_all_sys
;
2265 /* Clear s_ipc_to */
2266 fill_send_mask(&privp
->s_ipc_to
, FALSE
);
2268 is_ipc_all
= !strcmp(rp
->r_ipc_list
, RSS_IPC_ALL
);
2269 is_ipc_all_sys
= !strcmp(rp
->r_ipc_list
, RSS_IPC_ALL_SYS
);
2272 printf(" RS: init_privs: ipc list is '%s'...\n", rp
->r_ipc_list
);
2275 if (!is_ipc_all
&& !is_ipc_all_sys
)
2277 add_forward_ipc(rp
, privp
);
2278 add_backward_ipc(rp
, privp
);
2283 for (i
= 0; i
<NR_SYS_PROCS
; i
++)
2285 if (is_ipc_all
|| i
!= USER_PRIV_ID
)
2286 set_sys_bit(privp
->s_ipc_to
, i
);