libblockdriver: clear IPC only on stateful restart

This removes a race condition when the block driver performs a
complete restart after a crash (the new default). If any user of
the driver finds out its new endpoint and sends a request to the
new driver instance before this instance has had the chance to
initialize, then its initialization would clear all IPC state and
thereby erroneously cancel the incoming request. Clearing IPC
state is only desired upon a stateful restart (where the driver's
endpoint is retained). This information is now passed to and used
by libblockdriver accordingly.
This commit is contained in:
David van Moolenbroek 2011-12-11 22:36:19 +01:00
parent 95d1f25b28
commit 4005bba437
7 changed files with 19 additions and 16 deletions

View file

@ -32,7 +32,7 @@ struct blockdriver {
/* Functions defined by libblockdriver. These can be used for both
* singlethreaded and multithreaded drivers.
*/
_PROTOTYPE( void blockdriver_announce, (void) );
_PROTOTYPE( void blockdriver_announce, (int type) );
#ifndef _BLOCKDRIVER_MT_API
/* Additional functions for the singlethreaded version. These allow the driver

View file

@ -2071,7 +2071,7 @@ PRIVATE void ahci_set_mapping(void)
/*===========================================================================*
* sef_cb_init_fresh *
*===========================================================================*/
PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the driver.
*/
@ -2093,7 +2093,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
ahci_set_mapping();
/* Announce that we are up. */
blockdriver_announce();
blockdriver_announce(type);
return OK;
}

View file

@ -257,7 +257,7 @@ PRIVATE void sef_local_startup(void)
/*===========================================================================*
* sef_cb_init_fresh *
*===========================================================================*/
PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the at_wini driver. */
system_hz = sys_hz();
@ -272,7 +272,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
init_params();
/* Announce we are up! */
blockdriver_announce();
blockdriver_announce(type);
return(OK);
}

View file

@ -122,7 +122,7 @@ PRIVATE void sef_local_startup(void)
/*===========================================================================*
* sef_cb_init_fresh *
*===========================================================================*/
PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the bios_wini driver. */
long v;
@ -132,7 +132,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
remap_first = v;
/* Announce we are up! */
blockdriver_announce();
blockdriver_announce(type);
return(OK);
}

View file

@ -443,9 +443,9 @@ PRIVATE void sef_local_startup(void)
/*===========================================================================*
* sef_cb_init_fresh *
*===========================================================================*/
PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the filter driver. */
/* Initialize the filter driver. */
int r;
r = parse_arguments(env_argc, env_argv);
@ -468,7 +468,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
}
/* Announce we are up! */
blockdriver_announce();
blockdriver_announce(type);
return(OK);
}

View file

@ -331,7 +331,7 @@ PRIVATE void sef_local_startup(void)
/*===========================================================================*
* sef_cb_init_fresh *
*===========================================================================*/
PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
{
/* Initialize the floppy driver. */
struct floppy *fp;
@ -363,7 +363,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
panic("Couldn't enable IRQs: %d", s);
/* Announce we are up! */
blockdriver_announce();
blockdriver_announce(type);
return(OK);
}

View file

@ -92,7 +92,7 @@ PRIVATE void set_open_dev(int device)
/*===========================================================================*
* blockdriver_announce *
*===========================================================================*/
PUBLIC void blockdriver_announce(void)
PUBLIC void blockdriver_announce(int type)
{
/* Announce we are up after a fresh start or a restart. */
int r;
@ -102,12 +102,15 @@ PUBLIC void blockdriver_announce(void)
/* Callers are allowed to use sendrec to communicate with drivers.
* For this reason, there may blocked callers when a driver restarts.
* Ask the kernel to unblock them (if any).
* Ask the kernel to unblock them (if any). Note that most block drivers
* will not restart statefully, and thus will skip this code.
*/
if (type == SEF_INIT_RESTART) {
#if USE_STATECTL
if ((r = sys_statectl(SYS_STATE_CLEAR_IPC_REFS)) != OK)
panic("blockdriver_init: sys_statectl failed: %d", r);
if ((r = sys_statectl(SYS_STATE_CLEAR_IPC_REFS)) != OK)
panic("blockdriver_init: sys_statectl failed: %d", r);
#endif
}
/* Publish a driver up event. */
if ((r = ds_retrieve_label_name(label, getprocnr())) != OK)