secondary cache feature in vm.
[minix.git] / lib / libsys / sef_liveupdate.c
blobcf2a312def24cc5037cf1f30bf61019a9f4503c5
1 #include "syslib.h"
2 #include <assert.h>
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;
15 } sef_cbs = {
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) );
30 /* Debug. */
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. */
40 int r;
42 /* Nothing to do if we are not preparing for a live update. */
43 if(sef_lu_state == SEF_LU_STATE_NULL) {
44 return;
47 /* Debug. */
48 #if SEF_LU_DEBUG
49 sef_lu_debug_cycle++;
50 sef_lu_debug_begin();
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);
54 sef_lu_debug_end();
55 #endif
57 /* Let the callback code handle the event.
58 * For SEF_LU_STATE_WORK_FREE, we're always ready, tell immediately.
60 r = OK;
61 if(sef_lu_state != SEF_LU_STATE_WORK_FREE) {
62 r = sef_cbs.sef_cb_lu_prepare(sef_lu_state);
64 if(r == OK) {
65 sef_lu_ready(OK);
69 /*===========================================================================*
70 * do_sef_lu_request *
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);
86 if(!is_valid_state) {
87 if(sef_cbs.sef_cb_lu_state_isvalid == SEF_CB_LU_STATE_ISVALID_NULL) {
88 sef_lu_ready(ENOSYS);
90 else {
91 sef_lu_ready(EINVAL);
94 else {
95 /* Set the new live update state. */
96 sef_lu_state = state;
98 /* If the live update state changed, let the callback code
99 * handle the rest.
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. */
107 return(OK);
110 /*===========================================================================*
111 * sef_lu_ready *
112 *===========================================================================*/
113 PRIVATE void sef_lu_ready(int result)
115 message m;
116 int old_state, rs_result, r;
118 #if SEF_LU_DEBUG
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)" : ""));
123 sef_lu_debug_end();
124 #endif
126 /* If result is OK, let the callback code save
127 * any state that must be carried over to the new version.
129 if(result == OK) {
130 r = sef_cbs.sef_cb_lu_state_save(sef_lu_state);
131 if(r != OK) {
132 /* Abort update if callback returned error. */
133 result = r;
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);
142 if ( r != OK) {
143 panic("sendrec failed: %d", r);
146 #if SEF_LU_DEBUG
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. */
153 sef_lu_debug_end();
154 #endif
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)
171 assert(cb != NULL);
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)
180 assert(cb != NULL);
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)
189 assert(cb != NULL);
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)
198 assert(cb != NULL);
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)
207 assert(cb != NULL);
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))
216 return ENOTREADY;
219 /*===========================================================================*
220 * sef_cb_lu_state_isvalid_null *
221 *===========================================================================*/
222 PUBLIC int sef_cb_lu_state_isvalid_null(int UNUSED(state))
224 return FALSE;
227 /*===========================================================================*
228 * sef_cb_lu_state_changed_null *
229 *===========================================================================*/
230 PUBLIC void sef_cb_lu_state_changed_null(int UNUSED(old_state),
231 int UNUSED(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))
248 return OK;
251 /*===========================================================================*
252 * sef_cb_lu_prepare_always_ready *
253 *===========================================================================*/
254 PUBLIC int sef_cb_lu_prepare_always_ready(int UNUSED(state))
256 return OK;
259 /*===========================================================================*
260 * sef_cb_lu_prepare_never_ready *
261 *===========================================================================*/
262 PUBLIC int sef_cb_lu_prepare_never_ready(int UNUSED(state))
264 #if SEF_LU_DEBUG
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);
268 sef_lu_debug_end();
269 #endif
271 return ENOTREADY;
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...");
281 return OK;
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);