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
;
25 /* Check if the call can be allowed. */
26 if((r
= check_call_permission(m_ptr
->m_source
, RS_UP
, NULL
)) != OK
)
29 /* Allocate a new system service slot. */
32 printf("RS: do_up: unable to allocate a new slot: %d\n", r
);
37 /* Copy the request structure. */
38 r
= copy_rs_start(m_ptr
->m_source
, m_ptr
->RS_CMD_ADDR
, &rs_start
);
42 r
= check_request(&rs_start
);
46 noblock
= (rs_start
.rss_flags
& RSS_NOBLOCK
);
48 /* Initialize the slot as requested. */
49 r
= init_slot(rp
, &rs_start
, m_ptr
->m_source
);
51 printf("RS: do_up: unable to init the new slot: %d\n", r
);
55 /* Check for duplicates */
56 if(lookup_slot_by_label(rpub
->label
)) {
57 printf("RS: service with the same label '%s' already exists\n",
61 if(rpub
->dev_nr
>0 && lookup_slot_by_dev_nr(rpub
->dev_nr
)) {
62 printf("RS: service with the same device number %d already exists\n",
67 /* All information was gathered. Now try to start the system service. */
68 r
= start_service(rp
);
73 /* Unblock the caller immediately if requested. */
78 /* Late reply - send a reply when service completes initialization. */
79 rp
->r_flags
|= RS_LATEREPLY
;
80 rp
->r_caller
= m_ptr
->m_source
;
81 rp
->r_caller_request
= RS_UP
;
86 /*===========================================================================*
88 *===========================================================================*/
89 int do_down(message
*m_ptr
)
91 register struct rproc
*rp
;
93 char label
[RS_MAX_LABEL_LEN
];
96 s
= copy_label(m_ptr
->m_source
, m_ptr
->RS_CMD_ADDR
,
97 m_ptr
->RS_CMD_LEN
, label
, sizeof(label
));
102 /* Lookup slot by label. */
103 rp
= lookup_slot_by_label(label
);
106 printf("RS: do_down: service '%s' not found\n", label
);
110 /* Check if the call can be allowed. */
111 if((s
= check_call_permission(m_ptr
->m_source
, RS_DOWN
, rp
)) != OK
)
115 if (rp
->r_flags
& RS_TERMINATED
) {
116 /* A recovery script is requesting us to bring down the service.
117 * The service is already gone, simply perform cleanup.
120 printf("RS: recovery script performs service down...\n");
121 unpublish_service(rp
);
125 stop_service(rp
,RS_EXITING
);
127 /* Late reply - send a reply when service dies. */
128 rp
->r_flags
|= RS_LATEREPLY
;
129 rp
->r_caller
= m_ptr
->m_source
;
130 rp
->r_caller_request
= RS_DOWN
;
135 /*===========================================================================*
137 *===========================================================================*/
138 int do_restart(message
*m_ptr
)
142 char label
[RS_MAX_LABEL_LEN
];
143 char script
[MAX_SCRIPT_LEN
];
146 s
= copy_label(m_ptr
->m_source
, m_ptr
->RS_CMD_ADDR
,
147 m_ptr
->RS_CMD_LEN
, label
, sizeof(label
));
152 /* Lookup slot by label. */
153 rp
= lookup_slot_by_label(label
);
156 printf("RS: do_restart: service '%s' not found\n", label
);
160 /* Check if the call can be allowed. */
161 if((r
= check_call_permission(m_ptr
->m_source
, RS_RESTART
, rp
)) != OK
)
164 /* We can only be asked to restart a service from a recovery script. */
165 if (! (rp
->r_flags
& RS_TERMINATED
) ) {
167 printf("RS: %s is still running\n", srv_to_string(rp
));
172 printf("RS: recovery script performs service restart...\n");
174 /* Restart the service, but make sure we don't call the script again. */
175 strcpy(script
, rp
->r_script
);
176 rp
->r_script
[0] = '\0';
178 strcpy(rp
->r_script
, script
);
183 /*===========================================================================*
185 *===========================================================================*/
186 int do_clone(message
*m_ptr
)
189 struct rprocpub
*rpub
;
191 char label
[RS_MAX_LABEL_LEN
];
194 s
= copy_label(m_ptr
->m_source
, m_ptr
->RS_CMD_ADDR
,
195 m_ptr
->RS_CMD_LEN
, label
, sizeof(label
));
200 /* Lookup slot by label. */
201 rp
= lookup_slot_by_label(label
);
204 printf("RS: do_clone: service '%s' not found\n", label
);
209 /* Check if the call can be allowed. */
210 if((r
= check_call_permission(m_ptr
->m_source
, RS_CLONE
, rp
)) != OK
)
213 /* Don't clone if a replica is already available. */
218 /* Clone the service as requested. */
219 rpub
->sys_flags
|= SF_USE_REPL
;
220 if ((r
= clone_service(rp
, RST_SYS_PROC
)) != OK
) {
221 rpub
->sys_flags
&= ~SF_USE_REPL
;
228 /*===========================================================================*
230 *===========================================================================*/
231 int do_edit(message
*m_ptr
)
234 struct rprocpub
*rpub
;
235 struct rs_start rs_start
;
237 char label
[RS_MAX_LABEL_LEN
];
239 /* Copy the request structure. */
240 r
= copy_rs_start(m_ptr
->m_source
, m_ptr
->RS_CMD_ADDR
, &rs_start
);
246 r
= copy_label(m_ptr
->m_source
, rs_start
.rss_label
.l_addr
,
247 rs_start
.rss_label
.l_len
, label
, sizeof(label
));
252 /* Lookup slot by label. */
253 rp
= lookup_slot_by_label(label
);
256 printf("RS: do_edit: service '%s' not found\n", label
);
261 /* Check if the call can be allowed. */
262 if((r
= check_call_permission(m_ptr
->m_source
, RS_EDIT
, rp
)) != OK
)
266 printf("RS: %s edits settings\n", srv_to_string(rp
));
268 /* Synch the privilege structure with the kernel. */
269 if ((r
= sys_getpriv(&rp
->r_priv
, rpub
->endpoint
)) != OK
) {
270 printf("RS: do_edit: unable to synch privilege structure: %d\n", r
);
274 /* Tell scheduler this process is finished */
275 if ((r
= sched_stop(rp
->r_scheduler
, rpub
->endpoint
)) != OK
) {
276 printf("RS: do_edit: scheduler won't give up process: %d\n", r
);
280 /* Edit the slot as requested. */
281 if((r
= edit_slot(rp
, &rs_start
, m_ptr
->m_source
)) != OK
) {
282 printf("RS: do_edit: unable to edit the existing slot: %d\n", r
);
286 /* Update privilege structure. */
287 r
= sys_privctl(rpub
->endpoint
, SYS_PRIV_UPDATE_SYS
, &rp
->r_priv
);
289 printf("RS: do_edit: unable to update privilege structure: %d\n", r
);
293 /* Update VM calls. */
294 if ((r
= vm_set_priv(rpub
->endpoint
, &rpub
->vm_call_mask
[0])) != OK
) {
295 printf("RS: do_edit: failed: %d\n", r
);
299 /* Reinitialize scheduling. */
300 if ((r
= sched_init_proc(rp
)) != OK
) {
301 printf("RS: do_edit: unable to reinitialize scheduling: %d\n", r
);
305 /* Cleanup old replicas and create a new one, if necessary. */
306 if(rpub
->sys_flags
& SF_USE_REPL
) {
308 cleanup_service(rp
->r_next_rp
);
309 rp
->r_next_rp
= NULL
;
311 if ((r
= clone_service(rp
, RST_SYS_PROC
)) != OK
) {
312 printf("RS: warning: unable to clone %s\n", srv_to_string(rp
));
319 /*===========================================================================*
321 *===========================================================================*/
322 int do_refresh(message
*m_ptr
)
324 register struct rproc
*rp
;
326 char label
[RS_MAX_LABEL_LEN
];
329 s
= copy_label(m_ptr
->m_source
, m_ptr
->RS_CMD_ADDR
,
330 m_ptr
->RS_CMD_LEN
, label
, sizeof(label
));
335 /* Lookup slot by label. */
336 rp
= lookup_slot_by_label(label
);
339 printf("RS: do_refresh: service '%s' not found\n", label
);
343 /* Check if the call can be allowed. */
344 if((s
= check_call_permission(m_ptr
->m_source
, RS_REFRESH
, rp
)) != OK
)
347 /* Refresh service. */
349 printf("RS: %s refreshing\n", srv_to_string(rp
));
350 stop_service(rp
,RS_REFRESHING
);
355 /*===========================================================================*
357 *===========================================================================*/
358 int do_shutdown(message
*m_ptr
)
364 /* Check if the call can be allowed. */
366 if((r
= check_call_permission(m_ptr
->m_source
, RS_SHUTDOWN
, NULL
)) != OK
)
371 printf("RS: shutting down...\n");
373 /* Set flag to tell RS we are shutting down. */
374 shutting_down
= TRUE
;
376 /* Don't restart dead services. */
377 for (slot_nr
= 0; slot_nr
< NR_SYS_PROCS
; slot_nr
++) {
378 rp
= &rproc
[slot_nr
];
379 if (rp
->r_flags
& RS_IN_USE
) {
380 rp
->r_flags
|= RS_EXITING
;
386 /*===========================================================================*
388 *===========================================================================*/
389 int do_init_ready(message
*m_ptr
)
394 struct rprocpub
*rpub
;
398 is_rs
= (m_ptr
->m_source
== RS_PROC_NR
);
399 who_p
= _ENDPOINT_P(m_ptr
->m_source
);
400 result
= m_ptr
->RS_INIT_RESULT
;
402 /* Check for RS failing initialization first. */
403 if(is_rs
&& result
!= OK
) {
407 rp
= rproc_ptr
[who_p
];
410 /* Make sure the originating service was requested to initialize. */
411 if(! (rp
->r_flags
& RS_INITIALIZING
) ) {
413 printf("RS: do_init_ready: got unexpected init ready msg from %d\n",
418 /* Check if something went wrong and the service failed to init.
419 * In that case, kill the service.
423 printf("RS: %s initialization error: %s\n", srv_to_string(rp
),
424 init_strerror(result
));
425 if (result
== ERESTART
)
426 rp
->r_flags
|= RS_REINCARNATE
;
427 crash_service(rp
); /* simulate crash */
431 /* Mark the slot as no longer initializing. */
432 rp
->r_flags
&= ~RS_INITIALIZING
;
434 getuptime(&rp
->r_alive_tm
);
436 /* Reply and unblock the service before doing anything else. */
438 reply(rpub
->endpoint
, rp
, &m
);
440 /* See if a late reply has to be sent. */
444 printf("RS: %s initialized\n", srv_to_string(rp
));
446 /* If the service has completed initialization after a live
447 * update, end the update now.
449 if(rp
->r_flags
& RS_UPDATING
) {
450 printf("RS: update succeeded\n");
451 end_update(OK
, RS_DONTREPLY
);
454 /* If the service has completed initialization after a crash
455 * make the new instance active and cleanup the old replica.
458 cleanup_service(rp
->r_prev_rp
);
459 rp
->r_prev_rp
= NULL
;
463 printf("RS: %s completed restart\n", srv_to_string(rp
));
466 /* If we must keep a replica of this system service, create it now. */
467 if(rpub
->sys_flags
& SF_USE_REPL
) {
468 if ((r
= clone_service(rp
, RST_SYS_PROC
)) != OK
) {
469 printf("RS: warning: unable to clone %s\n", srv_to_string(rp
));
473 return is_rs
? OK
: EDONTREPLY
; /* return what the caller expects */
476 /*===========================================================================*
478 *===========================================================================*/
479 int do_update(message
*m_ptr
)
482 struct rproc
*new_rp
;
483 struct rprocpub
*rpub
;
484 struct rs_start rs_start
;
485 int noblock
, do_self_update
;
487 char label
[RS_MAX_LABEL_LEN
];
491 /* Copy the request structure. */
492 s
= copy_rs_start(m_ptr
->m_source
, m_ptr
->RS_CMD_ADDR
, &rs_start
);
496 noblock
= (rs_start
.rss_flags
& RSS_NOBLOCK
);
497 do_self_update
= (rs_start
.rss_flags
& RSS_SELF_LU
);
498 s
= check_request(&rs_start
);
504 s
= copy_label(m_ptr
->m_source
, rs_start
.rss_label
.l_addr
,
505 rs_start
.rss_label
.l_len
, label
, sizeof(label
));
510 /* Lookup slot by label. */
511 rp
= lookup_slot_by_label(label
);
514 printf("RS: do_update: service '%s' not found\n", label
);
519 /* Check if the call can be allowed. */
520 if((s
= check_call_permission(m_ptr
->m_source
, RS_UPDATE
, rp
)) != OK
)
523 /* Retrieve live update state. */
524 lu_state
= m_ptr
->RS_LU_STATE
;
525 if(lu_state
== SEF_LU_STATE_NULL
) {
529 /* Retrieve prepare max time. */
530 prepare_maxtime
= m_ptr
->RS_LU_PREPARE_MAXTIME
;
531 if(prepare_maxtime
) {
532 if(prepare_maxtime
< 0 || prepare_maxtime
> RS_MAX_PREPARE_MAXTIME
) {
537 prepare_maxtime
= RS_DEFAULT_PREPARE_MAXTIME
;
540 /* Make sure we are not already updating. */
541 if(rupdate
.flags
& RS_UPDATING
) {
543 printf("RS: do_update: an update is already in progress\n");
547 /* A self update live updates a service instance into a replica, a regular
548 * update live updates a service instance into a new version, as specified
549 * by the given binary.
553 printf("RS: %s performs self update\n", srv_to_string(rp
));
555 /* Clone the system service and use the replica as the new version. */
556 s
= clone_service(rp
, LU_SYS_PROC
);
558 printf("RS: do_update: unable to clone service: %d\n", s
);
564 printf("RS: %s performs regular update\n", srv_to_string(rp
));
566 /* Allocate a system service slot for the new version. */
567 s
= alloc_slot(&new_rp
);
569 printf("RS: do_update: unable to allocate a new slot: %d\n", s
);
573 /* Initialize the slot as requested. */
574 s
= init_slot(new_rp
, &rs_start
, m_ptr
->m_source
);
576 printf("RS: do_update: unable to init the new slot: %d\n", s
);
580 /* Let the new version inherit defaults from the old one. */
581 inherit_service_defaults(rp
, new_rp
);
583 /* Link the two versions. */
584 rp
->r_new_rp
= new_rp
;
585 new_rp
->r_old_rp
= rp
;
587 /* Create new version of the service but don't let it run. */
588 new_rp
->r_priv
.s_flags
|= LU_SYS_PROC
;
589 s
= create_service(new_rp
);
591 printf("RS: do_update: unable to create a new service: %d\n", s
);
596 /* Mark both versions as updating. */
597 rp
->r_flags
|= RS_UPDATING
;
598 rp
->r_new_rp
->r_flags
|= RS_UPDATING
;
599 rupdate
.flags
|= RS_UPDATING
;
600 getuptime(&rupdate
.prepare_tm
);
601 rupdate
.prepare_maxtime
= prepare_maxtime
;
605 printf("RS: %s updating\n", srv_to_string(rp
));
607 /* If RS is updating, set up signal managers for the new instance.
608 * The current RS instance must be made the backup signal manager to
609 * support rollback in case of a crash during initialization.
611 if(rp
->r_priv
.s_flags
& ROOT_SYS_PROC
) {
612 new_rp
= rp
->r_new_rp
;
614 s
= update_sig_mgrs(new_rp
, SELF
, new_rp
->r_pub
->endpoint
);
616 cleanup_service(new_rp
);
622 /* Unblock the caller immediately if requested. */
624 reply(m_ptr
->m_source
, NULL
, m_ptr
);
627 /* Send a reply when the new version completes initialization. */
628 rp
->r_flags
|= RS_LATEREPLY
;
629 rp
->r_caller
= m_ptr
->m_source
;
630 rp
->r_caller_request
= RS_UPDATE
;
633 /* Request to update. */
634 m_ptr
->m_type
= RS_LU_PREPARE
;
635 if(rpub
->endpoint
== RS_PROC_NR
) {
636 /* RS can process the request directly. */
637 do_sef_lu_request(m_ptr
);
640 /* Send request message to the system service. */
641 asynsend3(rpub
->endpoint
, m_ptr
, AMF_NOREPLY
);
647 /*===========================================================================*
649 *===========================================================================*/
650 int do_upd_ready(message
*m_ptr
)
652 struct rproc
*rp
, *old_rp
, *new_rp
;
658 who_p
= _ENDPOINT_P(m_ptr
->m_source
);
659 rp
= rproc_ptr
[who_p
];
660 result
= m_ptr
->RS_LU_RESULT
;
661 is_rs
= (m_ptr
->m_source
== RS_PROC_NR
);
663 /* Make sure the originating service was requested to prepare for update. */
664 if(rp
!= rupdate
.rp
) {
666 printf("RS: do_upd_ready: got unexpected update ready msg from %d\n",
671 /* Check if something went wrong and the service failed to prepare
672 * for the update. In that case, end the update process. The old version will
673 * be replied to and continue executing.
676 end_update(result
, RS_REPLY
);
678 printf("RS: update failed: %s\n", lu_strerror(result
));
679 return is_rs
? result
: EDONTREPLY
; /* return what the caller expects */
683 new_rp
= rp
->r_new_rp
;
685 /* If RS itself is updating, yield control to the new version immediately. */
687 r
= init_service(new_rp
, SEF_INIT_LU
);
689 panic("unable to initialize the new RS instance: %d", r
);
691 r
= sys_privctl(new_rp
->r_pub
->endpoint
, SYS_PRIV_YIELD
, NULL
);
693 panic("unable to yield control to the new RS instance: %d", r
);
695 /* If we get this far, the new version failed to initialize. Rollback. */
696 r
= srv_update(RS_PROC_NR
, new_rp
->r_pub
->endpoint
);
697 assert(r
== OK
); /* can't fail */
698 end_update(ERESTART
, RS_REPLY
);
702 /* Perform the update. */
703 r
= update_service(&old_rp
, &new_rp
, RS_SWAP
);
705 end_update(r
, RS_REPLY
);
706 printf("RS: update failed: error %d\n", r
);
710 /* Let the new version run. */
711 r
= run_service(new_rp
, SEF_INIT_LU
);
713 /* Something went wrong. Rollback. */
714 r
= update_service(&new_rp
, &old_rp
, RS_SWAP
);
715 assert(r
== OK
); /* can't fail */
716 end_update(r
, RS_REPLY
);
717 printf("RS: update failed: error %d\n", r
);
724 /*===========================================================================*
726 *===========================================================================*/
727 void do_period(m_ptr
)
730 register struct rproc
*rp
;
731 register struct rprocpub
*rpub
;
732 clock_t now
= m_ptr
->NOTIFY_TIMESTAMP
;
736 /* If an update is in progress, check its status. */
737 if(rupdate
.flags
& RS_UPDATING
) {
738 update_period(m_ptr
);
741 /* Search system services table. Only check slots that are in use and not
744 for (rp
=BEG_RPROC_ADDR
; rp
<END_RPROC_ADDR
; rp
++) {
746 if ((rp
->r_flags
& RS_ACTIVE
) && !(rp
->r_flags
& RS_UPDATING
)) {
748 /* Compute period. */
749 period
= rp
->r_period
;
750 if(rp
->r_flags
& RS_INITIALIZING
) {
754 /* If the service is to be revived (because it repeatedly exited,
755 * and was not directly restarted), the binary backoff field is
758 if (rp
->r_backoff
> 0) {
760 if (rp
->r_backoff
== 0) {
765 /* If the service was signaled with a SIGTERM and fails to respond,
766 * kill the system service with a SIGKILL signal.
768 else if (rp
->r_stop_tm
> 0 && now
- rp
->r_stop_tm
> 2*RS_DELTA_T
771 crash_service(rp
); /* simulate crash */
774 /* There seems to be no special conditions. If the service has a
775 * period assigned check its status.
777 else if (period
> 0) {
779 /* Check if an answer to a status request is still pending. If
780 * the service didn't respond within time, kill it to simulate
781 * a crash. The failure will be detected and the service will
782 * be restarted automatically. Give the service a free pass if
783 * somebody is initializing. There may be some weird dependencies
784 * if another service is, for example, restarting at the same
787 if (rp
->r_alive_tm
< rp
->r_check_tm
) {
788 if (now
- rp
->r_alive_tm
> 2*period
&&
789 rp
->r_pid
> 0 && !(rp
->r_flags
& RS_NOPINGREPLY
)) {
791 printf("RS: %s reported late\n", srv_to_string(rp
));
792 if(lookup_slot_by_flags(RS_INITIALIZING
)) {
795 printf("RS: %s gets a free pass\n",
797 rp
->r_alive_tm
= now
;
798 rp
->r_check_tm
= now
+1;
801 rp
->r_flags
|= RS_NOPINGREPLY
;
802 crash_service(rp
); /* simulate crash */
806 /* No answer pending. Check if a period expired since the last
807 * check and, if so request the system service's status.
809 else if (now
- rp
->r_check_tm
> rp
->r_period
) {
810 notify(rpub
->endpoint
); /* request status */
811 rp
->r_check_tm
= now
; /* mark time */
817 /* Reschedule a synchronous alarm for the next period. */
818 if (OK
!= (s
=sys_setalarm(RS_DELTA_T
, 0)))
819 panic("couldn't set alarm: %d", s
);
822 /*===========================================================================*
824 *===========================================================================*/
827 /* PM informed us that there are dead children to cleanup. Go get them. */
835 printf("RS: got SIGCHLD signal, cleaning up dead children\n");
837 while ( (pid
= waitpid(-1, &status
, WNOHANG
)) != 0 ) {
838 rp
= lookup_slot_by_pid(pid
);
842 printf("RS: %s exited via another signal manager\n",
845 /* The slot is still there. This means RS is not the signal
846 * manager assigned to the process. Ignore the event but
847 * free slots for all the service instances and send a late
848 * reply if necessary.
850 get_service_instances(rp
, &rps
, &nr_rps
);
851 for(i
=0;i
<nr_rps
;i
++) {
852 if(rupdate
.flags
& RS_UPDATING
) {
853 rupdate
.flags
&= ~RS_UPDATING
;
861 /*===========================================================================*
863 *===========================================================================*/
864 int do_getsysinfo(m_ptr
)
867 vir_bytes src_addr
, dst_addr
;
872 /* Check if the call can be allowed. */
873 if((s
= check_call_permission(m_ptr
->m_source
, 0, NULL
)) != OK
)
876 switch(m_ptr
->SI_WHAT
) {
878 src_addr
= (vir_bytes
) rproc
;
879 len
= sizeof(struct rproc
) * NR_SYS_PROCS
;
882 src_addr
= (vir_bytes
) rprocpub
;
883 len
= sizeof(struct rprocpub
) * NR_SYS_PROCS
;
889 if (len
!= m_ptr
->SI_SIZE
)
892 dst_proc
= m_ptr
->m_source
;
893 dst_addr
= (vir_bytes
) m_ptr
->SI_WHERE
;
894 return sys_datacopy(SELF
, src_addr
, dst_proc
, dst_addr
, len
);
897 /*===========================================================================*
899 *===========================================================================*/
903 static char namebuf
[100];
906 struct rprocpub
*rrpub
;
908 len
= m_ptr
->RS_NAME_LEN
;
910 if(len
< 2 || len
>= sizeof(namebuf
)) {
911 printf("RS: len too weird (%d)\n", len
);
915 if((r
=sys_vircopy(m_ptr
->m_source
, (vir_bytes
) m_ptr
->RS_NAME
,
916 SELF
, (vir_bytes
) namebuf
, len
)) != OK
) {
917 printf("RS: name copy failed\n");
924 rrp
= lookup_slot_by_label(namebuf
);
929 m_ptr
->RS_ENDPOINT
= rrpub
->endpoint
;
934 /*===========================================================================*
936 *===========================================================================*/
937 static int check_request(struct rs_start
*rs_start
)
939 /* Verify scheduling parameters */
940 if (rs_start
->rss_scheduler
!= KERNEL
&&
941 (rs_start
->rss_scheduler
< 0 ||
942 rs_start
->rss_scheduler
> LAST_SPECIAL_PROC_NR
)) {
943 printf("RS: check_request: invalid scheduler %d\n",
944 rs_start
->rss_scheduler
);
947 if (rs_start
->rss_priority
>= NR_SCHED_QUEUES
) {
948 printf("RS: check_request: priority %u out of range\n",
949 rs_start
->rss_priority
);
952 if (rs_start
->rss_quantum
<= 0) {
953 printf("RS: check_request: quantum %u out of range\n",
954 rs_start
->rss_quantum
);
958 if (rs_start
->rss_cpu
== RS_CPU_BSP
)
959 rs_start
->rss_cpu
= machine
.bsp_id
;
960 else if (rs_start
->rss_cpu
== RS_CPU_DEFAULT
) {
961 /* keep the default value */
962 } else if (rs_start
->rss_cpu
< 0)
964 else if (rs_start
->rss_cpu
> machine
.processors_count
) {
965 printf("RS: cpu number %d out of range 0-%d, using BSP\n",
966 rs_start
->rss_cpu
, machine
.processors_count
);
967 rs_start
->rss_cpu
= machine
.bsp_id
;
970 /* Verify signal manager. */
971 if (rs_start
->rss_sigmgr
!= SELF
&&
972 (rs_start
->rss_sigmgr
< 0 ||
973 rs_start
->rss_sigmgr
> LAST_SPECIAL_PROC_NR
)) {
974 printf("RS: check_request: invalid signal manager %d\n",
975 rs_start
->rss_sigmgr
);