RS: support for endpoint-changing driver restarts
This commit is contained in:
parent
01015cc0e2
commit
ba19c83fd6
6 changed files with 65 additions and 11 deletions
|
@ -33,6 +33,7 @@
|
|||
#define RS_INITIALIZING 0x040 /* set when init is in progress */
|
||||
#define RS_UPDATING 0x080 /* set when update is in progress */
|
||||
#define RS_ACTIVE 0x100 /* set for the active instance of a service */
|
||||
#define RS_REINCARNATE 0x200 /* after exit, restart with a new endpoint */
|
||||
|
||||
/* Sys flag values. */
|
||||
#define SF_CORE_SRV 0x001 /* set for core system services */
|
||||
|
|
|
@ -23,16 +23,16 @@ static int load_aout(struct exec_info *execi);
|
|||
static int load_elf(struct exec_info *execi);
|
||||
|
||||
/* Array of loaders for different object formats */
|
||||
struct exec_loaders {
|
||||
static struct exec_loaders {
|
||||
int (*load_object)(struct exec_info *);
|
||||
} static const exec_loaders[] = {
|
||||
} const exec_loaders[] = {
|
||||
{ load_aout },
|
||||
{ load_elf },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
int srv_execve(int proc_e, char *exec, size_t exec_len, char **argv,
|
||||
char **Xenvp)
|
||||
char **UNUSED(Xenvp))
|
||||
{
|
||||
char * const *ap;
|
||||
char * const *ep;
|
||||
|
|
|
@ -161,7 +161,7 @@ PRIVATE void sef_local_startup()
|
|||
/*===========================================================================*
|
||||
* sef_cb_init_fresh *
|
||||
*===========================================================================*/
|
||||
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
|
||||
PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
|
||||
{
|
||||
/* Initialize the reincarnation server. */
|
||||
struct boot_image *ip;
|
||||
|
|
|
@ -423,8 +423,9 @@ struct rproc *rp;
|
|||
srv_kill(rp->r_pid, SIGKILL);
|
||||
}
|
||||
|
||||
/* Free slot */
|
||||
free_slot(rp);
|
||||
/* Free slot, unless we're about to reuse it */
|
||||
if (!(rp->r_flags & RS_REINCARNATE))
|
||||
free_slot(rp);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
@ -941,6 +942,40 @@ PUBLIC void activate_service(struct rproc *rp, struct rproc *ex_rp)
|
|||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* reincarnate_service *
|
||||
*===========================================================================*/
|
||||
PUBLIC void reincarnate_service(struct rproc *rp)
|
||||
{
|
||||
/* Restart a service as if it were never started before. */
|
||||
struct rprocpub *rpub;
|
||||
int i;
|
||||
|
||||
rpub = rp->r_pub;
|
||||
|
||||
rp->r_flags &= RS_IN_USE;
|
||||
rp->r_pid = -1;
|
||||
rproc_ptr[_ENDPOINT_P(rpub->endpoint)] = NULL;
|
||||
|
||||
/* Restore original IRQ and I/O range tables in the priv struct. This is the
|
||||
* only part of the privilege structure that can be modified by processes
|
||||
* other than RS itself.
|
||||
*/
|
||||
rp->r_priv.s_nr_irq = rp->r_nr_irq;
|
||||
for (i = 0; i < rp->r_nr_irq; i++)
|
||||
rp->r_priv.s_irq_tab[i] = rp->r_irq_tab[i];
|
||||
rp->r_priv.s_nr_io_range = rp->r_nr_io_range;
|
||||
for (i = 0; i < rp->r_nr_io_range; i++)
|
||||
rp->r_priv.s_io_tab[i] = rp->r_io_tab[i];
|
||||
|
||||
rp->r_old_rp = NULL;
|
||||
rp->r_new_rp = NULL;
|
||||
rp->r_prev_rp = NULL;
|
||||
rp->r_next_rp = NULL;
|
||||
|
||||
start_service(rp);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* terminate_service *
|
||||
*===========================================================================*/
|
||||
|
@ -959,9 +994,10 @@ PUBLIC void terminate_service(struct rproc *rp)
|
|||
|
||||
/* Deal with failures during initialization. */
|
||||
if(rp->r_flags & RS_INITIALIZING) {
|
||||
printf("RS: service '%s' exited during initialization\n", rpub->label);
|
||||
if(rs_verbose)
|
||||
printf("RS: service '%s' exited during initialization\n",
|
||||
rpub->label);
|
||||
rp->r_flags |= RS_EXITING; /* don't restart. */
|
||||
sys_sysctl_stacktrace(rp->r_pub->endpoint);
|
||||
|
||||
/* If updating, rollback. */
|
||||
if(rp->r_flags & RS_UPDATING) {
|
||||
|
@ -995,6 +1031,14 @@ PUBLIC void terminate_service(struct rproc *rp)
|
|||
for(i=0;i<nr_rps;i++) {
|
||||
cleanup_service(rps[i]);
|
||||
}
|
||||
|
||||
/* If the service is reincarnating, its slot has not been cleaned up.
|
||||
* Check for this flag now, and attempt to start the service again.
|
||||
* If this fails, start_service() itself will perform cleanup.
|
||||
*/
|
||||
if (rp->r_flags & RS_REINCARNATE) {
|
||||
reincarnate_service(rp);
|
||||
}
|
||||
}
|
||||
else if(rp->r_flags & RS_REFRESHING) {
|
||||
/* Restart service. */
|
||||
|
@ -1335,9 +1379,9 @@ endpoint_t source;
|
|||
printf("RS: edit_slot: too many IRQs requested\n");
|
||||
return EINVAL;
|
||||
}
|
||||
rp->r_priv.s_nr_irq= rs_start->rss_nr_irq;
|
||||
rp->r_nr_irq= rp->r_priv.s_nr_irq= rs_start->rss_nr_irq;
|
||||
for (i= 0; i<rp->r_priv.s_nr_irq; i++) {
|
||||
rp->r_priv.s_irq_tab[i]= rs_start->rss_irq[i];
|
||||
rp->r_irq_tab[i]= rp->r_priv.s_irq_tab[i]= rs_start->rss_irq[i];
|
||||
if(rs_verbose)
|
||||
printf("RS: edit_slot: IRQ %d\n", rp->r_priv.s_irq_tab[i]);
|
||||
}
|
||||
|
@ -1353,11 +1397,12 @@ endpoint_t source;
|
|||
printf("RS: edit_slot: too many I/O ranges requested\n");
|
||||
return EINVAL;
|
||||
}
|
||||
rp->r_priv.s_nr_io_range= rs_start->rss_nr_io;
|
||||
rp->r_nr_io_range= rp->r_priv.s_nr_io_range= rs_start->rss_nr_io;
|
||||
for (i= 0; i<rp->r_priv.s_nr_io_range; i++) {
|
||||
rp->r_priv.s_io_tab[i].ior_base= rs_start->rss_io[i].base;
|
||||
rp->r_priv.s_io_tab[i].ior_limit=
|
||||
rs_start->rss_io[i].base+rs_start->rss_io[i].len-1;
|
||||
rp->r_io_tab[i] = rp->r_priv.s_io_tab[i];
|
||||
if(rs_verbose)
|
||||
printf("RS: edit_slot: I/O [%x..%x]\n",
|
||||
rp->r_priv.s_io_tab[i].ior_base,
|
||||
|
|
|
@ -426,6 +426,8 @@ PUBLIC int do_init_ready(message *m_ptr)
|
|||
if(rs_verbose)
|
||||
printf("RS: %s initialization error: %s\n", srv_to_string(rp),
|
||||
init_strerror(result));
|
||||
if (result == ERESTART)
|
||||
rp->r_flags |= RS_REINCARNATE;
|
||||
crash_service(rp); /* simulate crash */
|
||||
return EDONTREPLY;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,12 @@ struct rproc {
|
|||
int r_quantum;
|
||||
int r_cpu;
|
||||
|
||||
/* Backup values from the privilege structure. */
|
||||
struct io_range r_io_tab[NR_IO_RANGE];
|
||||
int r_nr_io_range;
|
||||
int r_irq_tab[NR_IRQ];
|
||||
int r_nr_irq;
|
||||
|
||||
char r_ipc_list[MAX_IPC_LIST];
|
||||
int r_nr_control;
|
||||
char r_control[RS_NR_CONTROL][RS_MAX_LABEL_LEN];
|
||||
|
|
Loading…
Reference in a new issue