From: Cristiano Giuffrida Date: Sat, 1 Mar 2014 22:48:16 +0000 (+0100) Subject: libsys: Change SEF Live Update state callback API. X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=refs%2Fchanges%2F85%2F3085%2F2;p=minix.git libsys: Change SEF Live Update state callback API. The following callbacks are concerned: - state_save - state_isvalid Change-Id: I75f71fe162ccd8b23b18cae15f844b79b290a8c1 --- diff --git a/minix/drivers/bus/i2c/i2c.c b/minix/drivers/bus/i2c/i2c.c index be1888547..4e753890e 100644 --- a/minix/drivers/bus/i2c/i2c.c +++ b/minix/drivers/bus/i2c/i2c.c @@ -43,12 +43,6 @@ static int i2c_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt, cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id); static void i2c_other(message * m, int ipc_status); -/* SEF callbacks and driver state management */ -static int sef_cb_lu_state_save(int); -static int lu_state_restore(void); -static int sef_cb_init(int type, sef_init_info_t * info); -static void sef_local_startup(void); - /* Globals */ /* the bus that this instance of the driver is responsible for */ @@ -82,6 +76,25 @@ static struct chardriver i2c_tab = { .cdr_other = i2c_other }; +static int +sef_cb_lu_state_save(int UNUSED(result), int UNUSED(flags)) +{ + int r; + char key[DS_MAX_KEYLEN]; + + memset(key, '\0', DS_MAX_KEYLEN); + snprintf(key, DS_MAX_KEYLEN, "i2c.%d.i2cdev", i2c_bus_id + 1); + r = ds_publish_mem(key, i2cdev, sizeof(i2cdev), DSF_OVERWRITE); + if (r != OK) { + log_warn(&log, "ds_publish_mem(%s) failed (r=%d)\n", key, r); + return r; + } + + log_debug(&log, "State Saved\n"); + + return OK; +} + /* * Claim an unclaimed device for exclusive use by endpt. This function can * also be used to update the endpt if the endpt's label matches the label @@ -126,7 +139,7 @@ do_reserve(endpoint_t endpt, int slave_addr) i2cdev[slave_addr].endpt = endpt; memcpy(i2cdev[slave_addr].key, key, DS_MAX_KEYLEN); - sef_cb_lu_state_save(0); /* save reservations */ + sef_cb_lu_state_save(0, 0); /* save reservations */ log_debug(&log, "Device 0x%x claimed by 0x%x key='%s'\n", slave_addr, endpt, key); @@ -380,25 +393,6 @@ ds_event(void) } } -static int -sef_cb_lu_state_save(int UNUSED(state)) -{ - int r; - char key[DS_MAX_KEYLEN]; - - memset(key, '\0', DS_MAX_KEYLEN); - snprintf(key, DS_MAX_KEYLEN, "i2c.%d.i2cdev", i2c_bus_id + 1); - r = ds_publish_mem(key, i2cdev, sizeof(i2cdev), DSF_OVERWRITE); - if (r != OK) { - log_warn(&log, "ds_publish_mem(%s) failed (r=%d)\n", key, r); - return r; - } - - log_debug(&log, "State Saved\n"); - - return OK; -} - static int lu_state_restore(void) { @@ -465,7 +459,7 @@ sef_cb_init(int type, sef_init_info_t * UNUSED(info)) } /* Save state */ - sef_cb_lu_state_save(0); + sef_cb_lu_state_save(0, 0); /* Initialization completed successfully. */ return OK; diff --git a/minix/drivers/eeprom/cat24c256/cat24c256.c b/minix/drivers/eeprom/cat24c256/cat24c256.c index 7a02cbdab..94fd45f72 100644 --- a/minix/drivers/eeprom/cat24c256/cat24c256.c +++ b/minix/drivers/eeprom/cat24c256/cat24c256.c @@ -22,12 +22,6 @@ static i2c_addr_t valid_addrs[9] = { 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x00 }; -/* SEF functions and variables. */ -static void sef_local_startup(void); -static int sef_cb_init(int type, sef_init_info_t * info); -static int sef_cb_lu_state_save(int); -static int lu_state_restore(void); - /* libblockdriver callbacks */ static int cat24c256_blk_open(devminor_t minor, int access); static int cat24c256_blk_close(devminor_t minor); @@ -396,7 +390,7 @@ cat24c256_write(uint16_t memaddr, void *buf, size_t buflen, int flags) } static int -sef_cb_lu_state_save(int UNUSED(state)) +sef_cb_lu_state_save(int UNUSED(result), int UNUSED(flags)) { ds_publish_u32("bus", bus, DSF_OVERWRITE); ds_publish_u32("address", address, DSF_OVERWRITE); diff --git a/minix/drivers/examples/hello/hello.c b/minix/drivers/examples/hello/hello.c index 791e20e0b..6683a0e5e 100644 --- a/minix/drivers/examples/hello/hello.c +++ b/minix/drivers/examples/hello/hello.c @@ -16,7 +16,7 @@ static ssize_t hello_read(devminor_t minor, u64_t position, endpoint_t endpt, /* SEF functions and variables. */ static void sef_local_startup(void); static int sef_cb_init(int type, sef_init_info_t *info); -static int sef_cb_lu_state_save(int); +static int sef_cb_lu_state_save(int, int); static int lu_state_restore(void); /* Entry points to the hello driver. */ @@ -73,7 +73,7 @@ static ssize_t hello_read(devminor_t UNUSED(minor), u64_t position, return size; } -static int sef_cb_lu_state_save(int UNUSED(state)) { +static int sef_cb_lu_state_save(int UNUSED(state), int UNUSED(flags)) { /* Save the state. */ ds_publish_u32("open_counter", open_counter, DSF_OVERWRITE); diff --git a/minix/drivers/net/rtl8139/liveupdate.c b/minix/drivers/net/rtl8139/liveupdate.c index d824b094b..e5f6d827f 100644 --- a/minix/drivers/net/rtl8139/liveupdate.c +++ b/minix/drivers/net/rtl8139/liveupdate.c @@ -65,7 +65,7 @@ int sef_cb_lu_prepare(int state) /*===========================================================================* * sef_cb_lu_state_isvalid * *===========================================================================*/ -int sef_cb_lu_state_isvalid(int state) +int sef_cb_lu_state_isvalid(int state, int UNUSED(flags)) { return SEF_LU_STATE_IS_STANDARD(state) || RL_STATE_IS_CUSTOM(state); } diff --git a/minix/drivers/power/tps65217/tps65217.c b/minix/drivers/power/tps65217/tps65217.c index 787954f60..16428c1d4 100644 --- a/minix/drivers/power/tps65217/tps65217.c +++ b/minix/drivers/power/tps65217/tps65217.c @@ -109,12 +109,6 @@ static int intr_enable(void); static int intr_handler(void); static void do_shutdown(int how); -/* SEF Related Function Prototypes */ -static void sef_local_startup(void); -static int sef_cb_lu_state_save(int); -static int lu_state_restore(void); -static int sef_cb_init(int type, sef_init_info_t * info); - static int check_revision(void) { @@ -244,7 +238,7 @@ intr_handler(void) } static int -sef_cb_lu_state_save(int UNUSED(state)) +sef_cb_lu_state_save(int UNUSED(result), int UNUSED(flags)) { ds_publish_u32("bus", bus, DSF_OVERWRITE); ds_publish_u32("address", address, DSF_OVERWRITE); diff --git a/minix/drivers/power/tps65950/tps65950.c b/minix/drivers/power/tps65950/tps65950.c index 16cd4951f..db508d633 100644 --- a/minix/drivers/power/tps65950/tps65950.c +++ b/minix/drivers/power/tps65950/tps65950.c @@ -38,12 +38,6 @@ i2c_addr_t addresses[NADDRESSES] = { /* local functions */ static int check_revision(void); -/* SEF related functions */ -static void sef_local_startup(void); -static int sef_cb_lu_state_save(int); -static int lu_state_restore(void); -static int sef_cb_init(int type, sef_init_info_t * info); - /* functions for transfering struct tm to/from this driver and calling proc. */ static int fetch_t(endpoint_t ep, cp_grant_id_t gid, struct tm *t); static int store_t(endpoint_t ep, cp_grant_id_t gid, struct tm *t); @@ -148,7 +142,7 @@ check_revision(void) } static int -sef_cb_lu_state_save(int UNUSED(state)) +sef_cb_lu_state_save(int UNUSED(result), int UNUSED(flags)) { /* The addresses are fixed/non-configurable so bus is the only state */ ds_publish_u32("bus", bus, DSF_OVERWRITE); diff --git a/minix/drivers/printer/printer/liveupdate.c b/minix/drivers/printer/printer/liveupdate.c index 232e4e29c..1815a1164 100644 --- a/minix/drivers/printer/printer/liveupdate.c +++ b/minix/drivers/printer/printer/liveupdate.c @@ -39,7 +39,7 @@ int sef_cb_lu_prepare(int state) /*===========================================================================* * sef_cb_lu_state_isvalid * *===========================================================================*/ -int sef_cb_lu_state_isvalid(int state) +int sef_cb_lu_state_isvalid(int state, int UNUSED(flags)) { return SEF_LU_STATE_IS_STANDARD(state) || PR_STATE_IS_CUSTOM(state); } diff --git a/minix/drivers/printer/printer/printer.c b/minix/drivers/printer/printer/printer.c index 47abec238..4dc1486be 100644 --- a/minix/drivers/printer/printer/printer.c +++ b/minix/drivers/printer/printer/printer.c @@ -92,7 +92,7 @@ static void printer_intr(unsigned int mask); static void sef_local_startup(void); static int sef_cb_init_fresh(int type, sef_init_info_t *info); EXTERN int sef_cb_lu_prepare(int state); -EXTERN int sef_cb_lu_state_isvalid(int state); +EXTERN int sef_cb_lu_state_isvalid(int state, int flags); EXTERN void sef_cb_lu_state_dump(int state); /* Entry points to this driver. */ diff --git a/minix/drivers/sensors/bmp085/bmp085.c b/minix/drivers/sensors/bmp085/bmp085.c index 7782fbf25..25cf17cb6 100644 --- a/minix/drivers/sensors/bmp085/bmp085.c +++ b/minix/drivers/sensors/bmp085/bmp085.c @@ -155,12 +155,6 @@ static ssize_t bmp085_read(devminor_t minor, u64_t position, endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags, cdev_id_t id); static void bmp085_other(message * m, int ipc_status); -/* SEF Function */ -static int sef_cb_lu_state_save(int); -static int lu_state_restore(void); -static int sef_cb_init(int type, sef_init_info_t * info); -static void sef_local_startup(void); - /* Entry points to this driver from libchardriver. */ static struct chardriver bmp085_tab = { .cdr_read = bmp085_read, @@ -473,7 +467,7 @@ bmp085_other(message * m, int ipc_status) } static int -sef_cb_lu_state_save(int UNUSED(state)) +sef_cb_lu_state_save(int UNUSED(result), int UNUSED(flags)) { ds_publish_u32("bus", bus, DSF_OVERWRITE); ds_publish_u32("address", address, DSF_OVERWRITE); diff --git a/minix/drivers/sensors/sht21/sht21.c b/minix/drivers/sensors/sht21/sht21.c index c6f585c43..2ce2dd5f5 100644 --- a/minix/drivers/sensors/sht21/sht21.c +++ b/minix/drivers/sensors/sht21/sht21.c @@ -118,12 +118,6 @@ static ssize_t sht21_read(devminor_t minor, u64_t position, endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags, cdev_id_t id); static void sht21_other(message * m, int ipc_status); -/* SEF functions */ -static int sef_cb_lu_state_save(int); -static int lu_state_restore(void); -static int sef_cb_init(int type, sef_init_info_t * info); -static void sef_local_startup(void); - /* Entry points to this driver from libchardriver. */ static struct chardriver sht21_tab = { .cdr_read = sht21_read, @@ -376,7 +370,7 @@ sht21_other(message * m, int ipc_status) } static int -sef_cb_lu_state_save(int UNUSED(state)) +sef_cb_lu_state_save(int UNUSED(result), int UNUSED(flags)) { ds_publish_u32("bus", bus, DSF_OVERWRITE); ds_publish_u32("address", address, DSF_OVERWRITE); diff --git a/minix/drivers/sensors/tsl2550/tsl2550.c b/minix/drivers/sensors/tsl2550/tsl2550.c index 82637b2ba..cfd58c8e8 100644 --- a/minix/drivers/sensors/tsl2550/tsl2550.c +++ b/minix/drivers/sensors/tsl2550/tsl2550.c @@ -69,12 +69,6 @@ static ssize_t tsl2550_read(devminor_t minor, u64_t position, endpoint_t endpt, cp_grant_id_t grant, size_t size, int flags, cdev_id_t id); static void tsl2550_other(message * m, int ipc_status); -/* SEF functions */ -static int sef_cb_lu_state_save(int); -static int lu_state_restore(void); -static int sef_cb_init(int type, sef_init_info_t * info); -static void sef_local_startup(void); - /* Entry points to this driver from libchardriver. */ static struct chardriver tsl2550_tab = { .cdr_read = tsl2550_read, @@ -325,7 +319,7 @@ tsl2550_other(message * m, int ipc_status) } static int -sef_cb_lu_state_save(int UNUSED(state)) +sef_cb_lu_state_save(int UNUSED(result), int UNUSED(flags)) { ds_publish_u32("bus", bus, DSF_OVERWRITE); ds_publish_u32("address", address, DSF_OVERWRITE); diff --git a/minix/drivers/storage/at_wini/at_wini.h b/minix/drivers/storage/at_wini/at_wini.h index 18ef3fd26..f0acc73e0 100644 --- a/minix/drivers/storage/at_wini/at_wini.h +++ b/minix/drivers/storage/at_wini/at_wini.h @@ -205,5 +205,5 @@ #define ATA_IF_NATIVE1 (1L << 2) /* second channel is in native mode */ extern int sef_cb_lu_prepare(int state); -extern int sef_cb_lu_state_isvalid(int state); +extern int sef_cb_lu_state_isvalid(int state, int flags); extern void sef_cb_lu_state_dump(int state); diff --git a/minix/drivers/storage/at_wini/liveupdate.c b/minix/drivers/storage/at_wini/liveupdate.c index 25a57b742..59bbdaa40 100644 --- a/minix/drivers/storage/at_wini/liveupdate.c +++ b/minix/drivers/storage/at_wini/liveupdate.c @@ -49,7 +49,7 @@ int sef_cb_lu_prepare(int state) /*===========================================================================* * sef_cb_lu_state_isvalid * *===========================================================================*/ -int sef_cb_lu_state_isvalid(int state) +int sef_cb_lu_state_isvalid(int state, int UNUSED(flags)) { return SEF_LU_STATE_IS_STANDARD(state) || AT_STATE_IS_CUSTOM(state); } diff --git a/minix/drivers/storage/floppy/floppy.c b/minix/drivers/storage/floppy/floppy.c index 75b436715..a5b352048 100644 --- a/minix/drivers/storage/floppy/floppy.c +++ b/minix/drivers/storage/floppy/floppy.c @@ -283,7 +283,7 @@ static void sef_local_startup(void); static int sef_cb_init_fresh(int type, sef_init_info_t *info); static void sef_cb_signal_handler(int signo); EXTERN int sef_cb_lu_prepare(int state); -EXTERN int sef_cb_lu_state_isvalid(int state); +EXTERN int sef_cb_lu_state_isvalid(int state, int flags); EXTERN void sef_cb_lu_state_dump(int state); int last_was_write; diff --git a/minix/drivers/storage/floppy/liveupdate.c b/minix/drivers/storage/floppy/liveupdate.c index d709725d8..b6066a667 100644 --- a/minix/drivers/storage/floppy/liveupdate.c +++ b/minix/drivers/storage/floppy/liveupdate.c @@ -49,7 +49,7 @@ int sef_cb_lu_prepare(int state) /*===========================================================================* * sef_cb_lu_state_isvalid * *===========================================================================*/ -int sef_cb_lu_state_isvalid(int state) +int sef_cb_lu_state_isvalid(int state, int UNUSED(flags)) { return SEF_LU_STATE_IS_STANDARD(state) || FL_STATE_IS_CUSTOM(state); } diff --git a/minix/drivers/system/log/liveupdate.c b/minix/drivers/system/log/liveupdate.c index e1d114ab7..ccf7885b8 100644 --- a/minix/drivers/system/log/liveupdate.c +++ b/minix/drivers/system/log/liveupdate.c @@ -68,7 +68,7 @@ int sef_cb_lu_prepare(int state) /*===========================================================================* * sef_cb_lu_state_isvalid * *===========================================================================*/ -int sef_cb_lu_state_isvalid(int state) +int sef_cb_lu_state_isvalid(int state, int UNUSED(flags)) { return SEF_LU_STATE_IS_STANDARD(state) || LOG_STATE_IS_CUSTOM(state); } diff --git a/minix/drivers/system/log/log.c b/minix/drivers/system/log/log.c index ee4393a7b..0f693e844 100644 --- a/minix/drivers/system/log/log.c +++ b/minix/drivers/system/log/log.c @@ -43,7 +43,7 @@ static struct chardriver log_dtab = { static void sef_local_startup(void); static int sef_cb_init_fresh(int type, sef_init_info_t *info); EXTERN int sef_cb_lu_prepare(int state); -EXTERN int sef_cb_lu_state_isvalid(int state); +EXTERN int sef_cb_lu_state_isvalid(int state, int flags); EXTERN void sef_cb_lu_state_dump(int state); static void sef_cb_signal_handler(int signo); diff --git a/minix/drivers/video/fb/fb.c b/minix/drivers/video/fb/fb.c index d8d271d33..b80456261 100644 --- a/minix/drivers/video/fb/fb.c +++ b/minix/drivers/video/fb/fb.c @@ -40,12 +40,6 @@ static int do_get_fixscreeninfo(int minor, endpoint_t ep, cp_grant_id_t gid); static int do_pan_display(int minor, endpoint_t ep, cp_grant_id_t gid); static int keep_displaying_restarted(void); -/* SEF functions and variables. */ -static void sef_local_startup(void); -static int sef_cb_init(int type, sef_init_info_t *info); -static int sef_cb_lu_state_save(int); -static int lu_state_restore(void); - /* Entry points to the fb driver. */ static struct chardriver fb_tab = { @@ -240,7 +234,8 @@ fb_write(devminor_t minor, u64_t pos, endpoint_t ep, cp_grant_id_t gid, } static int -sef_cb_lu_state_save(int UNUSED(state)) { +sef_cb_lu_state_save(int UNUSED(result), int UNUSED(flags)) +{ /* Save the state. */ ds_publish_u32("open_counter", open_counter[0], DSF_OVERWRITE); @@ -259,26 +254,6 @@ lu_state_restore() { return OK; } -static void -sef_local_startup() -{ - /* Register init callbacks. Use the same function for all event types */ - sef_setcb_init_fresh(sef_cb_init); - sef_setcb_init_lu(sef_cb_init); - sef_setcb_init_restart(sef_cb_init); - - /* Register live update callbacks */ - /* - Agree to update immediately when LU is requested in a valid state*/ - sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); - /* - Support live update starting from any standard state */ - sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard); - /* - Register a custom routine to save the state. */ - sef_setcb_lu_state_save(sef_cb_lu_state_save); - - /* Let SEF perform startup. */ - sef_startup(); -} - static int sef_cb_init(int type, sef_init_info_t *UNUSED(info)) { @@ -314,6 +289,26 @@ sef_cb_init(int type, sef_init_info_t *UNUSED(info)) return OK; } +static void +sef_local_startup() +{ + /* Register init callbacks. Use the same function for all event types */ + sef_setcb_init_fresh(sef_cb_init); + sef_setcb_init_lu(sef_cb_init); + sef_setcb_init_restart(sef_cb_init); + + /* Register live update callbacks */ + /* - Agree to update immediately when LU is requested in a valid state*/ + sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); + /* - Support live update starting from any standard state */ + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard); + /* - Register a custom routine to save the state. */ + sef_setcb_lu_state_save(sef_cb_lu_state_save); + + /* Let SEF perform startup. */ + sef_startup(); +} + int main(int argc, char *argv[]) { diff --git a/minix/drivers/video/tda19988/tda19988.c b/minix/drivers/video/tda19988/tda19988.c index 25176d10a..1beb932f7 100644 --- a/minix/drivers/video/tda19988/tda19988.c +++ b/minix/drivers/video/tda19988/tda19988.c @@ -141,11 +141,6 @@ static struct log log = { .log_func = default_log }; -static void sef_local_startup(void); -static int sef_cb_lu_state_save(int); -static int lu_state_restore(void); -static int sef_cb_init(int type, sef_init_info_t * info); - /* CEC Module */ static int is_display_connected(void); static int enable_hdmi_module(void); @@ -821,7 +816,7 @@ read_edid(uint8_t * buf, size_t count) } static int -sef_cb_lu_state_save(int UNUSED(state)) +sef_cb_lu_state_save(int UNUSED(result), int UNUSED(flags)) { ds_publish_u32("cec_bus", cec_bus, DSF_OVERWRITE); ds_publish_u32("hdmi_bus", hdmi_bus, DSF_OVERWRITE); diff --git a/minix/include/minix/ipc.h b/minix/include/minix/ipc.h index 97a42221d..83b723e99 100644 --- a/minix/include/minix/ipc.h +++ b/minix/include/minix/ipc.h @@ -1629,7 +1629,8 @@ typedef struct { int result; int state; int prepare_maxtime; - uint8_t padding[44]; + int flags; + uint8_t padding[40]; } mess_rs_update; _ASSERT_MSG_SIZE(mess_rs_update); diff --git a/minix/include/minix/sef.h b/minix/include/minix/sef.h index 6fb69fad9..bae2f0b10 100644 --- a/minix/include/minix/sef.h +++ b/minix/include/minix/sef.h @@ -125,10 +125,10 @@ void sef_cb_ping_reply_pong(endpoint_t source); /* Callback type definitions. */ typedef int(*sef_cb_lu_prepare_t)(int); -typedef int(*sef_cb_lu_state_isvalid_t)(int); +typedef int(*sef_cb_lu_state_isvalid_t)(int, int); typedef void(*sef_cb_lu_state_changed_t)(int, int); typedef void(*sef_cb_lu_state_dump_t)(int); -typedef int(*sef_cb_lu_state_save_t)(int); +typedef int(*sef_cb_lu_state_save_t)(int, int); typedef int(*sef_cb_lu_response_t)(message *m_ptr); /* Callback registration helpers. */ @@ -141,17 +141,19 @@ void sef_setcb_lu_response(sef_cb_lu_response_t cb); /* Predefined callback implementations. */ int sef_cb_lu_prepare_null(int state); -int sef_cb_lu_state_isvalid_null(int state); +int sef_cb_lu_state_isvalid_null(int state, int flags); void sef_cb_lu_state_changed_null(int old_state, int state); void sef_cb_lu_state_dump_null(int state); -int sef_cb_lu_state_save_null(int state); +int sef_cb_lu_state_save_null(int state, int flags); int sef_cb_lu_response_null(message *m_ptr); int sef_cb_lu_prepare_always_ready(int state); int sef_cb_lu_prepare_never_ready(int state); int sef_cb_lu_prepare_crash(int state); -int sef_cb_lu_state_isvalid_standard(int state); -int sef_cb_lu_state_isvalid_workfree(int state); +int sef_cb_lu_state_isvalid_standard(int state, int flags); +int sef_cb_lu_state_isvalid_workfree(int state, int flags); +int sef_cb_lu_state_isvalid_workfree_self(int state, int flags); +int sef_cb_lu_state_isvalid_generic(int state, int flags); int sef_cb_lu_response_rs_reply(message *m_ptr); /* Macros for predefined callback implementations. */ @@ -174,12 +176,39 @@ int sef_cb_lu_response_rs_reply(message *m_ptr); #define SEF_LU_STATE_WORK_FREE 1 /* no work in progress */ #define SEF_LU_STATE_REQUEST_FREE 2 /* no request in progress */ #define SEF_LU_STATE_PROTOCOL_FREE 3 /* no protocol in progress */ -#define SEF_LU_STATE_CUSTOM_BASE (SEF_LU_STATE_PROTOCOL_FREE+1) -#define SEF_LU_STATE_IS_STANDARD(s) ((s) > SEF_LU_STATE_NULL \ +#define SEF_LU_STATE_EVAL 4 /* evaluate expression */ + +#define SEF_LU_STATE_UNREACHABLE 5 /* unreachable state */ +#define SEF_LU_STATE_PREPARE_CRASH 6 /* crash at prepare time */ + +#define SEF_LU_STATE_STD_BASE (SEF_LU_STATE_WORK_FREE) +#define SEF_LU_STATE_DEBUG_BASE (SEF_LU_STATE_UNREACHABLE) +#define SEF_LU_STATE_CUSTOM_BASE (SEF_LU_STATE_PREPARE_CRASH+1) + +#define SEF_LU_STATE_IS_STANDARD(s) ((s) >= SEF_LU_STATE_STD_BASE \ + && (s) < SEF_LU_STATE_CUSTOM_BASE \ + && (SEF_LU_ALWAYS_ALLOW_DEBUG_STATES || !SEF_LU_STATE_IS_DEBUG(s))) +#define SEF_LU_STATE_IS_DEBUG(s) ((s) >= SEF_LU_STATE_DEBUG_BASE \ && (s) < SEF_LU_STATE_CUSTOM_BASE) +#define SEF_LU_STATE_EVAL_MAX_LEN 512 + +/* Live update flags (can be used as init flags as well). */ +#define SEF_LU_SELF 0x0100 /* this is a self update */ +#define SEF_LU_ASR 0x0200 /* this is an ASR update */ +#define SEF_LU_MULTI 0x0400 /* this is a multi-component update */ +#define SEF_LU_INCLUDES_VM 0x0800 /* the update includes VM */ +#define SEF_LU_INCLUDES_RS 0x1000 /* the update includes RS */ +#define SEF_LU_PREPARE_ONLY 0x2000 /* prepare only, no actual update taking place */ +#define SEF_LU_UNSAFE 0x4000 /* unsafe update, rollback may not be possible */ +#define SEF_LU_NOMMAP 0x8000 /* update doesn't inherit mmapped regions */ +#define SEF_LU_DETACHED 0x10000 /* update detaches the old instance */ + +#define SEF_LU_IS_IDENTITY_UPDATE(F) (((F) & (SEF_LU_SELF|SEF_LU_NOMMAP|SEF_LU_ASR|SEF_INIT_ST)) == SEF_LU_SELF) + /* Debug. */ #define SEF_LU_DEBUG_DEFAULT 1 +#define SEF_LU_ALWAYS_ALLOW_DEBUG_STATES 1 #ifndef SEF_LU_DEBUG #define SEF_LU_DEBUG SEF_LU_DEBUG_DEFAULT diff --git a/minix/lib/libsys/sef_liveupdate.c b/minix/lib/libsys/sef_liveupdate.c index f1834b77f..409336c68 100644 --- a/minix/lib/libsys/sef_liveupdate.c +++ b/minix/lib/libsys/sef_liveupdate.c @@ -4,6 +4,9 @@ /* SEF Live update variables. */ static int sef_lu_state; +static int sef_lu_flags; + +extern __attribute__((weak)) int st_do_state_cleanup(void); /* SEF Live update callbacks. */ static struct sef_cbs { @@ -83,19 +86,21 @@ void do_sef_lu_before_receive(void) int do_sef_lu_request(message *m_ptr) { /* Handle a SEF Live update request. */ - int state, old_state, is_valid_state; + int state, old_state, flags, is_valid_state; sef_lu_debug_cycle = 0; old_state = sef_lu_state; state = m_ptr->m_rs_update.state; + flags = m_ptr->m_rs_update.flags; /* Deal with prepare cancel requests first. */ is_valid_state = (state == SEF_LU_STATE_NULL); /* Otherwise only accept live update requests with a valid state. */ - is_valid_state = is_valid_state || sef_cbs.sef_cb_lu_state_isvalid(state); + is_valid_state = SEF_LU_ALWAYS_ALLOW_DEBUG_STATES && SEF_LU_STATE_IS_DEBUG(state); + is_valid_state = is_valid_state || sef_cbs.sef_cb_lu_state_isvalid(state, flags); if(!is_valid_state) { - if(sef_cbs.sef_cb_lu_state_isvalid == SEF_CB_LU_STATE_ISVALID_NULL) { + if(sef_cbs.sef_cb_lu_state_isvalid == SEF_CB_LU_STATE_ISVALID_DEFAULT) { sef_lu_ready(ENOSYS); } else { @@ -124,7 +129,7 @@ int do_sef_lu_request(message *m_ptr) static void sef_lu_ready(int result) { message m; - int old_state, r; + int old_state, r=EINVAL; #if SEF_LU_DEBUG sef_lu_debug_begin(); @@ -134,13 +139,19 @@ static void sef_lu_ready(int result) sef_lu_debug_end(); #endif - /* If result is OK, let the callback code save + /* If result is OK, let the callback code cleanup and save * any state that must be carried over to the new version. */ if(result == OK) { - r = sef_cbs.sef_cb_lu_state_save(sef_lu_state); + /* st_do_state_cleanup is a weak symbol. It is only defined if + * we are linked against magic */ + if (st_do_state_cleanup) + r = st_do_state_cleanup(); + if(r == OK) { + r = sef_cbs.sef_cb_lu_state_save(sef_lu_state, sef_lu_flags); + } if(r != OK) { - /* Abort update if callback returned error. */ + /* Abort update in case of error. */ result = r; } } @@ -239,7 +250,7 @@ int sef_cb_lu_prepare_null(int UNUSED(state)) /*===========================================================================* * sef_cb_lu_state_isvalid_null * *===========================================================================*/ -int sef_cb_lu_state_isvalid_null(int UNUSED(state)) +int sef_cb_lu_state_isvalid_null(int UNUSED(state), int UNUSED(flags)) { return FALSE; } @@ -263,7 +274,7 @@ void sef_cb_lu_state_dump_null(int UNUSED(state)) /*===========================================================================* * sef_cb_lu_state_save_null * *===========================================================================*/ -int sef_cb_lu_state_save_null(int UNUSED(result)) +int sef_cb_lu_state_save_null(int UNUSED(result), int UNUSED(flags)) { return OK; } @@ -312,7 +323,7 @@ int sef_cb_lu_prepare_crash(int UNUSED(state)) /*===========================================================================* * sef_cb_lu_state_isvalid_standard * *===========================================================================*/ -int sef_cb_lu_state_isvalid_standard(int state) +int sef_cb_lu_state_isvalid_standard(int state, int UNUSED(flags)) { return SEF_LU_STATE_IS_STANDARD(state); } @@ -320,11 +331,27 @@ int sef_cb_lu_state_isvalid_standard(int state) /*===========================================================================* * sef_cb_lu_state_isvalid_workfree * *===========================================================================*/ -int sef_cb_lu_state_isvalid_workfree(int state) +int sef_cb_lu_state_isvalid_workfree(int state, int UNUSED(flags)) { return (state == SEF_LU_STATE_WORK_FREE); } +/*===========================================================================* + * sef_cb_lu_state_isvalid_workfree_self * + *===========================================================================*/ +int sef_cb_lu_state_isvalid_workfree_self(int state, int flags) +{ + return (state == SEF_LU_STATE_WORK_FREE) && (flags & (SEF_LU_SELF|SEF_LU_ASR)); +} + +/*===========================================================================* + * sef_cb_lu_state_isvalid_generic * + *===========================================================================*/ +int sef_cb_lu_state_isvalid_generic(int state, int flags) +{ + return (state == SEF_LU_STATE_EVAL) || sef_cb_lu_state_isvalid_workfree(state, flags); +} + /*===========================================================================* * sef_cb_lu_response_rs_reply * *===========================================================================*/