3 * Jan 22, 2010: Created (Cristiano Giuffrida)
8 #include "kernel/proc.h"
10 static int check_request(struct rs_start
*rs_start
);
12 /*===========================================================================*
14 *===========================================================================*/
16 message
*m_ptr
; /* request message pointer */
18 /* A request was made to start a new system service. */
20 struct rprocpub
*rpub
;
22 struct rs_start rs_start
;
26 /* Check if the call can be allowed. */
27 if((r
= check_call_permission(m_ptr
->m_source
, RS_UP
, NULL
)) != OK
)
30 /* Allocate a new system service slot. */
33 printf("RS: do_up: unable to allocate a new slot: %d\n", r
);
38 /* Copy the request structure. */
39 r
= copy_rs_start(m_ptr
->m_source
, m_ptr
->m_rs_req
.addr
, &rs_start
);
43 r
= check_request(&rs_start
);
49 noblock
= (rs_start
.rss_flags
& RSS_NOBLOCK
);
50 if(rs_start
.rss_flags
& RSS_FORCE_INIT_CRASH
) {
51 init_flags
|= SEF_INIT_CRASH
;
53 if(rs_start
.rss_flags
& RSS_FORCE_INIT_FAIL
) {
54 init_flags
|= SEF_INIT_FAIL
;
56 if(rs_start
.rss_flags
& RSS_FORCE_INIT_TIMEOUT
) {
57 init_flags
|= SEF_INIT_TIMEOUT
;
59 if(rs_start
.rss_flags
& RSS_FORCE_INIT_DEFCB
) {
60 init_flags
|= SEF_INIT_DEFCB
;
63 /* Initialize the slot as requested. */
64 r
= init_slot(rp
, &rs_start
, m_ptr
->m_source
);
66 printf("RS: do_up: unable to init the new slot: %d\n", r
);
70 /* Check for duplicates */
71 if(lookup_slot_by_label(rpub
->label
)) {
72 printf("RS: service with the same label '%s' already exists\n",
76 if(rpub
->dev_nr
>0 && lookup_slot_by_dev_nr(rpub
->dev_nr
)) {
77 printf("RS: service with the same device number %d already exists\n",
81 for (i
= 0; i
< rpub
->nr_domain
; i
++) {
82 if (lookup_slot_by_domain(rpub
->domain
[i
]) != NULL
) {
83 printf("RS: service with the same domain %d already exists\n",
89 /* All information was gathered. Now try to start the system service. */
90 r
= start_service(rp
, init_flags
);
95 /* Unblock the caller immediately if requested. */
100 /* Late reply - send a reply when service completes initialization. */
101 rp
->r_flags
|= RS_LATEREPLY
;
102 rp
->r_caller
= m_ptr
->m_source
;
103 rp
->r_caller_request
= RS_UP
;
108 /*===========================================================================*
110 *===========================================================================*/
111 int do_down(message
*m_ptr
)
113 register struct rproc
*rp
;
115 char label
[RS_MAX_LABEL_LEN
];
118 s
= copy_label(m_ptr
->m_source
, m_ptr
->m_rs_req
.addr
,
119 m_ptr
->m_rs_req
.len
, label
, sizeof(label
));
124 /* Lookup slot by label. */
125 rp
= lookup_slot_by_label(label
);
128 printf("RS: do_down: service '%s' not found\n", label
);
132 /* Check if the call can be allowed. */
133 if((s
= check_call_permission(m_ptr
->m_source
, RS_DOWN
, rp
)) != OK
)
137 if (rp
->r_flags
& RS_TERMINATED
) {
138 /* A recovery script is requesting us to bring down the service.
139 * The service is already gone, simply perform cleanup.
142 printf("RS: recovery script performs service down...\n");
143 unpublish_service(rp
);
147 stop_service(rp
,RS_EXITING
);
149 /* Late reply - send a reply when service dies. */
150 rp
->r_flags
|= RS_LATEREPLY
;
151 rp
->r_caller
= m_ptr
->m_source
;
152 rp
->r_caller_request
= RS_DOWN
;
157 /*===========================================================================*
159 *===========================================================================*/
160 int do_restart(message
*m_ptr
)
164 char label
[RS_MAX_LABEL_LEN
];
165 char script
[MAX_SCRIPT_LEN
];
168 s
= copy_label(m_ptr
->m_source
, m_ptr
->m_rs_req
.addr
,
169 m_ptr
->m_rs_req
.len
, label
, sizeof(label
));
174 /* Lookup slot by label. */
175 rp
= lookup_slot_by_label(label
);
178 printf("RS: do_restart: service '%s' not found\n", label
);
182 /* Check if the call can be allowed. */
183 if((r
= check_call_permission(m_ptr
->m_source
, RS_RESTART
, rp
)) != OK
)
186 /* We can only be asked to restart a service from a recovery script. */
187 if (! (rp
->r_flags
& RS_TERMINATED
) ) {
189 printf("RS: %s is still running\n", srv_to_string(rp
));
194 printf("RS: recovery script performs service restart...\n");
196 /* Restart the service, but make sure we don't call the script again. */
197 strcpy(script
, rp
->r_script
);
198 rp
->r_script
[0] = '\0';
200 strcpy(rp
->r_script
, script
);
205 /*===========================================================================*
207 *===========================================================================*/
208 int do_clone(message
*m_ptr
)
211 struct rprocpub
*rpub
;
213 char label
[RS_MAX_LABEL_LEN
];
216 s
= copy_label(m_ptr
->m_source
, m_ptr
->m_rs_req
.addr
,
217 m_ptr
->m_rs_req
.len
, label
, sizeof(label
));
222 /* Lookup slot by label. */
223 rp
= lookup_slot_by_label(label
);
226 printf("RS: do_clone: service '%s' not found\n", label
);
231 /* Check if the call can be allowed. */
232 if((r
= check_call_permission(m_ptr
->m_source
, RS_CLONE
, rp
)) != OK
)
235 /* Don't clone if a replica is already available. */
240 /* Clone the service as requested. */
241 rpub
->sys_flags
|= SF_USE_REPL
;
242 if ((r
= clone_service(rp
, RST_SYS_PROC
, 0)) != OK
) {
243 rpub
->sys_flags
&= ~SF_USE_REPL
;
250 /*===========================================================================*
252 *===========================================================================*/
253 int do_unclone(message
*m_ptr
)
256 struct rprocpub
*rpub
;
258 char label
[RS_MAX_LABEL_LEN
];
261 s
= copy_label(m_ptr
->m_source
, m_ptr
->m_rs_req
.addr
,
262 m_ptr
->m_rs_req
.len
, label
, sizeof(label
));
267 /* Lookup slot by label. */
268 rp
= lookup_slot_by_label(label
);
271 printf("RS: do_unclone: service '%s' not found\n", label
);
276 /* Check if the call can be allowed. */
277 if((r
= check_call_permission(m_ptr
->m_source
, RS_UNCLONE
, rp
)) != OK
)
280 /* Don't unclone if no replica is available. */
281 if(!(rpub
->sys_flags
& SF_USE_REPL
)) {
285 /* Unclone the service as requested. */
286 rpub
->sys_flags
&= ~SF_USE_REPL
;
288 cleanup_service_now(rp
->r_next_rp
);
289 rp
->r_next_rp
= NULL
;
295 /*===========================================================================*
297 *===========================================================================*/
298 int do_edit(message
*m_ptr
)
301 struct rprocpub
*rpub
;
302 struct rs_start rs_start
;
304 char label
[RS_MAX_LABEL_LEN
];
306 /* Copy the request structure. */
307 r
= copy_rs_start(m_ptr
->m_source
, m_ptr
->m_rs_req
.addr
, &rs_start
);
313 r
= copy_label(m_ptr
->m_source
, rs_start
.rss_label
.l_addr
,
314 rs_start
.rss_label
.l_len
, label
, sizeof(label
));
319 /* Lookup slot by label. */
320 rp
= lookup_slot_by_label(label
);
323 printf("RS: do_edit: service '%s' not found\n", label
);
328 /* Check if the call can be allowed. */
329 if((r
= check_call_permission(m_ptr
->m_source
, RS_EDIT
, rp
)) != OK
)
333 printf("RS: %s edits settings\n", srv_to_string(rp
));
335 /* Synch the privilege structure with the kernel. */
336 if ((r
= sys_getpriv(&rp
->r_priv
, rpub
->endpoint
)) != OK
) {
337 printf("RS: do_edit: unable to synch privilege structure: %d\n", r
);
341 /* Tell scheduler this process is finished */
342 if ((r
= sched_stop(rp
->r_scheduler
, rpub
->endpoint
)) != OK
) {
343 printf("RS: do_edit: scheduler won't give up process: %d\n", r
);
347 /* Edit the slot as requested. */
348 if((r
= edit_slot(rp
, &rs_start
, m_ptr
->m_source
)) != OK
) {
349 printf("RS: do_edit: unable to edit the existing slot: %d\n", r
);
353 /* Update privilege structure. */
354 r
= sys_privctl(rpub
->endpoint
, SYS_PRIV_UPDATE_SYS
, &rp
->r_priv
);
356 printf("RS: do_edit: unable to update privilege structure: %d\n", r
);
360 /* Update VM calls. */
361 if ((r
= vm_set_priv(rpub
->endpoint
, &rpub
->vm_call_mask
[0],
362 !!(rp
->r_priv
.s_flags
& SYS_PROC
))) != OK
) {
363 printf("RS: do_edit: failed: %d\n", r
);
367 /* Reinitialize scheduling. */
368 if ((r
= sched_init_proc(rp
)) != OK
) {
369 printf("RS: do_edit: unable to reinitialize scheduling: %d\n", r
);
373 /* Cleanup old replicas and create a new one, if necessary. */
374 if(rpub
->sys_flags
& SF_USE_REPL
) {
376 cleanup_service(rp
->r_next_rp
);
377 rp
->r_next_rp
= NULL
;
379 if ((r
= clone_service(rp
, RST_SYS_PROC
, 0)) != OK
) {
380 printf("RS: warning: unable to clone %s\n", srv_to_string(rp
));
387 /*===========================================================================*
389 *===========================================================================*/
390 int do_refresh(message
*m_ptr
)
392 register struct rproc
*rp
;
394 char label
[RS_MAX_LABEL_LEN
];
397 s
= copy_label(m_ptr
->m_source
, m_ptr
->m_rs_req
.addr
,
398 m_ptr
->m_rs_req
.len
, label
, sizeof(label
));
403 /* Lookup slot by label. */
404 rp
= lookup_slot_by_label(label
);
407 printf("RS: do_refresh: service '%s' not found\n", label
);
411 /* Check if the call can be allowed. */
412 if((s
= check_call_permission(m_ptr
->m_source
, RS_REFRESH
, rp
)) != OK
)
415 /* Refresh service. */
417 printf("RS: %s refreshing\n", srv_to_string(rp
));
418 stop_service(rp
,RS_REFRESHING
);
420 /* Late reply - send a reply when refresh completes. */
421 rp
->r_flags
|= RS_LATEREPLY
;
422 rp
->r_caller
= m_ptr
->m_source
;
423 rp
->r_caller_request
= RS_REFRESH
;
428 /*===========================================================================*
430 *===========================================================================*/
431 int do_shutdown(message
*m_ptr
)
437 /* Check if the call can be allowed. */
439 if((r
= check_call_permission(m_ptr
->m_source
, RS_SHUTDOWN
, NULL
)) != OK
)
444 printf("RS: shutting down...\n");
446 /* Set flag to tell RS we are shutting down. */
447 shutting_down
= TRUE
;
449 /* Don't restart dead services. */
450 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
451 rp
= &rproc
[slot_nr
];
452 if (rp
->r_flags
& RS_IN_USE
) {
453 rp
->r_flags
|= RS_EXITING
;
459 /*===========================================================================*
461 *===========================================================================*/
462 int do_init_ready(message
*m_ptr
)
466 struct rproc
*rp
, *new_rp
;
467 struct rprocpub
*rpub
;
471 who_p
= _ENDPOINT_P(m_ptr
->m_source
);
472 result
= m_ptr
->m_rs_init
.result
;
474 rp
= rproc_ptr
[who_p
];
477 /* Make sure the originating service was requested to initialize. */
478 if(! (rp
->r_flags
& RS_INITIALIZING
) ) {
480 printf("RS: do_init_ready: got unexpected init ready msg from %d\n",
485 /* Check if something went wrong and the service failed to init.
486 * In that case, kill the service.
490 printf("RS: %s initialization error: %s\n", srv_to_string(rp
),
491 init_strerror(result
));
492 if (result
== ERESTART
&& !SRV_IS_UPDATING(rp
))
493 rp
->r_flags
|= RS_REINCARNATE
;
494 crash_service(rp
); /* simulate crash */
495 rp
->r_init_err
= result
;
500 printf("RS: %s initialized\n", srv_to_string(rp
));
502 /* If updating, check if there is no service to update left. In that case,
503 * end the update process. If VM has completed initialization as part of
504 * multi-component live update, let the other services under update run now.
506 if(SRV_IS_UPDATING(rp
)) {
507 rupdate
.num_init_ready_pending
--;
508 rp
->r_flags
|= RS_INIT_DONE
;
509 if(rupdate
.num_init_ready_pending
== 0) {
510 printf("RS: update succeeded\n");
511 end_update(OK
, RS_REPLY
);
515 /* Mark the slot as no longer initializing. */
516 rp
->r_flags
&= ~RS_INITIALIZING
;
518 rp
->r_alive_tm
= getticks();
520 /* Reply and unblock the service before doing anything else. */
522 reply(rpub
->endpoint
, rp
, &m
);
524 /* Finalize initialization. */
531 /*===========================================================================*
533 *===========================================================================*/
534 int do_update(message
*m_ptr
)
537 struct rproc
*trg_rp
;
538 struct rproc
*new_rp
;
539 struct rprocpub
*rpub
;
540 struct rprocupd
*rpupd
;
541 struct rs_start rs_start
;
542 int noblock
, do_self_update
, force_self_update
, batch_mode
, prepare_only
;
544 char label
[RS_MAX_LABEL_LEN
];
545 int prepare_state
, prepare_maxtime
;
546 endpoint_t state_endpoint
;
549 int allow_retries
= 0;
551 /* Copy the request structure. */
552 s
= copy_rs_start(m_ptr
->m_source
, m_ptr
->m_rs_req
.addr
, &rs_start
);
558 s
= copy_label(m_ptr
->m_source
, rs_start
.rss_label
.l_addr
,
559 rs_start
.rss_label
.l_len
, label
, sizeof(label
));
564 /* Lookup slot by label. */
565 rp
= lookup_slot_by_label(label
);
568 printf("RS: do_update: service '%s' not found\n", label
);
574 noblock
= (rs_start
.rss_flags
& RSS_NOBLOCK
);
575 do_self_update
= (rs_start
.rss_flags
& RSS_SELF_LU
);
576 force_self_update
= (rs_start
.rss_flags
& RSS_FORCE_SELF_LU
);
577 batch_mode
= (rs_start
.rss_flags
& RSS_BATCH
);
578 prepare_only
= (rs_start
.rss_flags
& RSS_PREPARE_ONLY_LU
);
579 if(do_self_update
|| force_self_update
) {
580 lu_flags
|= SEF_LU_SELF
;
583 lu_flags
|= SEF_LU_PREPARE_ONLY
;
585 if(rs_start
.rss_flags
& RSS_ASR_LU
) {
586 lu_flags
|= SEF_LU_ASR
;
588 if(!prepare_only
&& (rs_start
.rss_flags
& RSS_DETACH
)) {
589 lu_flags
|= SEF_LU_DETACHED
;
591 if(rs_start
.rss_map_prealloc_bytes
<= 0
592 && rpub
->endpoint
== VM_PROC_NR
593 && (((lu_flags
& (SEF_LU_SELF
|SEF_LU_ASR
)) != SEF_LU_SELF
) || rs_start
.rss_flags
& RSS_FORCE_INIT_ST
)
594 && RS_VM_DEFAULT_MAP_PREALLOC_LEN
> 0) {
595 /* Give VM some mmapped regions by default on non-identical updates.*/
596 rs_start
.rss_map_prealloc_bytes
= RS_VM_DEFAULT_MAP_PREALLOC_LEN
;
598 printf("RS: %s gets %ld default mmap bytes\n", srv_to_string(rp
),
599 rs_start
.rss_map_prealloc_bytes
);
601 if((rs_start
.rss_flags
& RSS_NOMMAP_LU
) || rs_start
.rss_map_prealloc_bytes
) {
602 /* Don't inherit mmapped regions at update time if requested or if
603 * mmap preallocation is used.
605 lu_flags
|= SEF_LU_NOMMAP
;
607 if(rs_start
.rss_flags
& RSS_FORCE_INIT_CRASH
) {
608 init_flags
|= SEF_INIT_CRASH
;
610 if(rs_start
.rss_flags
& RSS_FORCE_INIT_FAIL
) {
611 init_flags
|= SEF_INIT_FAIL
;
613 if(rs_start
.rss_flags
& RSS_FORCE_INIT_TIMEOUT
) {
614 init_flags
|= SEF_INIT_TIMEOUT
;
616 if(rs_start
.rss_flags
& RSS_FORCE_INIT_DEFCB
) {
617 init_flags
|= SEF_INIT_DEFCB
;
619 if(rs_start
.rss_flags
& RSS_FORCE_INIT_ST
) {
620 init_flags
|= SEF_INIT_ST
;
622 init_flags
|= lu_flags
;
624 /* Lookup target label (if any). */
626 state_endpoint
= NONE
;
627 if(rs_start
.rss_trg_label
.l_len
> 0) {
628 s
= copy_label(m_ptr
->m_source
, rs_start
.rss_trg_label
.l_addr
,
629 rs_start
.rss_trg_label
.l_len
, label
, sizeof(label
));
633 trg_rp
= lookup_slot_by_label(label
);
636 printf("RS: do_update: target service '%s' not found\n", label
);
639 state_endpoint
= trg_rp
->r_pub
->endpoint
;
642 /* Check if the call can be allowed. */
643 if((s
= check_call_permission(m_ptr
->m_source
, RS_UPDATE
, rp
)) != OK
)
646 /* Retrieve live update state. */
647 prepare_state
= m_ptr
->m_rs_update
.state
;
648 if(prepare_state
== SEF_LU_STATE_NULL
) {
652 /* Retrieve prepare max time. */
653 prepare_maxtime
= m_ptr
->m_rs_update
.prepare_maxtime
;
654 if(prepare_maxtime
== 0) {
655 prepare_maxtime
= RS_DEFAULT_PREPARE_MAXTIME
;
658 /* Make sure we are not already updating. */
659 if(RUPDATE_IS_UPDATING()) {
660 printf("RS: an update is already in progress\n");
664 /* If an update is already scheduled, check constraints. */
665 if(RUPDATE_IS_UPD_SCHEDULED()) {
667 printf("RS: an update is already scheduled, cannot start a new one\n");
670 if(SRV_IS_UPD_SCHEDULED(rp
)) {
671 printf("RS: the specified process is already part of the currently scheduled update\n");
676 /* Prepare-only update for VM, PM, and VFS is only supported with an unreachable state. */
678 && (rp
->r_pub
->endpoint
== VM_PROC_NR
|| rp
->r_pub
->endpoint
== PM_PROC_NR
|| rp
->r_pub
->endpoint
== VFS_PROC_NR
)) {
679 if(prepare_state
!= SEF_LU_STATE_UNREACHABLE
) {
680 printf("RS: prepare-only update for VM, PM and VFS is only supported with state %d\n", SEF_LU_STATE_UNREACHABLE
);
685 /* Prepare-only update for RS is not supported. */
686 if(prepare_only
&& rp
->r_pub
->endpoint
== RS_PROC_NR
) {
687 printf("RS: prepare-only update for RS is not supported\n");
691 /* Initialize update descriptor. */
693 rupdate_upd_init(rpupd
, rp
);
694 rpupd
->lu_flags
|= lu_flags
;
695 rpupd
->init_flags
|= init_flags
;
696 rupdate_set_new_upd_flags(rpupd
);
698 /* A self update live updates a service instance into a replica, a regular
699 * update live updates a service instance into a new version, as specified
700 * by the given binary.
705 printf("RS: %s requested to perform self update\n", srv_to_string(rp
));
707 /* Clone the system service and use the replica as the new version. */
708 s
= clone_service(rp
, LU_SYS_PROC
, rpupd
->init_flags
);
710 printf("RS: do_update: unable to clone service: %d\n", s
);
713 new_rp
= rp
->r_new_rp
;
717 printf("RS: %s requested to perform %s update\n", srv_to_string(rp
),
718 force_self_update
? "(forced) self" : "regular");
720 /* Allocate a system service slot for the new version. */
721 s
= alloc_slot(&new_rp
);
723 printf("RS: do_update: unable to allocate a new slot: %d\n", s
);
727 /* Initialize the slot as requested. */
728 s
= init_slot(new_rp
, &rs_start
, m_ptr
->m_source
);
730 printf("RS: do_update: unable to init the new slot: %d\n", s
);
734 /* Let the new version inherit defaults from the old one. */
735 inherit_service_defaults(rp
, new_rp
);
737 /* Link the two versions. */
738 rp
->r_new_rp
= new_rp
;
739 new_rp
->r_old_rp
= rp
;
741 /* Create new version of the service but don't let it run. */
742 new_rp
->r_priv
.s_flags
|= LU_SYS_PROC
;
743 new_rp
->r_priv
.s_init_flags
|= rpupd
->init_flags
;
744 s
= create_service(new_rp
);
746 printf("RS: do_update: unable to create a new service: %d\n", s
);
751 /* Set default state endpoint. */
752 if(state_endpoint
== NONE
) {
753 state_endpoint
= new_rp
->r_pub
->endpoint
;
756 /* If RS is updating, set up signal managers for the new instance.
757 * The current RS instance must be made the backup signal manager to
758 * support rollback in case of a crash during initialization.
760 if(rp
->r_priv
.s_flags
& ROOT_SYS_PROC
) {
761 s
= update_sig_mgrs(new_rp
, SELF
, new_rp
->r_pub
->endpoint
);
763 cleanup_service(new_rp
);
768 /* Preallocate heap regions if requested. */
769 if(rs_start
.rss_heap_prealloc_bytes
< 0) {
770 rs_start
.rss_heap_prealloc_bytes
= 0;
772 if(rs_start
.rss_heap_prealloc_bytes
) {
775 printf("RS: %s preallocating %ld heap bytes\n", srv_to_string(new_rp
),
776 rs_start
.rss_heap_prealloc_bytes
);
778 len
= rs_start
.rss_heap_prealloc_bytes
;
779 s
= vm_memctl(new_rp
->r_pub
->endpoint
, VM_RS_MEM_HEAP_PREALLOC
,
782 printf("vm_memctl(VM_RS_MEM_HEAP_PREALLOC) failed: %d\n", s
);
783 cleanup_service(new_rp
);
786 if(rp
->r_priv
.s_flags
& ROOT_SYS_PROC
) {
787 vm_memctl(new_rp
->r_pub
->endpoint
, VM_RS_MEM_PIN
, 0, 0);
791 /* Preallocate mmapped regions if requested. */
792 if(rs_start
.rss_map_prealloc_bytes
< 0) {
793 rs_start
.rss_map_prealloc_bytes
= 0;
795 if(rs_start
.rss_map_prealloc_bytes
) {
798 printf("RS: %s preallocating %ld mmap bytes\n", srv_to_string(new_rp
),
799 rs_start
.rss_map_prealloc_bytes
);
801 new_rp
->r_map_prealloc_len
= rs_start
.rss_map_prealloc_bytes
;
802 s
= vm_memctl(new_rp
->r_pub
->endpoint
, VM_RS_MEM_MAP_PREALLOC
,
803 &addr
, &new_rp
->r_map_prealloc_len
);
805 printf("vm_memctl(VM_RS_MEM_MAP_PREALLOC) failed: %d\n", s
);
806 cleanup_service(new_rp
);
809 new_rp
->r_map_prealloc_addr
= (vir_bytes
) addr
;
813 /* Process state data. */
814 s
= init_state_data(m_ptr
->m_source
, prepare_state
, &rs_start
.rss_state_data
, &rpupd
->prepare_state_data
);
816 rupdate_upd_clear(rpupd
);
820 /* Create update grants. */
821 if(rpupd
->prepare_state_data
.size
> 0) {
822 struct rs_state_data
*state_data
= &rpupd
->prepare_state_data
;
823 rpupd
->prepare_state_data_gid
= cpf_grant_direct(rpub
->endpoint
, (vir_bytes
) state_data
,
824 state_data
->size
, CPF_READ
);
825 if(rpupd
->prepare_state_data_gid
== GRANT_INVALID
) {
826 rupdate_upd_clear(rpupd
);
829 state_data
->ipcf_els_gid
= GRANT_INVALID
;
830 if(state_data
->ipcf_els
) {
831 state_data
->ipcf_els_gid
= (int) cpf_grant_direct(rpub
->endpoint
, (vir_bytes
) state_data
->ipcf_els
,
832 state_data
->ipcf_els_size
, CPF_READ
);
833 if(state_data
->ipcf_els_gid
== GRANT_INVALID
) {
834 rupdate_upd_clear(rpupd
);
838 state_data
->eval_gid
= GRANT_INVALID
;
839 if(state_data
->eval_addr
) {
840 state_data
->eval_gid
= (int) cpf_grant_direct(rpub
->endpoint
, (vir_bytes
) state_data
->eval_addr
,
841 state_data
->eval_len
, CPF_READ
);
842 if(state_data
->eval_gid
== GRANT_INVALID
) {
843 rupdate_upd_clear(rpupd
);
849 /* Fill the new update descriptor and add it to the update chain. */
850 rpupd
->prepare_state
= prepare_state
;
851 rpupd
->state_endpoint
= state_endpoint
;
852 rpupd
->prepare_tm
= getticks();
853 rpupd
->prepare_maxtime
= prepare_maxtime
;
854 rupdate_add_upd(rpupd
);
857 printf("RS: %s scheduled for %s\n", srv_to_string(rp
), srv_upd_to_string(rpupd
));
859 /* If batch mode, reply immediately. More services to update will follow. */
864 /* Start preparing for the update process. */
865 s
= start_update_prepare(allow_retries
);
867 /* No process left in the update chain. We are done already. */
874 /* Unblock the caller immediately if requested. */
879 /* Otherwise, send a reply when the new version completes initialization. */
880 rupdate
.last_rpupd
->rp
->r_flags
|= RS_LATEREPLY
;
881 rupdate
.last_rpupd
->rp
->r_caller
= m_ptr
->m_source
;
882 rupdate
.last_rpupd
->rp
->r_caller_request
= RS_UPDATE
;
887 /*===========================================================================*
889 *===========================================================================*/
890 int do_upd_ready(message
*m_ptr
)
893 struct rprocupd
*prev_rpupd
, *rpupd
;
899 who_p
= _ENDPOINT_P(m_ptr
->m_source
);
900 rp
= rproc_ptr
[who_p
];
901 result
= m_ptr
->m_rs_update
.result
;
903 /* Make sure the originating service was requested to prepare for update. */
904 rpupd
= rupdate
.curr_rpupd
;
905 if(!rpupd
|| rp
!= rpupd
->rp
|| RUPDATE_IS_INITIALIZING()) {
907 printf("RS: %s sent late/unexpected update ready msg\n",
911 rp
->r_flags
|= RS_PREPARE_DONE
;
913 /* Check if something went wrong and the service failed to prepare
914 * for the update. In that case, end the update process. The old version will
915 * be replied to and continue executing.
918 printf("RS: update failed: %s\n", lu_strerror(result
));
919 end_update(result
, RS_REPLY
);
925 printf("RS: %s ready to update\n", srv_to_string(rp
));
927 /* If this is a multi-component update and this is not the last service
928 * in the update, request the next process to update.
930 if(start_update_prepare_next() != NULL
) {
934 /* Now perform the update and request each new instance to initialize. */
940 /*===========================================================================*
942 *===========================================================================*/
943 void do_period(m_ptr
)
946 register struct rproc
*rp
;
947 register struct rprocpub
*rpub
;
948 clock_t now
= m_ptr
->m_notify
.timestamp
;
952 /* If an update is in progress, check its status. */
953 if(RUPDATE_IS_UPDATING() && !RUPDATE_IS_INITIALIZING()) {
954 update_period(m_ptr
);
957 /* Search system services table. Only check slots that are in use and not
960 for (rp
=BEG_RPROC_ADDR
; rp
<END_RPROC_ADDR
; rp
++) {
963 if ((rp
->r_flags
& RS_ACTIVE
) && (!SRV_IS_UPDATING(rp
) || ((rp
->r_flags
& (RS_INITIALIZING
|RS_INIT_DONE
|RS_INIT_PENDING
)) == RS_INITIALIZING
))) {
965 /* Compute period. */
966 period
= rp
->r_period
;
967 if(rp
->r_flags
& RS_INITIALIZING
) {
968 period
= SRV_IS_UPDATING(rp
) ? UPD_INIT_MAXTIME(&rp
->r_upd
) : RS_INIT_T
;
971 /* If the service is to be revived (because it repeatedly exited,
972 * and was not directly restarted), the binary backoff field is
975 if (rp
->r_backoff
> 0) {
977 if (rp
->r_backoff
== 0) {
982 /* If the service was signaled with a SIGTERM and fails to respond,
983 * kill the system service with a SIGKILL signal.
985 else if (rp
->r_stop_tm
> 0 && now
- rp
->r_stop_tm
> 2*RS_DELTA_T
988 crash_service(rp
); /* simulate crash */
991 /* There seems to be no special conditions. If the service has a
992 * period assigned check its status.
994 else if (period
> 0) {
996 /* Check if an answer to a status request is still pending. If
997 * the service didn't respond within time, kill it to simulate
998 * a crash. The failure will be detected and the service will
999 * be restarted automatically. Give the service a free pass if
1000 * somebody is initializing. There may be some weird dependencies
1001 * if another service is, for example, restarting at the same
1004 if (rp
->r_alive_tm
< rp
->r_check_tm
) {
1005 if (now
- rp
->r_alive_tm
> 2*period
&&
1006 rp
->r_pid
> 0 && !(rp
->r_flags
& RS_NOPINGREPLY
)) {
1010 printf("RS: %s reported late\n", srv_to_string(rp
));
1011 init_flag
= rp
->r_flags
& RS_INITIALIZING
;
1012 rp
->r_flags
&= ~RS_INITIALIZING
;
1013 rp2
= lookup_slot_by_flags(RS_INITIALIZING
);
1014 rp
->r_flags
|= init_flag
;
1015 if(rp2
!= NULL
&& !SRV_IS_UPDATING(rp
)) {
1018 printf("RS: %s gets a free pass\n",
1020 rp
->r_alive_tm
= now
;
1021 rp
->r_check_tm
= now
+1;
1024 rp
->r_flags
|= RS_NOPINGREPLY
;
1025 crash_service(rp
); /* simulate crash */
1026 if(rp
->r_flags
& RS_INITIALIZING
) {
1027 rp
->r_init_err
= EINTR
;
1032 /* No answer pending. Check if a period expired since the last
1033 * check and, if so request the system service's status.
1035 else if (now
- rp
->r_check_tm
> rp
->r_period
) {
1036 ipc_notify(rpub
->endpoint
); /* request status */
1037 rp
->r_check_tm
= now
; /* mark time */
1043 /* Reschedule a synchronous alarm for the next period. */
1044 if (OK
!= (s
=sys_setalarm(RS_DELTA_T
, 0)))
1045 panic("couldn't set alarm: %d", s
);
1048 /*===========================================================================*
1050 *===========================================================================*/
1053 /* PM informed us that there are dead children to cleanup. Go get them. */
1058 int i
, nr_rps
, found
;
1061 printf("RS: got SIGCHLD signal, cleaning up dead children\n");
1063 while ( (pid
= waitpid(-1, &status
, WNOHANG
)) != 0 ) {
1064 rp
= lookup_slot_by_pid(pid
);
1068 printf("RS: %s exited via another signal manager\n",
1071 /* The slot is still there. This means RS is not the signal
1072 * manager assigned to the process. Ignore the event but
1073 * free slots for all the service instances and send a late
1074 * reply if necessary.
1077 get_service_instances(rp
, &rps
, &nr_rps
);
1078 for(i
=0;i
<nr_rps
;i
++) {
1079 if(SRV_IS_UPDATING(rps
[i
])) {
1080 rps
[i
]->r_flags
&= ~(RS_UPDATING
|RS_PREPARE_DONE
|RS_INIT_DONE
|RS_INIT_PENDING
);
1086 rupdate_clear_upds();
1092 /*===========================================================================*
1094 *===========================================================================*/
1095 int do_getsysinfo(m_ptr
)
1098 vir_bytes src_addr
, dst_addr
;
1103 /* Check if the call can be allowed. */
1104 if((s
= check_call_permission(m_ptr
->m_source
, 0, NULL
)) != OK
)
1107 dst_proc
= m_ptr
->m_source
;
1108 dst_addr
= m_ptr
->m_lsys_getsysinfo
.where
;
1109 size
= m_ptr
->m_lsys_getsysinfo
.size
;
1111 switch(m_ptr
->m_lsys_getsysinfo
.what
) {
1113 src_addr
= (vir_bytes
) rproc
;
1114 len
= sizeof(struct rproc
) * NR_SYS_PROCS
;
1116 case SI_PROCALL_TAB
:
1117 /* Copy out both tables, one after the other. */
1118 src_addr
= (vir_bytes
) rproc
;
1119 len
= sizeof(struct rproc
) * NR_SYS_PROCS
;
1122 if ((s
= sys_datacopy(SELF
, src_addr
, dst_proc
, dst_addr
, len
)) != OK
)
1127 case SI_PROCPUB_TAB
:
1128 src_addr
= (vir_bytes
) rprocpub
;
1129 len
= sizeof(struct rprocpub
) * NR_SYS_PROCS
;
1138 return sys_datacopy(SELF
, src_addr
, dst_proc
, dst_addr
, len
);
1141 /*===========================================================================*
1143 *===========================================================================*/
1144 int do_lookup(m_ptr
)
1147 static char namebuf
[100];
1150 struct rprocpub
*rrpub
;
1152 len
= m_ptr
->m_rs_req
.name_len
;
1154 if(len
< 2 || len
>= sizeof(namebuf
)) {
1155 printf("RS: len too weird (%d)\n", len
);
1159 if((r
=sys_datacopy(m_ptr
->m_source
, (vir_bytes
) m_ptr
->m_rs_req
.name
,
1160 SELF
, (vir_bytes
) namebuf
, len
)) != OK
) {
1161 printf("RS: name copy failed\n");
1166 namebuf
[len
] = '\0';
1168 rrp
= lookup_slot_by_label(namebuf
);
1173 m_ptr
->m_rs_req
.endpoint
= rrpub
->endpoint
;
1178 /*===========================================================================*
1180 *===========================================================================*/
1181 int do_sysctl(message
*m_ptr
)
1183 int request_type
= m_ptr
->m_rs_req
.subtype
;
1184 int r
, allow_retries
= 1;
1185 switch(request_type
) {
1186 case RS_SYSCTL_SRV_STATUS
:
1187 print_services_status();
1189 case RS_SYSCTL_UPD_START
:
1190 case RS_SYSCTL_UPD_RUN
:
1191 r
= start_update_prepare(allow_retries
);
1192 print_update_status();
1195 /* We are done already. */
1200 if(request_type
== RS_SYSCTL_UPD_START
) {
1203 /* Send a reply when done. */
1204 rupdate
.last_rpupd
->rp
->r_flags
|= RS_LATEREPLY
;
1205 rupdate
.last_rpupd
->rp
->r_caller
= m_ptr
->m_source
;
1206 rupdate
.last_rpupd
->rp
->r_caller_request
= RS_UPDATE
;
1209 case RS_SYSCTL_UPD_STOP
:
1210 r
= abort_update_proc(EINTR
);
1211 print_update_status();
1214 case RS_SYSCTL_UPD_STATUS
:
1215 print_update_status();
1218 printf("RS: bad sysctl type\n");
1226 /*===========================================================================*
1228 *===========================================================================*/
1229 int do_fi(message
*m_ptr
)
1232 struct rprocpub
*rpub
;
1234 char label
[RS_MAX_LABEL_LEN
];
1237 s
= copy_label(m_ptr
->m_source
, m_ptr
->m_rs_req
.addr
,
1238 m_ptr
->m_rs_req
.len
, label
, sizeof(label
));
1243 /* Lookup slot by label. */
1244 rp
= lookup_slot_by_label(label
);
1247 printf("RS: do_fi: service '%s' not found\n", label
);
1252 /* Check if the call can be allowed. */
1253 if((r
= check_call_permission(m_ptr
->m_source
, RS_FI
, rp
)) != OK
)
1256 /* Inject fault into the service as requested. */
1262 /*===========================================================================*
1264 *===========================================================================*/
1265 static int check_request(struct rs_start
*rs_start
)
1267 /* Verify scheduling parameters */
1268 if (rs_start
->rss_scheduler
!= KERNEL
&&
1269 (rs_start
->rss_scheduler
< 0 ||
1270 rs_start
->rss_scheduler
> LAST_SPECIAL_PROC_NR
)) {
1271 printf("RS: check_request: invalid scheduler %d\n",
1272 rs_start
->rss_scheduler
);
1275 if (rs_start
->rss_priority
>= NR_SCHED_QUEUES
) {
1276 printf("RS: check_request: priority %u out of range\n",
1277 rs_start
->rss_priority
);
1280 if (rs_start
->rss_quantum
<= 0) {
1281 printf("RS: check_request: quantum %u out of range\n",
1282 rs_start
->rss_quantum
);
1286 if (rs_start
->rss_cpu
== RS_CPU_BSP
)
1287 rs_start
->rss_cpu
= machine
.bsp_id
;
1288 else if (rs_start
->rss_cpu
== RS_CPU_DEFAULT
) {
1289 /* keep the default value */
1290 } else if (rs_start
->rss_cpu
< 0)
1292 else if (rs_start
->rss_cpu
> machine
.processors_count
) {
1293 printf("RS: cpu number %d out of range 0-%d, using BSP\n",
1294 rs_start
->rss_cpu
, machine
.processors_count
);
1295 rs_start
->rss_cpu
= machine
.bsp_id
;
1298 /* Verify signal manager. */
1299 if (rs_start
->rss_sigmgr
!= SELF
&&
1300 (rs_start
->rss_sigmgr
< 0 ||
1301 rs_start
->rss_sigmgr
> LAST_SPECIAL_PROC_NR
)) {
1302 printf("RS: check_request: invalid signal manager %d\n",
1303 rs_start
->rss_sigmgr
);