3 #include <minix/sysutil.h>
10 #define SEF_SELF_NAME_MAXLEN 20
11 char sef_self_name
[SEF_SELF_NAME_MAXLEN
];
12 endpoint_t sef_self_endpoint
= NONE
;
13 int sef_self_priv_flags
;
14 int sef_self_first_receive_done
;
15 int sef_self_receiving
;
18 #if SEF_INIT_DEBUG || SEF_LU_DEBUG || SEF_PING_DEBUG || SEF_SIGNAL_DEBUG
19 #define SEF_DEBUG_HEADER_MAXLEN 32
20 static time_t sef_debug_boottime
= 0;
21 static u32_t sef_debug_system_hz
= 0;
22 static time_t sef_debug_time_sec
= 0;
23 static time_t sef_debug_time_us
= 0;
24 static char sef_debug_header_buff
[SEF_DEBUG_HEADER_MAXLEN
];
25 static void sef_debug_refresh_params(void);
26 char* sef_debug_header(void);
29 /* SEF Init prototypes. */
30 EXTERN
int do_sef_rs_init(endpoint_t old_endpoint
);
31 EXTERN
int do_sef_init_request(message
*m_ptr
);
33 /* SEF Ping prototypes. */
34 EXTERN
int do_sef_ping_request(message
*m_ptr
);
36 /* SEF Live update prototypes. */
37 EXTERN
void do_sef_lu_before_receive(void);
38 EXTERN
int do_sef_lu_request(message
*m_ptr
);
40 /* SEF Signal prototypes. */
41 EXTERN
int do_sef_signal_request(message
*m_ptr
);
43 /* SEF GCOV prototypes. */
45 EXTERN
int do_sef_gcov_request(message
*m_ptr
);
48 /* SEF Fault Injection prototypes. */
49 EXTERN
int do_sef_fi_request(message
*m_ptr
);
51 /*===========================================================================*
53 *===========================================================================*/
56 /* SEF startup interface for system services. */
58 endpoint_t old_endpoint
;
61 /* Get information about self. */
62 r
= sys_whoami(&sef_self_endpoint
, sef_self_name
, SEF_SELF_NAME_MAXLEN
,
65 sef_self_endpoint
= SELF
;
66 strlcpy(sef_self_name
, "Unknown", sizeof(sef_self_name
));
68 sef_self_priv_flags
= priv_flags
;
72 /* RS may wake up with the wrong endpoint, perfom the update in that case. */
73 if((sef_self_priv_flags
& ROOT_SYS_PROC
) && sef_self_endpoint
!= RS_PROC_NR
) {
74 r
= vm_update(RS_PROC_NR
, sef_self_endpoint
);
76 panic("unable to update RS from instance %d to %d: %d",
77 RS_PROC_NR
, sef_self_endpoint
, r
);
79 old_endpoint
= sef_self_endpoint
;
80 sef_self_endpoint
= RS_PROC_NR
;
82 #endif /* USE_LIVEUPDATE */
84 #if INTERCEPT_SEF_INIT_REQUESTS
85 /* Intercept SEF Init requests. */
86 if(sef_self_priv_flags
& ROOT_SYS_PROC
) {
87 /* RS initialization is special. */
88 if((r
= do_sef_rs_init(old_endpoint
)) != OK
) {
89 panic("RS unable to complete init: %d", r
);
92 else if(sef_self_endpoint
== VM_PROC_NR
) {
93 /* VM handles initialization by RS later */
97 /* Wait for an initialization message from RS. We need this to learn the
98 * initialization type and parameters. When restarting after a crash, we
99 * may get some spurious IPC messages from RS (e.g. update request) that
100 * were originally meant to be delivered to the old instance. We discard
101 * these messages and block till a proper initialization request arrives.
104 r
= ipc_receive(RS_PROC_NR
, &m
, &status
);
106 panic("unable to ipc_receive from RS: %d", r
);
108 } while(!IS_SEF_INIT_REQUEST(&m
));
110 /* Process initialization request for this system service. */
111 if((r
= do_sef_init_request(&m
)) != OK
) {
112 panic("unable to process init request: %d", r
);
117 /* (Re)initialize SEF variables. */
118 sef_self_first_receive_done
= FALSE
;
119 sef_self_priv_flags
= priv_flags
;
122 /*===========================================================================*
123 * sef_receive_status *
124 *===========================================================================*/
125 int sef_receive_status(endpoint_t src
, message
*m_ptr
, int *status_ptr
)
127 /* SEF receive() interface for system services. */
130 sef_self_receiving
= TRUE
;
133 /* If the caller indicated that it no longer wants to receive a message,
136 if (!sef_self_receiving
)
139 #if INTERCEPT_SEF_LU_REQUESTS
140 /* Handle SEF Live update before receive events. */
141 do_sef_lu_before_receive();
144 /* Receive and return in case of error. */
145 r
= ipc_receive(src
, m_ptr
, &status
);
146 if(status_ptr
) *status_ptr
= status
;
147 if(!sef_self_first_receive_done
) sef_self_first_receive_done
= TRUE
;
152 #if INTERCEPT_SEF_PING_REQUESTS
153 /* Intercept SEF Ping requests. */
154 if(IS_SEF_PING_REQUEST(m_ptr
, status
)) {
155 if(do_sef_ping_request(m_ptr
) == OK
) {
161 #if INTERCEPT_SEF_LU_REQUESTS
162 /* Intercept SEF Live update requests. */
163 if(IS_SEF_LU_REQUEST(m_ptr
, status
)) {
164 if(do_sef_lu_request(m_ptr
) == OK
) {
170 #if INTERCEPT_SEF_SIGNAL_REQUESTS
171 /* Intercept SEF Signal requests. */
172 if(IS_SEF_SIGNAL_REQUEST(m_ptr
, status
)) {
173 if(do_sef_signal_request(m_ptr
) == OK
) {
180 /* Intercept GCOV data requests (sent by VFS in vfs/gcov.c). */
181 if(m_ptr
->m_type
== COMMON_REQ_GCOV_DATA
&&
182 m_ptr
->m_source
== VFS_PROC_NR
) {
183 if(do_sef_gcov_request(m_ptr
) == OK
) {
189 #ifdef INTERCEPT_SEF_FI_REQUESTS
190 /* Intercept Fault injection requests. */
191 if(IS_SEF_FI_REQUEST(m_ptr
, status
)) {
192 if(do_sef_fi_request(m_ptr
) == OK
) {
198 /* If we get this far, this is not a valid SEF request, return and
199 * let the caller deal with that.
207 /*===========================================================================*
209 *===========================================================================*/
210 endpoint_t
sef_self(void)
212 /* Return the process's own endpoint number. */
214 if (sef_self_endpoint
== NONE
)
215 panic("sef_self called before initialization");
217 return sef_self_endpoint
;
220 /*===========================================================================*
222 *===========================================================================*/
223 void sef_cancel(void)
225 /* Cancel receiving a message. This function be called from a callback invoked
226 * from within sef_receive_status(), which will then return an EINTR error
227 * code. In particular, this function can be used to exit from the main receive
228 * loop when a signal handler causes the process to want to shut down.
231 sef_self_receiving
= FALSE
;
234 /*===========================================================================*
236 *===========================================================================*/
237 void sef_exit(int status
)
239 /* System services use a special version of exit() that generates a
240 * self-termination signal.
244 /* Ask the kernel to exit. */
247 /* If everything else fails, hang. */
248 printf("Warning: system service %d couldn't exit\n", sef_self_endpoint
);
253 __weak_alias(_exit
, sef_exit
);
254 __weak_alias(__exit
, sef_exit
);
257 #if SEF_INIT_DEBUG || SEF_LU_DEBUG || SEF_PING_DEBUG || SEF_SIGNAL_DEBUG
258 /*===========================================================================*
259 * sef_debug_refresh_params *
260 *===========================================================================*/
261 static void sef_debug_refresh_params(void)
263 /* Refresh SEF debug params. */
267 /* Get boottime the first time. */
268 if(!sef_debug_boottime
) {
269 r
= sys_times(NONE
, NULL
, NULL
, NULL
, &sef_debug_boottime
);
271 sef_debug_boottime
= -1;
275 /* Get system hz the first time. */
276 if(!sef_debug_system_hz
) {
277 r
= sys_getinfo(GET_HZ
, &sef_debug_system_hz
,
278 sizeof(sef_debug_system_hz
), 0, 0);
280 sef_debug_system_hz
= -1;
286 if(sef_debug_boottime
!=-1 && sef_debug_system_hz
!=-1) {
287 r
= sys_times(NONE
, NULL
, NULL
, &uptime
, NULL
);
293 /* Compute current time. */
294 if(sef_debug_boottime
==-1 || sef_debug_system_hz
==-1 || uptime
==-1) {
295 sef_debug_time_sec
= 0;
296 sef_debug_time_us
= 0;
299 sef_debug_time_sec
= (time_t) (sef_debug_boottime
300 + (uptime
/sef_debug_system_hz
));
301 sef_debug_time_us
= (uptime
%sef_debug_system_hz
)
302 * 1000000/sef_debug_system_hz
;
306 /*===========================================================================*
308 *===========================================================================*/
309 char* sef_debug_header(void)
311 /* Build and return a SEF debug header. */
312 sef_debug_refresh_params();
313 snprintf(sef_debug_header_buff
, sizeof(sef_debug_header_buff
),
314 "%s: time = %ds %06dus", sef_self_name
, (int) sef_debug_time_sec
,
315 (int) sef_debug_time_us
);
317 return sef_debug_header_buff
;
319 #endif /*SEF_INIT_DEBUG || SEF_LU_DEBUG || SEF_PING_DEBUG || SEF_SIGNAL_DEBUG*/