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
;
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. */
31 EXTERN
int do_sef_gcov_request(message
*m_ptr
);
33 EXTERN
int do_sef_rs_init(endpoint_t old_endpoint
);
34 EXTERN
int do_sef_init_request(message
*m_ptr
);
36 /* SEF Ping prototypes. */
37 EXTERN
int do_sef_ping_request(message
*m_ptr
);
39 /* SEF Live update prototypes. */
40 EXTERN
void do_sef_lu_before_receive(void);
41 EXTERN
int do_sef_lu_request(message
*m_ptr
);
43 /* SEF Signal prototypes. */
44 EXTERN
int do_sef_signal_request(message
*m_ptr
);
46 /*===========================================================================*
48 *===========================================================================*/
51 /* SEF startup interface for system services. */
53 endpoint_t old_endpoint
;
56 /* Get information about self. */
57 r
= sys_whoami(&sef_self_endpoint
, sef_self_name
, SEF_SELF_NAME_MAXLEN
,
60 sef_self_endpoint
= SELF
;
61 strlcpy(sef_self_name
, "Unknown", sizeof(sef_self_name
));
63 sef_self_priv_flags
= priv_flags
;
67 /* RS may wake up with the wrong endpoint, perfom the update in that case. */
68 if((sef_self_priv_flags
& ROOT_SYS_PROC
) && sef_self_endpoint
!= RS_PROC_NR
) {
69 r
= vm_update(RS_PROC_NR
, sef_self_endpoint
);
71 panic("unable to update RS from instance %d to %d",
72 RS_PROC_NR
, sef_self_endpoint
);
74 old_endpoint
= sef_self_endpoint
;
75 sef_self_endpoint
= RS_PROC_NR
;
77 #endif /* USE_LIVEUPDATE */
79 #if INTERCEPT_SEF_INIT_REQUESTS
80 /* Intercept SEF Init requests. */
81 if(sef_self_priv_flags
& ROOT_SYS_PROC
) {
82 /* RS initialization is special. */
83 if((r
= do_sef_rs_init(old_endpoint
)) != OK
) {
84 panic("RS unable to complete init: %d", r
);
87 else if(sef_self_endpoint
== VM_PROC_NR
) {
88 /* VM handles initialization by RS later */
92 /* Wait for an initialization message from RS. We need this to learn the
93 * initialization type and parameters. When restarting after a crash, we
94 * may get some spurious IPC messages from RS (e.g. update request) that
95 * were originally meant to be delivered to the old instance. We discard
96 * these messages and block till a proper initialization request arrives.
99 r
= receive(RS_PROC_NR
, &m
, &status
);
101 panic("unable to receive from RS: %d", r
);
103 } while(!IS_SEF_INIT_REQUEST(&m
));
105 /* Process initialization request for this system service. */
106 if((r
= do_sef_init_request(&m
)) != OK
) {
107 panic("unable to process init request: %d", r
);
112 /* (Re)initialize SEF variables. */
113 sef_self_first_receive_done
= FALSE
;
114 sef_self_priv_flags
= priv_flags
;
117 /*===========================================================================*
118 * sef_receive_status *
119 *===========================================================================*/
120 int sef_receive_status(endpoint_t src
, message
*m_ptr
, int *status_ptr
)
122 /* SEF receive() interface for system services. */
125 sef_self_receiving
= TRUE
;
128 /* If the caller indicated that it no longer wants to receive a message,
131 if (!sef_self_receiving
)
134 #if INTERCEPT_SEF_LU_REQUESTS
135 /* Handle SEF Live update before receive events. */
136 do_sef_lu_before_receive();
139 /* Receive and return in case of error. */
140 r
= receive(src
, m_ptr
, &status
);
141 if(status_ptr
) *status_ptr
= status
;
142 if(!sef_self_first_receive_done
) sef_self_first_receive_done
= TRUE
;
147 #if INTERCEPT_SEF_PING_REQUESTS
148 /* Intercept SEF Ping requests. */
149 if(IS_SEF_PING_REQUEST(m_ptr
, status
)) {
150 if(do_sef_ping_request(m_ptr
) == OK
) {
156 #if INTERCEPT_SEF_LU_REQUESTS
157 /* Intercept SEF Live update requests. */
158 if(IS_SEF_LU_REQUEST(m_ptr
, status
)) {
159 if(do_sef_lu_request(m_ptr
) == OK
) {
165 #if INTERCEPT_SEF_SIGNAL_REQUESTS
166 /* Intercept SEF Signal requests. */
167 if(IS_SEF_SIGNAL_REQUEST(m_ptr
, status
)) {
168 if(do_sef_signal_request(m_ptr
) == OK
) {
175 /* Intercept GCOV data requests (sent by VFS in vfs/gcov.c). */
176 if(m_ptr
->m_type
== COMMON_REQ_GCOV_DATA
&&
177 m_ptr
->m_source
== VFS_PROC_NR
) {
178 if(do_sef_gcov_request(m_ptr
) == OK
) {
184 /* If we get this far, this is not a valid SEF request, return and
185 * let the caller deal with that.
193 /*===========================================================================*
195 *===========================================================================*/
196 void sef_cancel(void)
198 /* Cancel receiving a message. This function be called from a callback invoked
199 * from within sef_receive_status(), which will then return an EINTR error
200 * code. In particular, this function can be used to exit from the main receive
201 * loop when a signal handler causes the process to want to shut down.
204 sef_self_receiving
= FALSE
;
207 /*===========================================================================*
209 *===========================================================================*/
210 void sef_exit(int status
)
212 /* System services use a special version of exit() that generates a
213 * self-termination signal.
217 /* Ask the kernel to exit. */
220 /* If sys_exit() fails, this is not a system service. Exit through PM. */
222 _syscall(PM_PROC_NR
, EXIT
, &m
);
224 /* If everything else fails, hang. */
225 printf("Warning: system service %d couldn't exit\n", sef_self_endpoint
);
229 /*===========================================================================*
231 *===========================================================================*/
232 void _exit(int status
)
234 /* Make exit() an alias for sef_exit() for system services. */
236 panic("sef_exit failed");
239 /*===========================================================================*
241 *===========================================================================*/
242 void __exit(int status
)
244 /* Make exit() an alias for sef_exit() for system services. */
246 panic("sef_exit failed");
249 #if SEF_INIT_DEBUG || SEF_LU_DEBUG || SEF_PING_DEBUG || SEF_SIGNAL_DEBUG
250 /*===========================================================================*
251 * sef_debug_refresh_params *
252 *===========================================================================*/
253 static void sef_debug_refresh_params(void)
255 /* Refresh SEF debug params. */
259 /* Get boottime the first time. */
260 if(!sef_debug_boottime
) {
261 r
= sys_times(NONE
, NULL
, NULL
, NULL
, &sef_debug_boottime
);
263 sef_debug_boottime
= -1;
267 /* Get system hz the first time. */
268 if(!sef_debug_system_hz
) {
269 r
= sys_getinfo(GET_HZ
, &sef_debug_system_hz
,
270 sizeof(sef_debug_system_hz
), 0, 0);
272 sef_debug_system_hz
= -1;
278 if(sef_debug_boottime
!=-1 && sef_debug_system_hz
!=-1) {
279 r
= sys_times(NONE
, NULL
, NULL
, &uptime
, NULL
);
285 /* Compute current time. */
286 if(sef_debug_boottime
==-1 || sef_debug_system_hz
==-1 || uptime
==-1) {
287 sef_debug_time_sec
= 0;
288 sef_debug_time_us
= 0;
291 sef_debug_time_sec
= (time_t) (sef_debug_boottime
292 + (uptime
/sef_debug_system_hz
));
293 sef_debug_time_us
= (uptime
%sef_debug_system_hz
)
294 * 1000000/sef_debug_system_hz
;
298 /*===========================================================================*
300 *===========================================================================*/
301 char* sef_debug_header(void)
303 /* Build and return a SEF debug header. */
304 sef_debug_refresh_params();
305 snprintf(sef_debug_header_buff
, sizeof(sef_debug_header_buff
),
306 "%s: time = %ds %06dus", sef_self_name
, (int) sef_debug_time_sec
,
307 (int) sef_debug_time_us
);
309 return sef_debug_header_buff
;
311 #endif /*SEF_INIT_DEBUG || SEF_LU_DEBUG || SEF_PING_DEBUG || SEF_SIGNAL_DEBUG*/