RS crash recovery support.

This commit is contained in:
Cristiano Giuffrida
2010-07-06 22:05:21 +00:00
parent e920c1e1df
commit 1f8dbed029
21 changed files with 429 additions and 200 deletions

View File

@@ -17,10 +17,11 @@ PUBLIC void panic(const char *fmt, ...)
*/
endpoint_t me = NONE;
char name[20];
int priv_flags;
void (*suicide)(void);
va_list args;
if(sys_whoami(&me, name, sizeof(name)) == OK && me != NONE)
if(sys_whoami(&me, name, sizeof(name), &priv_flags) == OK && me != NONE)
printf("%s(%d): panic: ", name, me);
else
printf("(sys_whoami failed): panic: ");

View File

@@ -7,6 +7,7 @@
#define SEF_SELF_NAME_MAXLEN 20
PUBLIC char sef_self_name[SEF_SELF_NAME_MAXLEN];
PUBLIC endpoint_t sef_self_endpoint;
PUBLIC int sef_self_priv_flags;
/* Debug. */
#define SEF_DEBUG_HEADER_MAXLEN 32
@@ -19,7 +20,7 @@ FORWARD _PROTOTYPE( void sef_debug_refresh_params, (void) );
PUBLIC _PROTOTYPE( char* sef_debug_header, (void) );
/* SEF Init prototypes. */
EXTERN _PROTOTYPE( int do_sef_rs_init, (void) );
EXTERN _PROTOTYPE( int do_sef_rs_init, (endpoint_t old_endpoint) );
EXTERN _PROTOTYPE( int do_sef_init_request, (message *m_ptr) );
/* SEF Ping prototypes. */
@@ -39,20 +40,34 @@ PUBLIC void sef_startup()
{
/* SEF startup interface for system services. */
int r, status;
endpoint_t old_endpoint;
/* Get information about self. */
r = sys_whoami(&sef_self_endpoint, sef_self_name, SEF_SELF_NAME_MAXLEN);
r = sys_whoami(&sef_self_endpoint, sef_self_name, SEF_SELF_NAME_MAXLEN,
&sef_self_priv_flags);
if ( r != OK) {
sef_self_endpoint = SELF;
sprintf(sef_self_name, "%s", "Unknown");
}
old_endpoint = NONE;
/* RS may wake up with the wrong endpoint, perfom the update in that case. */
if((sef_self_priv_flags & ROOT_SYS_PROC) && sef_self_endpoint != RS_PROC_NR) {
r = vm_update(RS_PROC_NR, sef_self_endpoint);
if(r != OK) {
panic("unable to update RS from instance %d to %d",
RS_PROC_NR, sef_self_endpoint);
}
old_endpoint = sef_self_endpoint;
sef_self_endpoint = RS_PROC_NR;
}
#if INTERCEPT_SEF_INIT_REQUESTS
/* Intercept SEF Init requests. */
if(sef_self_endpoint == RS_PROC_NR) {
if(sef_self_priv_flags & ROOT_SYS_PROC) {
/* RS initialization is special. */
if((r = do_sef_rs_init()) != OK) {
panic("unable to complete init: %d", r);
if((r = do_sef_rs_init(old_endpoint)) != OK) {
panic("RS unable to complete init: %d (%s)", r, strerror(-r));
}
}
else {

View File

@@ -1,5 +1,6 @@
#include "syslib.h"
#include <assert.h>
#include <unistd.h>
#include <minix/sysutil.h>
/* SEF Init callbacks. */
@@ -14,19 +15,79 @@ PRIVATE struct sef_cbs {
};
/* SEF Init prototypes for sef_startup(). */
PUBLIC _PROTOTYPE( int do_sef_rs_init, (void) );
PUBLIC _PROTOTYPE( int do_sef_rs_init, (endpoint_t old_endpoint) );
PUBLIC _PROTOTYPE( int do_sef_init_request, (message *m_ptr) );
/* Debug. */
EXTERN _PROTOTYPE( char* sef_debug_header, (void) );
/* Information about SELF. */
EXTERN endpoint_t sef_self_endpoint;
EXTERN endpoint_t sef_self_priv_flags;
/*===========================================================================*
* process_init *
*===========================================================================*/
PRIVATE int process_init(int type, sef_init_info_t *info)
{
/* Process initialization. */
int r;
/* Debug. */
#if SEF_INIT_DEBUG
sef_init_debug_begin();
sef_init_dprint("%s. Got a SEF Init request of type: %d. About to init.\n",
sef_debug_header(), type);
sef_init_debug_end();
#endif
/* Let the callback code handle the specific initialization type. */
switch(type) {
case SEF_INIT_FRESH:
r = sef_cbs.sef_cb_init_fresh(type, info);
break;
case SEF_INIT_LU:
r = sef_cbs.sef_cb_init_lu(type, info);
break;
case SEF_INIT_RESTART:
r = sef_cbs.sef_cb_init_restart(type, info);
break;
default:
/* Not a valid SEF init type. */
r = EINVAL;
break;
}
return r;
}
/*===========================================================================*
* do_sef_rs_init *
*===========================================================================*/
PUBLIC int do_sef_rs_init()
PUBLIC int do_sef_rs_init(endpoint_t old_endpoint)
{
/* Special SEF Init for RS. */
return sef_cbs.sef_cb_init_fresh(SEF_INIT_FRESH, NULL);
int r;
int type;
sef_init_info_t info;
/* Get init parameters from SEF. */
type = SEF_INIT_FRESH;
if(sef_self_priv_flags & LU_SYS_PROC) {
type = SEF_INIT_LU;
}
else if(sef_self_priv_flags & RST_SYS_PROC) {
type = SEF_INIT_RESTART;
}
info.rproctab_gid = -1;
info.endpoint = sef_self_endpoint;
info.old_endpoint = old_endpoint;
/* Peform initialization. */
r = process_init(type, &info);
return r;
}
/*===========================================================================*
@@ -39,34 +100,14 @@ PUBLIC int do_sef_init_request(message *m_ptr)
int type;
sef_init_info_t info;
/* Debug. */
#if SEF_INIT_DEBUG
sef_init_debug_begin();
sef_init_dprint("%s. Got a SEF Init request of type: %d. About to init.\n",
sef_debug_header(), m_ptr->RS_INIT_TYPE);
sef_init_debug_end();
#endif
/* Let the callback code handle the request. */
/* Get init parameters from message. */
type = m_ptr->RS_INIT_TYPE;
info.rproctab_gid = m_ptr->RS_INIT_RPROCTAB_GID;
info.endpoint = sef_self_endpoint;
info.old_endpoint = m_ptr->RS_INIT_OLD_ENDPOINT;
switch(type) {
case SEF_INIT_FRESH:
r = sef_cbs.sef_cb_init_fresh(type, &info);
break;
case SEF_INIT_LU:
r = sef_cbs.sef_cb_init_lu(type, &info);
break;
case SEF_INIT_RESTART:
r = sef_cbs.sef_cb_init_restart(type, &info);
break;
default:
/* Not a valid SEF init type. */
r = EINVAL;
break;
}
/* Peform initialization. */
r = process_init(type, &info);
/* Report back to RS. */
m_ptr->RS_INIT_RESULT = r;

View File

@@ -28,7 +28,8 @@ int len2; /* length or process nr */
/*===========================================================================*
* sys_whoami *
*===========================================================================*/
PUBLIC int sys_whoami(endpoint_t *who_ep, char *who_name, int len)
PUBLIC int sys_whoami(endpoint_t *who_ep, char *who_name, int len,
int *priv_flags)
{
message m;
int r;
@@ -47,6 +48,7 @@ PUBLIC int sys_whoami(endpoint_t *who_ep, char *who_name, int len)
strncpy(who_name, m.GIWHO_NAME, lenmin);
who_name[lenmin] = '\0';
*who_ep = m.GIWHO_EP;
*priv_flags = m.GIWHO_PRIVFLAGS;
return OK;
}