3 #include <minix/sysutil.h>
5 /* SEF Live update variables. */
6 PRIVATE
int sef_lu_state
= SEF_LU_STATE_NULL
;
8 /* SEF Live update callbacks. */
9 PRIVATE
struct sef_cbs
{
10 sef_cb_lu_prepare_t sef_cb_lu_prepare
;
11 sef_cb_lu_state_isvalid_t sef_cb_lu_state_isvalid
;
12 sef_cb_lu_state_changed_t sef_cb_lu_state_changed
;
13 sef_cb_lu_state_dump_t sef_cb_lu_state_dump
;
14 sef_cb_lu_state_save_t sef_cb_lu_state_save
;
16 SEF_CB_LU_PREPARE_DEFAULT
,
17 SEF_CB_LU_STATE_ISVALID_DEFAULT
,
18 SEF_CB_LU_STATE_CHANGED_DEFAULT
,
19 SEF_CB_LU_STATE_DUMP_DEFAULT
,
20 SEF_CB_LU_STATE_SAVE_DEFAULT
,
23 /* SEF Live update prototypes for sef_receive(). */
24 PUBLIC
_PROTOTYPE( void do_sef_lu_before_receive
, (void) );
25 PUBLIC
_PROTOTYPE( int do_sef_lu_request
, (message
*m_ptr
) );
27 /* SEF Live update helpers. */
28 PRIVATE
_PROTOTYPE( void sef_lu_ready
, (int result
) );
31 EXTERN
_PROTOTYPE( char* sef_debug_header
, (void) );
32 PRIVATE
int sef_lu_debug_cycle
= 0;
34 /*===========================================================================*
35 * do_sef_lu_before_receive *
36 *===========================================================================*/
37 PUBLIC
void do_sef_lu_before_receive()
39 /* Handle SEF Live update before receive events. */
42 /* Nothing to do if we are not preparing for a live update. */
43 if(sef_lu_state
== SEF_LU_STATE_NULL
) {
51 sef_lu_dprint("%s, cycle=%d. Dumping state variables:\n",
52 sef_debug_header(), sef_lu_debug_cycle
);
53 sef_cbs
.sef_cb_lu_state_dump(sef_lu_state
);
57 /* Let the callback code handle the event.
58 * For SEF_LU_STATE_WORK_FREE, we're always ready, tell immediately.
61 if(sef_lu_state
!= SEF_LU_STATE_WORK_FREE
) {
62 r
= sef_cbs
.sef_cb_lu_prepare(sef_lu_state
);
69 /*===========================================================================*
71 *===========================================================================*/
72 PUBLIC
int do_sef_lu_request(message
*m_ptr
)
74 /* Handle a SEF Live update request. */
75 int state
, old_state
, is_valid_state
;
77 sef_lu_debug_cycle
= 0;
78 old_state
= sef_lu_state
;
79 state
= m_ptr
->RS_LU_STATE
;
81 /* Deal with prepare cancel requests first. */
82 is_valid_state
= (state
== SEF_LU_STATE_NULL
);
84 /* Otherwise only accept live update requests with a valid state. */
85 is_valid_state
= is_valid_state
|| sef_cbs
.sef_cb_lu_state_isvalid(state
);
87 if(sef_cbs
.sef_cb_lu_state_isvalid
== SEF_CB_LU_STATE_ISVALID_NULL
) {
95 /* Set the new live update state. */
98 /* If the live update state changed, let the callback code
101 if(old_state
!= sef_lu_state
) {
102 sef_cbs
.sef_cb_lu_state_changed(old_state
, sef_lu_state
);
106 /* Return OK not to let anybody else intercept the request. */
110 /*===========================================================================*
112 *===========================================================================*/
113 PRIVATE
void sef_lu_ready(int result
)
116 int old_state
, rs_result
, r
;
119 sef_lu_debug_begin();
120 sef_lu_dprint("%s, cycle=%d. Ready to update with result: %d%s\n",
121 sef_debug_header(), sef_lu_debug_cycle
,
122 result
, (result
== OK
? "(OK)" : ""));
126 /* If result is OK, let the callback code save
127 * any state that must be carried over to the new version.
130 r
= sef_cbs
.sef_cb_lu_state_save(sef_lu_state
);
132 /* Abort update if callback returned error. */
137 /* Inform RS that we're ready with the given result. */
138 m
.m_type
= RS_LU_PREPARE
;
139 m
.RS_LU_STATE
= sef_lu_state
;
140 m
.RS_LU_RESULT
= result
;
141 r
= sendrec(RS_PROC_NR
, &m
);
143 panic("sendrec failed: %d", r
);
147 rs_result
= m
.m_type
== RS_LU_PREPARE
? EINTR
: m
.m_type
;
148 sef_lu_debug_begin();
149 sef_lu_dprint("%s, cycle=%d. The %s aborted the update with result %d!\n",
150 sef_debug_header(), sef_lu_debug_cycle
,
151 (result
== OK
? "server" : "client"),
152 (result
== OK
? rs_result
: result
)); /* EINTR if update was canceled. */
156 /* Something went wrong. Update was aborted and we didn't get updated.
157 * Restore things back to normal and continue executing.
159 old_state
= sef_lu_state
;
160 sef_lu_state
= SEF_LU_STATE_NULL
;
161 if(old_state
!= sef_lu_state
) {
162 sef_cbs
.sef_cb_lu_state_changed(old_state
, sef_lu_state
);
166 /*===========================================================================*
167 * sef_setcb_lu_prepare *
168 *===========================================================================*/
169 PUBLIC
void sef_setcb_lu_prepare(sef_cb_lu_prepare_t cb
)
172 sef_cbs
.sef_cb_lu_prepare
= cb
;
175 /*===========================================================================*
176 * sef_setcb_lu_state_isvalid *
177 *===========================================================================*/
178 PUBLIC
void sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_t cb
)
181 sef_cbs
.sef_cb_lu_state_isvalid
= cb
;
184 /*===========================================================================*
185 * sef_setcb_lu_state_changed *
186 *===========================================================================*/
187 PUBLIC
void sef_setcb_lu_state_changed(sef_cb_lu_state_changed_t cb
)
190 sef_cbs
.sef_cb_lu_state_changed
= cb
;
193 /*===========================================================================*
194 * sef_setcb_lu_state_dump *
195 *===========================================================================*/
196 PUBLIC
void sef_setcb_lu_state_dump(sef_cb_lu_state_dump_t cb
)
199 sef_cbs
.sef_cb_lu_state_dump
= cb
;
202 /*===========================================================================*
203 * sef_setcb_lu_state_save *
204 *===========================================================================*/
205 PUBLIC
void sef_setcb_lu_state_save(sef_cb_lu_state_save_t cb
)
208 sef_cbs
.sef_cb_lu_state_save
= cb
;
211 /*===========================================================================*
212 * sef_cb_lu_prepare_null *
213 *===========================================================================*/
214 PUBLIC
int sef_cb_lu_prepare_null(int UNUSED(state
))
219 /*===========================================================================*
220 * sef_cb_lu_state_isvalid_null *
221 *===========================================================================*/
222 PUBLIC
int sef_cb_lu_state_isvalid_null(int UNUSED(state
))
227 /*===========================================================================*
228 * sef_cb_lu_state_changed_null *
229 *===========================================================================*/
230 PUBLIC
void sef_cb_lu_state_changed_null(int UNUSED(old_state
),
235 /*===========================================================================*
236 * sef_cb_lu_state_dump_null *
237 *===========================================================================*/
238 PUBLIC
void sef_cb_lu_state_dump_null(int UNUSED(state
))
240 sef_lu_dprint("NULL\n");
243 /*===========================================================================*
244 * sef_cb_lu_state_save_null *
245 *===========================================================================*/
246 PUBLIC
int sef_cb_lu_state_save_null(int UNUSED(result
))
251 /*===========================================================================*
252 * sef_cb_lu_prepare_always_ready *
253 *===========================================================================*/
254 PUBLIC
int sef_cb_lu_prepare_always_ready(int UNUSED(state
))
259 /*===========================================================================*
260 * sef_cb_lu_prepare_never_ready *
261 *===========================================================================*/
262 PUBLIC
int sef_cb_lu_prepare_never_ready(int UNUSED(state
))
265 sef_lu_debug_begin();
266 sef_lu_dprint("%s, cycle=%d. Simulating a service never ready to update...\n",
267 sef_debug_header(), sef_lu_debug_cycle
);
274 /*===========================================================================*
275 * sef_cb_lu_prepare_crash *
276 *===========================================================================*/
277 PUBLIC
int sef_cb_lu_prepare_crash(int UNUSED(state
))
279 panic("Simulating a crash at update prepare time...");
284 /*===========================================================================*
285 * sef_cb_lu_state_isvalid_standard *
286 *===========================================================================*/
287 PUBLIC
int sef_cb_lu_state_isvalid_standard(int state
)
289 return SEF_LU_STATE_IS_STANDARD(state
);
292 /*===========================================================================*
293 * sef_cb_lu_state_isvalid_workfree *
294 *===========================================================================*/
295 PUBLIC
int sef_cb_lu_state_isvalid_workfree(int state
)
297 return (state
== SEF_LU_STATE_WORK_FREE
);