1 /* Reincarnation Server. This servers starts new system services and detects
2 * they are exiting. In case of errors, system services can be restarted.
3 * The RS server periodically checks the status of all registered services
4 * services to see whether they are still alive. The system services are
5 * expected to periodically send a heartbeat message.
8 * Nov 22, 2009: rewrite of boot process (Cristiano Giuffrida)
9 * Jul 22, 2005: Created (Jorrit N. Herder)
13 #include "kernel/const.h"
14 #include "kernel/type.h"
15 #include "kernel/proc.h"
17 /* Declare some local functions. */
18 static void boot_image_info_lookup( endpoint_t endpoint
, struct
19 boot_image
*image
, struct boot_image
**ip
, struct boot_image_priv
**pp
,
20 struct boot_image_sys
**sp
, struct boot_image_dev
**dp
);
21 static void catch_boot_init_ready(endpoint_t endpoint
);
22 static void get_work(message
*m_ptr
, int *status_ptr
);
24 /* SEF functions and variables. */
25 static void sef_local_startup(void);
26 static int sef_cb_init_fresh(int type
, sef_init_info_t
*info
);
27 static int sef_cb_init_restart(int type
, sef_init_info_t
*info
);
28 static int sef_cb_init_lu(int type
, sef_init_info_t
*info
);
29 static int sef_cb_init_response(message
*m_ptr
);
30 static int sef_cb_lu_response(message
*m_ptr
);
31 static void sef_cb_signal_handler(int signo
);
32 static int sef_cb_signal_manager(endpoint_t target
, int signo
);
35 /*===========================================================================*
37 *===========================================================================*/
40 /* This is the main routine of this service. The main loop consists of
41 * three major activities: getting new work, processing the work, and
42 * sending the reply. The loop never terminates, unless a panic occurs.
44 message m
; /* request message */
45 int ipc_status
; /* status code */
46 int call_nr
, who_e
,who_p
; /* call number and caller */
47 int result
; /* result to return */
50 /* SEF local startup. */
53 if (OK
!= (s
=sys_getmachine(&machine
)))
54 panic("couldn't get machine info: %d", s
);
56 /* Main loop - get work and do it, forever. */
58 /* Perform sensitive background operations when RS is idle. */
61 /* Wait for request message. */
62 get_work(&m
, &ipc_status
);
64 if(rs_isokendpt(who_e
, &who_p
) != OK
) {
65 panic("message from bogus source: %d", who_e
);
70 /* Now determine what to do. Four types of requests are expected:
71 * - Heartbeat messages (notifications from registered system services)
72 * - System notifications (synchronous alarm)
73 * - User requests (control messages to manage system services)
74 * - Ready messages (reply messages from registered services)
77 /* Notification messages are control messages and do not need a reply.
78 * These include heartbeat messages and system notifications.
80 if (is_ipc_notify(ipc_status
)) {
83 do_period(&m
); /* check services status */
85 default: /* heartbeat notification */
86 if (rproc_ptr
[who_p
] != NULL
) { /* mark heartbeat time */
87 rproc_ptr
[who_p
]->r_alive_tm
= m
.m_notify
.timestamp
;
89 printf("RS: warning: got unexpected notify message from %d\n",
95 /* If we get this far, this is a normal request.
96 * Handle the request and send a reply to the caller.
99 /* Handler functions are responsible for permission checking. */
102 case RS_UP
: result
= do_up(&m
); break;
103 case RS_DOWN
: result
= do_down(&m
); break;
104 case RS_REFRESH
: result
= do_refresh(&m
); break;
105 case RS_RESTART
: result
= do_restart(&m
); break;
106 case RS_SHUTDOWN
: result
= do_shutdown(&m
); break;
107 case RS_UPDATE
: result
= do_update(&m
); break;
108 case RS_CLONE
: result
= do_clone(&m
); break;
109 case RS_UNCLONE
: result
= do_unclone(&m
); break;
110 case RS_EDIT
: result
= do_edit(&m
); break;
111 case RS_SYSCTL
: result
= do_sysctl(&m
); break;
112 case RS_FI
: result
= do_fi(&m
); break;
113 case RS_GETSYSINFO
: result
= do_getsysinfo(&m
); break;
114 case RS_LOOKUP
: result
= do_lookup(&m
); break;
115 /* Ready messages. */
116 case RS_INIT
: result
= do_init_ready(&m
); break;
117 case RS_LU_PREPARE
: result
= do_upd_ready(&m
); break;
119 printf("RS: warning: got unexpected request %d from %d\n",
120 m
.m_type
, m
.m_source
);
124 /* Finally send reply message, unless disabled. */
125 if (result
!= EDONTREPLY
) {
127 reply(who_e
, NULL
, &m
);
133 /*===========================================================================*
134 * sef_local_startup *
135 *===========================================================================*/
136 static void sef_local_startup()
138 /* Register init callbacks. */
139 sef_setcb_init_fresh(sef_cb_init_fresh
);
140 sef_setcb_init_restart(sef_cb_init_restart
);
141 sef_setcb_init_lu(sef_cb_init_lu
);
143 /* Register response callbacks. */
144 sef_setcb_init_response(sef_cb_init_response
);
145 sef_setcb_lu_response(sef_cb_lu_response
);
147 /* Register signal callbacks. */
148 sef_setcb_signal_handler(sef_cb_signal_handler
);
149 sef_setcb_signal_manager(sef_cb_signal_manager
);
151 /* Let SEF perform startup. */
155 /*===========================================================================*
156 * sef_cb_init_fresh *
157 *===========================================================================*/
158 static int sef_cb_init_fresh(int UNUSED(type
), sef_init_info_t
*UNUSED(info
))
160 /* Initialize the reincarnation server. */
161 struct boot_image
*ip
;
163 int nr_image_srvs
, nr_image_priv_srvs
, nr_uncaught_init_srvs
;
165 struct rproc
*replica_rp
;
166 struct rprocpub
*rpub
;
167 struct boot_image image
[NR_BOOT_PROCS
];
168 struct boot_image_priv
*boot_image_priv
;
169 struct boot_image_sys
*boot_image_sys
;
170 struct boot_image_dev
*boot_image_dev
;
171 int pid
, replica_pid
;
172 endpoint_t replica_endpoint
;
175 int all_c
[] = { ALL_C
, NULL_C
};
176 int no_c
[] = { NULL_C
};
178 /* See if we run in verbose mode. */
179 env_parse("rs_verbose", "d", 0, &rs_verbose
, 0, 1);
181 if ((s
= sys_getinfo(GET_HZ
, &system_hz
, sizeof(system_hz
), 0, 0)) != OK
)
182 panic("Cannot get system timer frequency\n");
184 /* Initialize the global init descriptor. */
185 rinit
.rproctab_gid
= cpf_grant_direct(ANY
, (vir_bytes
) rprocpub
,
186 sizeof(rprocpub
), CPF_READ
);
187 if(!GRANT_VALID(rinit
.rproctab_gid
)) {
188 panic("unable to create rprocpub table grant: %d", rinit
.rproctab_gid
);
191 /* Initialize some global variables. */
193 shutting_down
= FALSE
;
195 /* Get a copy of the boot image table. */
196 if ((s
= sys_getimage(image
)) != OK
) {
197 panic("unable to get copy of boot image table: %d", s
);
200 /* Determine the number of system services in the boot image table. */
202 for(i
=0;i
<NR_BOOT_PROCS
;i
++) {
205 /* System services only. */
206 if(iskerneln(_ENDPOINT_P(ip
->endpoint
))) {
212 /* Determine the number of entries in the boot image priv table and make sure
213 * it matches the number of system services in the boot image table.
215 nr_image_priv_srvs
= 0;
216 for (i
=0; boot_image_priv_table
[i
].endpoint
!= NULL_BOOT_NR
; i
++) {
217 boot_image_priv
= &boot_image_priv_table
[i
];
219 /* System services only. */
220 if(iskerneln(_ENDPOINT_P(boot_image_priv
->endpoint
))) {
223 nr_image_priv_srvs
++;
225 if(nr_image_srvs
!= nr_image_priv_srvs
) {
226 panic("boot image table and boot image priv table mismatch");
229 /* Reset the system process table. */
230 for (rp
=BEG_RPROC_ADDR
; rp
<END_RPROC_ADDR
; rp
++) {
232 rp
->r_init_err
= ERESTART
;
233 rp
->r_pub
= &rprocpub
[rp
- rproc
];
234 rp
->r_pub
->in_use
= FALSE
;
235 rp
->r_pub
->old_endpoint
= NONE
;
236 rp
->r_pub
->new_endpoint
= NONE
;
239 /* Initialize the system process table in 4 steps, each of them following
240 * the appearance of system services in the boot image priv table.
241 * - Step 1: set priviliges, sys properties, and dev properties (if any)
242 * for every system service.
244 for (i
=0; boot_image_priv_table
[i
].endpoint
!= NULL_BOOT_NR
; i
++) {
245 boot_image_priv
= &boot_image_priv_table
[i
];
247 /* System services only. */
248 if(iskerneln(_ENDPOINT_P(boot_image_priv
->endpoint
))) {
252 /* Lookup the corresponding entries in other tables. */
253 boot_image_info_lookup(boot_image_priv
->endpoint
, image
,
254 &ip
, NULL
, &boot_image_sys
, &boot_image_dev
);
255 rp
= &rproc
[boot_image_priv
- boot_image_priv_table
];
262 strcpy(rpub
->label
, boot_image_priv
->label
);
264 /* Force a static priv id for system services in the boot image. */
265 rp
->r_priv
.s_id
= static_priv_id(
266 _ENDPOINT_P(boot_image_priv
->endpoint
));
268 /* Initialize privilege bitmaps and signal manager. */
269 rp
->r_priv
.s_flags
= boot_image_priv
->flags
; /* priv flags */
270 rp
->r_priv
.s_init_flags
= SRV_OR_USR(rp
, SRV_I
, USR_I
); /* init flags */
271 rp
->r_priv
.s_trap_mask
= SRV_OR_USR(rp
, SRV_T
, USR_T
); /* traps */
272 ipc_to
= SRV_OR_USR(rp
, SRV_M
, USR_M
); /* targets */
273 fill_send_mask(&rp
->r_priv
.s_ipc_to
, ipc_to
== ALL_M
);
274 rp
->r_priv
.s_sig_mgr
= SRV_OR_USR(rp
, SRV_SM
, USR_SM
); /* sig mgr */
275 rp
->r_priv
.s_bak_sig_mgr
= NONE
; /* backup sig mgr */
277 /* Initialize kernel call mask bitmap. */
278 calls
= SRV_OR_USR(rp
, SRV_KC
, USR_KC
) == ALL_C
? all_c
: no_c
;
279 fill_call_mask(calls
, NR_SYS_CALLS
,
280 rp
->r_priv
.s_k_call_mask
, KERNEL_CALL
, TRUE
);
282 /* Set the privilege structure. RS and VM are exceptions and are already
285 if(boot_image_priv
->endpoint
!= RS_PROC_NR
&&
286 boot_image_priv
->endpoint
!= VM_PROC_NR
) {
287 if ((s
= sys_privctl(ip
->endpoint
, SYS_PRIV_SET_SYS
, &(rp
->r_priv
)))
289 panic("unable to set privilege structure: %d", s
);
293 /* Synch the privilege structure with the kernel. */
294 if ((s
= sys_getpriv(&(rp
->r_priv
), ip
->endpoint
)) != OK
) {
295 panic("unable to synch privilege structure: %d", s
);
299 * Set sys properties.
301 rpub
->sys_flags
= boot_image_sys
->flags
; /* sys flags */
304 * Set dev properties.
306 rpub
->dev_nr
= boot_image_dev
->dev_nr
; /* major device number */
308 /* Build command settings. Also set the process name. */
309 strlcpy(rp
->r_cmd
, ip
->proc_name
, sizeof(rp
->r_cmd
));
310 rp
->r_script
[0]= '\0';
313 strlcpy(rpub
->proc_name
, ip
->proc_name
, sizeof(rpub
->proc_name
));
315 /* Initialize vm call mask bitmap. */
316 calls
= SRV_OR_USR(rp
, SRV_VC
, USR_VC
) == ALL_C
? all_c
: no_c
;
317 fill_call_mask(calls
, NR_VM_CALLS
, rpub
->vm_call_mask
, VM_RQ_BASE
, TRUE
);
319 /* Scheduling parameters. */
320 rp
->r_scheduler
= SRV_OR_USR(rp
, SRV_SCH
, USR_SCH
);
321 rp
->r_priority
= SRV_OR_USR(rp
, SRV_Q
, USR_Q
);
322 rp
->r_quantum
= SRV_OR_USR(rp
, SRV_QT
, USR_QT
);
324 /* Get some settings from the boot image table. */
325 rpub
->endpoint
= ip
->endpoint
;
327 /* Set some defaults. */
328 rp
->r_old_rp
= NULL
; /* no old version yet */
329 rp
->r_new_rp
= NULL
; /* no new version yet */
330 rp
->r_prev_rp
= NULL
; /* no prev replica yet */
331 rp
->r_next_rp
= NULL
; /* no next replica yet */
332 rp
->r_uid
= 0; /* root */
333 rp
->r_check_tm
= 0; /* not checked yet */
334 rp
->r_alive_tm
= getticks(); /* currently alive */
335 rp
->r_stop_tm
= 0; /* not exiting yet */
336 rp
->r_asr_count
= 0; /* no ASR updates yet */
337 rp
->r_restarts
= 0; /* no restarts so far */
338 rp
->r_period
= 0; /* no period yet */
339 rp
->r_exec
= NULL
; /* no in-memory copy yet */
342 /* Mark as in use and active. */
343 rp
->r_flags
= RS_IN_USE
| RS_ACTIVE
;
344 rproc_ptr
[_ENDPOINT_P(rpub
->endpoint
)]= rp
;
348 /* - Step 2: allow every system service in the boot image to run. */
349 nr_uncaught_init_srvs
= 0;
350 for (i
=0; boot_image_priv_table
[i
].endpoint
!= NULL_BOOT_NR
; i
++) {
351 boot_image_priv
= &boot_image_priv_table
[i
];
353 /* System services only. */
354 if(iskerneln(_ENDPOINT_P(boot_image_priv
->endpoint
))) {
358 /* Lookup the corresponding slot in the system process table. */
359 rp
= &rproc
[boot_image_priv
- boot_image_priv_table
];
362 /* RS/VM are already running as we speak. */
363 if(boot_image_priv
->endpoint
== RS_PROC_NR
||
364 boot_image_priv
->endpoint
== VM_PROC_NR
) {
365 if ((s
= init_service(rp
, SEF_INIT_FRESH
, rp
->r_priv
.s_init_flags
)) != OK
) {
366 panic("unable to initialize %d: %d", boot_image_priv
->endpoint
, s
);
368 /* VM will still send an RS_INIT message, though. */
369 if (boot_image_priv
->endpoint
!= RS_PROC_NR
) {
370 nr_uncaught_init_srvs
++;
375 /* Allow the service to run. */
376 if ((s
= sched_init_proc(rp
)) != OK
) {
377 panic("unable to initialize scheduling: %d", s
);
379 if ((s
= sys_privctl(rpub
->endpoint
, SYS_PRIV_ALLOW
, NULL
)) != OK
) {
380 panic("unable to initialize privileges: %d", s
);
383 /* Initialize service. We assume every service will always get
384 * back to us here at boot time.
386 if(boot_image_priv
->flags
& SYS_PROC
) {
387 if ((s
= init_service(rp
, SEF_INIT_FRESH
, rp
->r_priv
.s_init_flags
)) != OK
) {
388 panic("unable to initialize service: %d", s
);
390 if(rpub
->sys_flags
& SF_SYNCH_BOOT
) {
391 /* Catch init ready message now to synchronize. */
392 catch_boot_init_ready(rpub
->endpoint
);
395 /* Catch init ready message later. */
396 nr_uncaught_init_srvs
++;
401 /* - Step 3: let every system service complete initialization by
402 * catching all the init ready messages left.
404 while(nr_uncaught_init_srvs
) {
405 catch_boot_init_ready(ANY
);
406 nr_uncaught_init_srvs
--;
409 /* - Step 4: all the system services in the boot image are now running.
410 * Complete the initialization of the system process table in collaboration
411 * with other system services.
413 for (i
=0; boot_image_priv_table
[i
].endpoint
!= NULL_BOOT_NR
; i
++) {
414 boot_image_priv
= &boot_image_priv_table
[i
];
416 /* System services only. */
417 if(iskerneln(_ENDPOINT_P(boot_image_priv
->endpoint
))) {
421 /* Lookup the corresponding slot in the system process table. */
422 rp
= &rproc
[boot_image_priv
- boot_image_priv_table
];
425 /* Get pid from PM. */
426 rp
->r_pid
= getnpid(rpub
->endpoint
);
428 panic("unable to get pid: %d", rp
->r_pid
);
432 /* Set alarm to periodically check service status. */
433 if (OK
!= (s
=sys_setalarm(RS_DELTA_T
, 0)))
434 panic("couldn't set alarm: %d", s
);
437 /* Now create a new RS instance and let the current
438 * instance live update into the replica. Clone RS' own slot first.
440 rp
= rproc_ptr
[_ENDPOINT_P(RS_PROC_NR
)];
441 if((s
= clone_slot(rp
, &replica_rp
)) != OK
) {
442 panic("unable to clone current RS instance: %d", s
);
445 /* Fork a new RS instance with root:wheel. */
446 pid
= srv_fork(0, 0);
448 panic("unable to fork a new RS instance: %d", pid
);
450 replica_pid
= pid
? pid
: getpid();
451 if ((s
= getprocnr(replica_pid
, &replica_endpoint
)) != 0)
452 panic("unable to get replica endpoint: %d", s
);
453 replica_rp
->r_pid
= replica_pid
;
454 replica_rp
->r_pub
->endpoint
= replica_endpoint
;
457 /* New RS instance running. */
459 /* Live update the old instance into the new one. */
460 s
= update_service(&rp
, &replica_rp
, RS_SWAP
, 0);
462 panic("unable to live update RS: %d", s
);
466 /* Clean up the old RS instance, the new instance will take over. */
469 /* Ask VM to pin memory for the new RS instance. */
470 if((s
= vm_memctl(RS_PROC_NR
, VM_RS_MEM_PIN
, 0, 0)) != OK
) {
471 panic("unable to pin memory for the new RS instance: %d", s
);
475 /* Old RS instance running. */
477 /* Set up privileges for the new instance and let it run. */
478 s
= sys_privctl(replica_endpoint
, SYS_PRIV_SET_SYS
, &(replica_rp
->r_priv
));
480 panic("unable to set privileges for the new RS instance: %d", s
);
482 if ((s
= sched_init_proc(replica_rp
)) != OK
) {
483 panic("unable to initialize RS replica scheduling: %d", s
);
485 s
= sys_privctl(replica_endpoint
, SYS_PRIV_YIELD
, NULL
);
487 panic("unable to yield control to the new RS instance: %d", s
);
491 #endif /* USE_LIVEUPDATE */
496 /*===========================================================================*
497 * sef_cb_init_restart *
498 *===========================================================================*/
499 static int sef_cb_init_restart(int type
, sef_init_info_t
*info
)
501 /* Restart the reincarnation server. */
503 struct rproc
*old_rs_rp
, *new_rs_rp
;
505 assert(info
->endpoint
== RS_PROC_NR
);
507 /* Perform default state transfer first. */
508 r
= SEF_CB_INIT_RESTART_STATEFUL(type
, info
);
510 printf("SEF_CB_INIT_RESTART_STATEFUL failed: %d\n", r
);
514 /* New RS takes over. */
515 old_rs_rp
= rproc_ptr
[_ENDPOINT_P(RS_PROC_NR
)];
516 new_rs_rp
= rproc_ptr
[_ENDPOINT_P(info
->old_endpoint
)];
518 printf("RS: %s is the new RS after restart\n", srv_to_string(new_rs_rp
));
520 /* If an update was in progress, end it. */
521 if(SRV_IS_UPDATING(old_rs_rp
)) {
522 end_update(ERESTART
, RS_REPLY
);
525 /* Update the service into the replica. */
526 r
= update_service(&old_rs_rp
, &new_rs_rp
, RS_DONTSWAP
, 0);
528 printf("update_service failed: %d\n", r
);
532 /* Initialize the new RS instance. */
533 r
= init_service(new_rs_rp
, SEF_INIT_RESTART
, 0);
535 printf("init_service failed: %d\n", r
);
539 /* Reschedule a synchronous alarm for the next period. */
540 if (OK
!= (r
=sys_setalarm(RS_DELTA_T
, 0)))
541 panic("couldn't set alarm: %d", r
);
546 /*===========================================================================*
548 *===========================================================================*/
549 static int sef_cb_init_lu(int type
, sef_init_info_t
*info
)
551 /* Start a new version of the reincarnation server. */
553 struct rproc
*old_rs_rp
, *new_rs_rp
;
555 assert(info
->endpoint
== RS_PROC_NR
);
557 /* Perform default state transfer first. */
558 sef_setcb_init_restart(SEF_CB_INIT_RESTART_STATEFUL
);
559 r
= SEF_CB_INIT_LU_DEFAULT(type
, info
);
561 printf("SEF_CB_INIT_LU_DEFAULT failed: %d\n", r
);
565 /* New RS takes over. */
566 old_rs_rp
= rproc_ptr
[_ENDPOINT_P(RS_PROC_NR
)];
567 new_rs_rp
= rproc_ptr
[_ENDPOINT_P(info
->old_endpoint
)];
569 printf("RS: %s is the new RS after live update\n",
570 srv_to_string(new_rs_rp
));
572 /* Update the service into the replica. */
573 r
= update_service(&old_rs_rp
, &new_rs_rp
, RS_DONTSWAP
, 0);
575 printf("update_service failed: %d\n", r
);
579 /* Check if everything is as expected. */
580 assert(RUPDATE_IS_UPDATING());
581 assert(RUPDATE_IS_INITIALIZING());
582 assert(rupdate
.num_rpupds
> 0);
583 assert(rupdate
.num_init_ready_pending
> 0);
588 /*===========================================================================*
589 * sef_cb_init_response *
590 *===========================================================================*/
591 int sef_cb_init_response(message
*m_ptr
)
595 /* Return now if RS initialization failed. */
596 r
= m_ptr
->m_rs_init
.result
;
601 /* Simulate an RS-to-RS init message. */
602 r
= do_init_ready(m_ptr
);
604 /* Assume everything is OK if EDONTREPLY was returned. */
605 if(r
== EDONTREPLY
) {
611 /*===========================================================================*
612 * sef_cb_lu_response *
613 *===========================================================================*/
614 int sef_cb_lu_response(message
*m_ptr
)
618 /* Simulate an RS-to-RS update ready message. */
619 r
= do_upd_ready(m_ptr
);
621 /* If we get this far, we didn't get updated for some reason. Report error. */
622 if(r
== EDONTREPLY
) {
628 /*===========================================================================*
629 * sef_cb_signal_handler *
630 *===========================================================================*/
631 static void sef_cb_signal_handler(int signo
)
633 /* Check for known signals, ignore anything else. */
644 /*===========================================================================*
645 * sef_cb_signal_manager *
646 *===========================================================================*/
647 static int sef_cb_signal_manager(endpoint_t target
, int signo
)
649 /* Process system signal on behalf of the kernel. */
655 if(rs_isokendpt(target
, &target_p
) != OK
|| rproc_ptr
[target_p
] == NULL
) {
657 printf("RS: ignoring spurious signal %d for process %d\n",
659 return OK
; /* clear the signal */
661 rp
= rproc_ptr
[target_p
];
663 /* Don't bother if a termination signal has already been processed. */
664 if((rp
->r_flags
& RS_TERMINATED
) && !(rp
->r_flags
& RS_EXITING
)) {
665 return EDEADEPT
; /* process is gone */
668 /* Ignore external signals for inactive service instances. */
669 if( !(rp
->r_flags
& RS_ACTIVE
) && !(rp
->r_flags
& RS_EXITING
)) {
671 printf("RS: ignoring signal %d for inactive %s\n",
672 signo
, srv_to_string(rp
));
673 return OK
; /* clear the signal */
677 printf("RS: %s got %s signal %d\n", srv_to_string(rp
),
678 SIGS_IS_TERMINATION(signo
) ? "termination" : "non-termination",signo
);
680 /* Print stacktrace if necessary. */
681 if(SIGS_IS_STACKTRACE(signo
)) {
682 sys_diagctl_stacktrace(target
);
685 /* In case of termination signal handle the event. */
686 if(SIGS_IS_TERMINATION(signo
)) {
687 rp
->r_flags
|= RS_TERMINATED
;
688 terminate_service(rp
);
691 return EDEADEPT
; /* process is now gone */
693 /* Never deliver signals to VM. */
694 if (rp
->r_pub
->endpoint
== VM_PROC_NR
) {
698 /* Translate every non-termination signal into a message. */
699 m
.m_type
= SIGS_SIGNAL_RECEIVED
;
700 m
.m_pm_lsys_sigs_signal
.num
= signo
;
701 rs_asynsend(rp
, &m
, 1);
703 return OK
; /* signal has been delivered */
706 /*===========================================================================*
707 * boot_image_info_lookup *
708 *===========================================================================*/
709 static void boot_image_info_lookup(endpoint
, image
, ip
, pp
, sp
, dp
)
711 struct boot_image
*image
;
712 struct boot_image
**ip
;
713 struct boot_image_priv
**pp
;
714 struct boot_image_sys
**sp
;
715 struct boot_image_dev
**dp
;
717 /* Lookup entries in boot image tables. */
720 /* When requested, locate the corresponding entry in the boot image table
721 * or panic if not found.
724 for (i
=0; i
< NR_BOOT_PROCS
; i
++) {
725 if(image
[i
].endpoint
== endpoint
) {
730 if(i
== NR_BOOT_PROCS
) {
731 panic("boot image table lookup failed");
735 /* When requested, locate the corresponding entry in the boot image priv table
736 * or panic if not found.
739 for (i
=0; boot_image_priv_table
[i
].endpoint
!= NULL_BOOT_NR
; i
++) {
740 if(boot_image_priv_table
[i
].endpoint
== endpoint
) {
741 *pp
= &boot_image_priv_table
[i
];
745 if(i
== NULL_BOOT_NR
) {
746 panic("boot image priv table lookup failed");
750 /* When requested, locate the corresponding entry in the boot image sys table
751 * or resort to the default entry if not found.
754 for (i
=0; boot_image_sys_table
[i
].endpoint
!= DEFAULT_BOOT_NR
; i
++) {
755 if(boot_image_sys_table
[i
].endpoint
== endpoint
) {
756 *sp
= &boot_image_sys_table
[i
];
760 if(boot_image_sys_table
[i
].endpoint
== DEFAULT_BOOT_NR
) {
761 *sp
= &boot_image_sys_table
[i
]; /* accept the default entry */
765 /* When requested, locate the corresponding entry in the boot image dev table
766 * or resort to the default entry if not found.
769 for (i
=0; boot_image_dev_table
[i
].endpoint
!= DEFAULT_BOOT_NR
; i
++) {
770 if(boot_image_dev_table
[i
].endpoint
== endpoint
) {
771 *dp
= &boot_image_dev_table
[i
];
775 if(boot_image_dev_table
[i
].endpoint
== DEFAULT_BOOT_NR
) {
776 *dp
= &boot_image_dev_table
[i
]; /* accept the default entry */
781 /*===========================================================================*
782 * catch_boot_init_ready *
783 *===========================================================================*/
784 static void catch_boot_init_ready(endpoint
)
787 /* Block and catch an init ready message from the given source. */
794 /* Receive init ready message. */
795 if ((r
= sef_receive_status(endpoint
, &m
, &ipc_status
)) != OK
) {
796 panic("unable to receive init reply: %d", r
);
798 if(m
.m_type
!= RS_INIT
) {
799 panic("unexpected reply from service: %d", m
.m_source
);
801 result
= m
.m_rs_init
.result
;
802 rp
= rproc_ptr
[_ENDPOINT_P(m
.m_source
)];
806 panic("unable to complete init for service: %d", m
.m_source
);
809 /* Send a reply to unblock the service, except to VM, which sent the reply
810 * asynchronously. Synchronous replies could lead to deadlocks there.
812 if (m
.m_source
!= VM_PROC_NR
) {
814 reply(m
.m_source
, rp
, &m
);
817 /* Mark the slot as no longer initializing. */
818 rp
->r_flags
&= ~RS_INITIALIZING
;
820 rp
->r_alive_tm
= getticks();
823 /*===========================================================================*
825 *===========================================================================*/
826 static void get_work(m_ptr
, status_ptr
)
827 message
*m_ptr
; /* pointer to message */
828 int *status_ptr
; /* pointer to status */
831 if (OK
!= (r
=sef_receive_status(ANY
, m_ptr
, status_ptr
)))
832 panic("sef_receive_status failed: %d", r
);