libsys: Change SEF Live Update state callback API.

The following callbacks are concerned:
 - state_save
 - state_isvalid

Change-Id: I75f71fe162ccd8b23b18cae15f844b79b290a8c1
This commit is contained in:
Cristiano Giuffrida 2014-03-01 23:48:16 +01:00 committed by David van Moolenbroek
parent 01c875ce91
commit e1f889d228
22 changed files with 138 additions and 133 deletions

View file

@ -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); cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id);
static void i2c_other(message * m, int ipc_status); 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 */ /* Globals */
/* the bus that this instance of the driver is responsible for */ /* the bus that this instance of the driver is responsible for */
@ -82,6 +76,25 @@ static struct chardriver i2c_tab = {
.cdr_other = i2c_other .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 * 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 * 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; i2cdev[slave_addr].endpt = endpt;
memcpy(i2cdev[slave_addr].key, key, DS_MAX_KEYLEN); 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", log_debug(&log, "Device 0x%x claimed by 0x%x key='%s'\n",
slave_addr, endpt, key); 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 static int
lu_state_restore(void) lu_state_restore(void)
{ {
@ -465,7 +459,7 @@ sef_cb_init(int type, sef_init_info_t * UNUSED(info))
} }
/* Save state */ /* Save state */
sef_cb_lu_state_save(0); sef_cb_lu_state_save(0, 0);
/* Initialization completed successfully. */ /* Initialization completed successfully. */
return OK; return OK;

View file

@ -22,12 +22,6 @@ static i2c_addr_t valid_addrs[9] = {
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x00 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 */ /* libblockdriver callbacks */
static int cat24c256_blk_open(devminor_t minor, int access); static int cat24c256_blk_open(devminor_t minor, int access);
static int cat24c256_blk_close(devminor_t minor); 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 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("bus", bus, DSF_OVERWRITE);
ds_publish_u32("address", address, DSF_OVERWRITE); ds_publish_u32("address", address, DSF_OVERWRITE);

View file

@ -16,7 +16,7 @@ static ssize_t hello_read(devminor_t minor, u64_t position, endpoint_t endpt,
/* SEF functions and variables. */ /* SEF functions and variables. */
static void sef_local_startup(void); static void sef_local_startup(void);
static int sef_cb_init(int type, sef_init_info_t *info); 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); static int lu_state_restore(void);
/* Entry points to the hello driver. */ /* Entry points to the hello driver. */
@ -73,7 +73,7 @@ static ssize_t hello_read(devminor_t UNUSED(minor), u64_t position,
return size; 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. */ /* Save the state. */
ds_publish_u32("open_counter", open_counter, DSF_OVERWRITE); ds_publish_u32("open_counter", open_counter, DSF_OVERWRITE);

View file

@ -65,7 +65,7 @@ int sef_cb_lu_prepare(int state)
/*===========================================================================* /*===========================================================================*
* sef_cb_lu_state_isvalid * * 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); return SEF_LU_STATE_IS_STANDARD(state) || RL_STATE_IS_CUSTOM(state);
} }

View file

@ -109,12 +109,6 @@ static int intr_enable(void);
static int intr_handler(void); static int intr_handler(void);
static void do_shutdown(int how); 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 static int
check_revision(void) check_revision(void)
{ {
@ -244,7 +238,7 @@ intr_handler(void)
} }
static int 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("bus", bus, DSF_OVERWRITE);
ds_publish_u32("address", address, DSF_OVERWRITE); ds_publish_u32("address", address, DSF_OVERWRITE);

View file

@ -38,12 +38,6 @@ i2c_addr_t addresses[NADDRESSES] = {
/* local functions */ /* local functions */
static int check_revision(void); 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. */ /* 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 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); static int store_t(endpoint_t ep, cp_grant_id_t gid, struct tm *t);
@ -148,7 +142,7 @@ check_revision(void)
} }
static int 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 */ /* The addresses are fixed/non-configurable so bus is the only state */
ds_publish_u32("bus", bus, DSF_OVERWRITE); ds_publish_u32("bus", bus, DSF_OVERWRITE);

View file

@ -39,7 +39,7 @@ int sef_cb_lu_prepare(int state)
/*===========================================================================* /*===========================================================================*
* sef_cb_lu_state_isvalid * * 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); return SEF_LU_STATE_IS_STANDARD(state) || PR_STATE_IS_CUSTOM(state);
} }

View file

@ -92,7 +92,7 @@ static void printer_intr(unsigned int mask);
static void sef_local_startup(void); static void sef_local_startup(void);
static int sef_cb_init_fresh(int type, sef_init_info_t *info); 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_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); EXTERN void sef_cb_lu_state_dump(int state);
/* Entry points to this driver. */ /* Entry points to this driver. */

View file

@ -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); cp_grant_id_t grant, size_t size, int flags, cdev_id_t id);
static void bmp085_other(message * m, int ipc_status); 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. */ /* Entry points to this driver from libchardriver. */
static struct chardriver bmp085_tab = { static struct chardriver bmp085_tab = {
.cdr_read = bmp085_read, .cdr_read = bmp085_read,
@ -473,7 +467,7 @@ bmp085_other(message * m, int ipc_status)
} }
static int 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("bus", bus, DSF_OVERWRITE);
ds_publish_u32("address", address, DSF_OVERWRITE); ds_publish_u32("address", address, DSF_OVERWRITE);

View file

@ -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); cp_grant_id_t grant, size_t size, int flags, cdev_id_t id);
static void sht21_other(message * m, int ipc_status); 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. */ /* Entry points to this driver from libchardriver. */
static struct chardriver sht21_tab = { static struct chardriver sht21_tab = {
.cdr_read = sht21_read, .cdr_read = sht21_read,
@ -376,7 +370,7 @@ sht21_other(message * m, int ipc_status)
} }
static int 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("bus", bus, DSF_OVERWRITE);
ds_publish_u32("address", address, DSF_OVERWRITE); ds_publish_u32("address", address, DSF_OVERWRITE);

View file

@ -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); cp_grant_id_t grant, size_t size, int flags, cdev_id_t id);
static void tsl2550_other(message * m, int ipc_status); 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. */ /* Entry points to this driver from libchardriver. */
static struct chardriver tsl2550_tab = { static struct chardriver tsl2550_tab = {
.cdr_read = tsl2550_read, .cdr_read = tsl2550_read,
@ -325,7 +319,7 @@ tsl2550_other(message * m, int ipc_status)
} }
static int 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("bus", bus, DSF_OVERWRITE);
ds_publish_u32("address", address, DSF_OVERWRITE); ds_publish_u32("address", address, DSF_OVERWRITE);

View file

@ -205,5 +205,5 @@
#define ATA_IF_NATIVE1 (1L << 2) /* second channel is in native mode */ #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_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); extern void sef_cb_lu_state_dump(int state);

View file

@ -49,7 +49,7 @@ int sef_cb_lu_prepare(int state)
/*===========================================================================* /*===========================================================================*
* sef_cb_lu_state_isvalid * * 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); return SEF_LU_STATE_IS_STANDARD(state) || AT_STATE_IS_CUSTOM(state);
} }

View file

@ -283,7 +283,7 @@ static void sef_local_startup(void);
static int sef_cb_init_fresh(int type, sef_init_info_t *info); static int sef_cb_init_fresh(int type, sef_init_info_t *info);
static void sef_cb_signal_handler(int signo); static void sef_cb_signal_handler(int signo);
EXTERN int sef_cb_lu_prepare(int state); 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); EXTERN void sef_cb_lu_state_dump(int state);
int last_was_write; int last_was_write;

View file

@ -49,7 +49,7 @@ int sef_cb_lu_prepare(int state)
/*===========================================================================* /*===========================================================================*
* sef_cb_lu_state_isvalid * * 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); return SEF_LU_STATE_IS_STANDARD(state) || FL_STATE_IS_CUSTOM(state);
} }

View file

@ -68,7 +68,7 @@ int sef_cb_lu_prepare(int state)
/*===========================================================================* /*===========================================================================*
* sef_cb_lu_state_isvalid * * 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); return SEF_LU_STATE_IS_STANDARD(state) || LOG_STATE_IS_CUSTOM(state);
} }

View file

@ -43,7 +43,7 @@ static struct chardriver log_dtab = {
static void sef_local_startup(void); static void sef_local_startup(void);
static int sef_cb_init_fresh(int type, sef_init_info_t *info); 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_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); EXTERN void sef_cb_lu_state_dump(int state);
static void sef_cb_signal_handler(int signo); static void sef_cb_signal_handler(int signo);

View file

@ -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 do_pan_display(int minor, endpoint_t ep, cp_grant_id_t gid);
static int keep_displaying_restarted(void); 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. */ /* Entry points to the fb driver. */
static struct chardriver fb_tab = 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 static int
sef_cb_lu_state_save(int UNUSED(state)) { sef_cb_lu_state_save(int UNUSED(result), int UNUSED(flags))
{
/* Save the state. */ /* Save the state. */
ds_publish_u32("open_counter", open_counter[0], DSF_OVERWRITE); ds_publish_u32("open_counter", open_counter[0], DSF_OVERWRITE);
@ -259,26 +254,6 @@ lu_state_restore() {
return OK; 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 static int
sef_cb_init(int type, sef_init_info_t *UNUSED(info)) 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; 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 int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {

View file

@ -141,11 +141,6 @@ static struct log log = {
.log_func = default_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 */ /* CEC Module */
static int is_display_connected(void); static int is_display_connected(void);
static int enable_hdmi_module(void); static int enable_hdmi_module(void);
@ -821,7 +816,7 @@ read_edid(uint8_t * buf, size_t count)
} }
static int 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("cec_bus", cec_bus, DSF_OVERWRITE);
ds_publish_u32("hdmi_bus", hdmi_bus, DSF_OVERWRITE); ds_publish_u32("hdmi_bus", hdmi_bus, DSF_OVERWRITE);

View file

@ -1629,7 +1629,8 @@ typedef struct {
int result; int result;
int state; int state;
int prepare_maxtime; int prepare_maxtime;
uint8_t padding[44]; int flags;
uint8_t padding[40];
} mess_rs_update; } mess_rs_update;
_ASSERT_MSG_SIZE(mess_rs_update); _ASSERT_MSG_SIZE(mess_rs_update);

View file

@ -125,10 +125,10 @@ void sef_cb_ping_reply_pong(endpoint_t source);
/* Callback type definitions. */ /* Callback type definitions. */
typedef int(*sef_cb_lu_prepare_t)(int); 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_changed_t)(int, int);
typedef void(*sef_cb_lu_state_dump_t)(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); typedef int(*sef_cb_lu_response_t)(message *m_ptr);
/* Callback registration helpers. */ /* Callback registration helpers. */
@ -141,17 +141,19 @@ void sef_setcb_lu_response(sef_cb_lu_response_t cb);
/* Predefined callback implementations. */ /* Predefined callback implementations. */
int sef_cb_lu_prepare_null(int state); 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_changed_null(int old_state, int state);
void sef_cb_lu_state_dump_null(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_response_null(message *m_ptr);
int sef_cb_lu_prepare_always_ready(int state); int sef_cb_lu_prepare_always_ready(int state);
int sef_cb_lu_prepare_never_ready(int state); int sef_cb_lu_prepare_never_ready(int state);
int sef_cb_lu_prepare_crash(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_standard(int state, int flags);
int sef_cb_lu_state_isvalid_workfree(int state); 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); int sef_cb_lu_response_rs_reply(message *m_ptr);
/* Macros for predefined callback implementations. */ /* 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_WORK_FREE 1 /* no work in progress */
#define SEF_LU_STATE_REQUEST_FREE 2 /* no request 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_PROTOCOL_FREE 3 /* no protocol in progress */
#define SEF_LU_STATE_CUSTOM_BASE (SEF_LU_STATE_PROTOCOL_FREE+1) #define SEF_LU_STATE_EVAL 4 /* evaluate expression */
#define SEF_LU_STATE_IS_STANDARD(s) ((s) > SEF_LU_STATE_NULL \
#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) && (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. */ /* Debug. */
#define SEF_LU_DEBUG_DEFAULT 1 #define SEF_LU_DEBUG_DEFAULT 1
#define SEF_LU_ALWAYS_ALLOW_DEBUG_STATES 1
#ifndef SEF_LU_DEBUG #ifndef SEF_LU_DEBUG
#define SEF_LU_DEBUG SEF_LU_DEBUG_DEFAULT #define SEF_LU_DEBUG SEF_LU_DEBUG_DEFAULT

View file

@ -4,6 +4,9 @@
/* SEF Live update variables. */ /* SEF Live update variables. */
static int sef_lu_state; static int sef_lu_state;
static int sef_lu_flags;
extern __attribute__((weak)) int st_do_state_cleanup(void);
/* SEF Live update callbacks. */ /* SEF Live update callbacks. */
static struct sef_cbs { static struct sef_cbs {
@ -83,19 +86,21 @@ void do_sef_lu_before_receive(void)
int do_sef_lu_request(message *m_ptr) int do_sef_lu_request(message *m_ptr)
{ {
/* Handle a SEF Live update request. */ /* 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; sef_lu_debug_cycle = 0;
old_state = sef_lu_state; old_state = sef_lu_state;
state = m_ptr->m_rs_update.state; state = m_ptr->m_rs_update.state;
flags = m_ptr->m_rs_update.flags;
/* Deal with prepare cancel requests first. */ /* Deal with prepare cancel requests first. */
is_valid_state = (state == SEF_LU_STATE_NULL); is_valid_state = (state == SEF_LU_STATE_NULL);
/* Otherwise only accept live update requests with a valid state. */ /* 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(!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); sef_lu_ready(ENOSYS);
} }
else { else {
@ -124,7 +129,7 @@ int do_sef_lu_request(message *m_ptr)
static void sef_lu_ready(int result) static void sef_lu_ready(int result)
{ {
message m; message m;
int old_state, r; int old_state, r=EINVAL;
#if SEF_LU_DEBUG #if SEF_LU_DEBUG
sef_lu_debug_begin(); sef_lu_debug_begin();
@ -134,13 +139,19 @@ static void sef_lu_ready(int result)
sef_lu_debug_end(); sef_lu_debug_end();
#endif #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. * any state that must be carried over to the new version.
*/ */
if(result == OK) { 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) { if(r != OK) {
/* Abort update if callback returned error. */ /* Abort update in case of error. */
result = r; result = r;
} }
} }
@ -239,7 +250,7 @@ int sef_cb_lu_prepare_null(int UNUSED(state))
/*===========================================================================* /*===========================================================================*
* sef_cb_lu_state_isvalid_null * * 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; return FALSE;
} }
@ -263,7 +274,7 @@ void sef_cb_lu_state_dump_null(int UNUSED(state))
/*===========================================================================* /*===========================================================================*
* sef_cb_lu_state_save_null * * 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; return OK;
} }
@ -312,7 +323,7 @@ int sef_cb_lu_prepare_crash(int UNUSED(state))
/*===========================================================================* /*===========================================================================*
* sef_cb_lu_state_isvalid_standard * * 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); 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 * * 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); 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 * * sef_cb_lu_response_rs_reply *
*===========================================================================*/ *===========================================================================*/