diff --git a/drivers/amddev/amddev.c b/drivers/amddev/amddev.c index 86267550e..342c969b6 100644 --- a/drivers/amddev/amddev.c +++ b/drivers/amddev/amddev.c @@ -49,7 +49,6 @@ static int dev_devind; static u8_t dev_capptr; static u8_t *table; -static int init(void); static int find_dev(int *devindp, u8_t *capaddrp); static u32_t read_reg(int function, int index); static void write_reg(int function, int index, u32_t value); @@ -65,6 +64,7 @@ static void report_exceptions(void); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); int main(void) { @@ -74,10 +74,6 @@ int main(void) /* SEF local startup. */ sef_local_startup(); - printf("amddev: starting\n"); - - init(); - for(;;) { report_exceptions(); @@ -106,6 +102,11 @@ int main(void) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard); @@ -114,12 +115,18 @@ PRIVATE void sef_local_startup() sef_startup(); } -static int init() +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { +/* Initialize the amddev driver. */ int r, n_maps, n_domains, revision; u16_t flags; u32_t bits; + printf("amddev: starting\n"); + r= find_dev(&dev_devind, &dev_capptr); if (!r) return r; @@ -147,6 +154,8 @@ static int init() write_reg(DEVF_CR, 0, 0x10 | 0x8 | 0x4 | 1); printf("after write: DEVF_CR: 0x%x\n", read_reg(DEVF_CR, 0)); + + return(OK); } static int find_dev(devindp, capaddrp) diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index 23c69b6fc..ee6a518f1 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -217,6 +217,7 @@ PRIVATE struct driver w_dtab = { /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) ); EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) ); EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) ); @@ -226,11 +227,43 @@ EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) ); *===========================================================================*/ PUBLIC int main(int argc, char *argv[]) { - struct sigaction sa; - /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); + /* Call the generic receive loop. */ + driver_task(&w_dtab, DRIVER_STD); + + return(OK); +} + +/*===========================================================================* + * sef_local_startup * + *===========================================================================*/ +PRIVATE void sef_local_startup() +{ + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid); + sef_setcb_lu_state_dump(sef_cb_lu_state_dump); + + /* Let SEF perform startup. */ + sef_startup(); +} + +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the at_wini driver. */ + struct sigaction sa; + /* Install signal handlers. Ask PM to transform signal into message. */ system_hz = sys_hz(); @@ -244,28 +277,13 @@ PUBLIC int main(int argc, char *argv[]) sa.sa_flags = 0; if (sigaction(SIGTERM,&sa,NULL)<0) panic("AT","sigaction failed", errno); - /* Set special disk parameters then call the generic main loop. */ - env_setargs(argc, argv); + /* Set special disk parameters. */ init_params(); signal(SIGTERM, SIG_IGN); - driver_task(&w_dtab, DRIVER_STD); + return(OK); } -/*===========================================================================* - * sef_local_startup * - *===========================================================================*/ -PRIVATE void sef_local_startup() -{ - /* Register live update callbacks. */ - sef_setcb_lu_prepare(sef_cb_lu_prepare); - sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid); - sef_setcb_lu_state_dump(sef_cb_lu_state_dump); - - /* Let SEF perform startup. */ - sef_startup(); -} - /*===========================================================================* * init_params * *===========================================================================*/ diff --git a/drivers/atl2/atl2.c b/drivers/atl2/atl2.c index e57a8983f..eefd3ea3a 100644 --- a/drivers/atl2/atl2.c +++ b/drivers/atl2/atl2.c @@ -91,6 +91,8 @@ PRIVATE struct { { 0x0000, 0x0000 } }; +long instance; + /*===========================================================================* * atl2_read_vpd * *===========================================================================*/ @@ -1237,39 +1239,19 @@ PRIVATE void atl2_dump(void) } /*===========================================================================* - * sef_local_startup * + * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE void sef_local_startup(void) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { - /* Initialize the System Event Framework. - */ - - /* No support for live update yet. */ - sef_startup(); -} - -/*===========================================================================* - * main * - *===========================================================================*/ -int main(int argc, char **argv) -{ - /* Driver task. - */ +/* Initialize the atl2 driver. */ u32_t inet_endpt; - message m; - sigset_t set; int r, devind; - long instance; #if ATL2_FKEY int fkeys, sfkeys; #endif - /* Initialize SEF. */ - sef_local_startup(); - /* How many matching devices should we skip? */ instance = 0; - env_setargs(argc, argv); env_parse("atl2_instance", "d", 0, &instance, 0, 32); /* Try to find a recognized device. */ @@ -1296,6 +1278,39 @@ int main(int argc, char **argv) printf("ATL2: warning, could not map Shift+F11 key (%d)\n", r); #endif + return(OK); +} + +/*===========================================================================* + * sef_local_startup * + *===========================================================================*/ +PRIVATE void sef_local_startup(void) +{ + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + + /* No support for live update yet. */ + + /* Let SEF perform startup. */ + sef_startup(); +} + +/*===========================================================================* + * main * + *===========================================================================*/ +int main(int argc, char **argv) +{ + /* Driver task. + */ + message m; + sigset_t set; + int r; + + /* Initialize SEF. */ + env_setargs(argc, argv); + sef_local_startup(); + while (TRUE) { if ((r = sef_receive(ANY, &m)) != OK) panic("atl2", "sef_receive failed", r); diff --git a/drivers/audio/framework/audio_fw.c b/drivers/audio/framework/audio_fw.c index 84951eb7c..be719cef1 100644 --- a/drivers/audio/framework/audio_fw.c +++ b/drivers/audio/framework/audio_fw.c @@ -79,6 +79,7 @@ PRIVATE device_available = 0;/*todo*/ /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) ); EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) ); EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) ); @@ -92,8 +93,6 @@ PUBLIC void main(void) /* SEF local startup. */ sef_local_startup(); - drv_init(); - /* Here is the main loop of the dma driver. It waits for a message, carries it out, and sends a reply. */ @@ -185,6 +184,11 @@ PUBLIC void main(void) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid); @@ -194,6 +198,15 @@ PRIVATE void sef_local_startup() sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the audio driver framework. */ + return init_driver(); +} + PRIVATE int init_driver(void) { u32_t i; char irq; static int executed = 0; diff --git a/drivers/bios_wini/bios_wini.c b/drivers/bios_wini/bios_wini.c index c14ce12da..a62650e86 100644 --- a/drivers/bios_wini/bios_wini.c +++ b/drivers/bios_wini/bios_wini.c @@ -96,23 +96,19 @@ PRIVATE struct driver w_dtab = { /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * bios_winchester_task * *===========================================================================*/ PUBLIC int main() { - long v; - /* SEF local startup. */ sef_local_startup(); - v= 0; - env_parse("bios_remap_first", "d", 0, &v, 0, 1); - remap_first= v; - -/* Set special disk parameters then call the generic main loop. */ + /* Call the generic receive loop. */ driver_task(&w_dtab, DRIVER_STD); + return(OK); } @@ -121,6 +117,11 @@ PUBLIC int main() *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard); @@ -129,6 +130,21 @@ PRIVATE void sef_local_startup() sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the bios_wini driver. */ + long v; + + v = 0; + env_parse("bios_remap_first", "d", 0, &v, 0, 1); + remap_first = v; + + return(OK); +} + /*===========================================================================* * w_prepare * *===========================================================================*/ diff --git a/drivers/dp8390/dp8390.c b/drivers/dp8390/dp8390.c index 9dfac7d63..bedede9c9 100644 --- a/drivers/dp8390/dp8390.c +++ b/drivers/dp8390/dp8390.c @@ -234,6 +234,9 @@ PRIVATE int handle_hw_intr(void) /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); +EXTERN int env_argc; +EXTERN char **env_argv; /*===========================================================================* * dpeth_task * @@ -241,38 +244,11 @@ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); int main(int argc, char *argv[]) { message m; - int i, r, tasknr; - dpeth_t *dep; - long v; + int r; /* SEF local startup. */ - sef_local_startup(); - - system_hz = sys_hz(); - - if (argc < 1) - { - panic("DP8390", - "A head which at this time has no name", NO_NUM); - } - (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]); - env_setargs(argc, argv); - - for (i= 0, dep= de_table; ide_name, "dp8390#0"); - dep->de_name[7] += i; - } - - v= 0; - (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); - eth_ign_proto= htons((u16_t) v); - - /* Try to notify inet that we are present (again) */ - r = _pm_findproc("inet", &tasknr); - if (r == OK) - notify(tasknr); + sef_local_startup(); while (TRUE) { @@ -331,12 +307,54 @@ int main(int argc, char *argv[]) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the dp8390 driver. */ + int i, r, tasknr; + dpeth_t *dep; + long v; + + system_hz = sys_hz(); + + if (env_argc < 1) + { + panic("DP8390", + "A head which at this time has no name", NO_NUM); + } + (progname=strrchr(env_argv[0],'/')) ? progname++ + : (progname=env_argv[0]); + + for (i= 0, dep= de_table; ide_name, "dp8390#0"); + dep->de_name[7] += i; + } + + v= 0; + (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); + eth_ign_proto= htons((u16_t) v); + + /* Try to notify inet that we are present (again) */ + r = _pm_findproc("inet", &tasknr); + if (r == OK) + notify(tasknr); + + return(OK); +} + #if 0 /*===========================================================================* * dp8390_dump * diff --git a/drivers/dpeth/dp.c b/drivers/dpeth/dp.c index 7de00b474..c8ca4ea2c 100644 --- a/drivers/dpeth/dp.c +++ b/drivers/dpeth/dp.c @@ -579,6 +579,9 @@ PRIVATE void handle_hw_intr(void) /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); +EXTERN int env_argc; +EXTERN char **env_argv; /* ** Name: int dpeth_task(void) @@ -588,34 +591,11 @@ PUBLIC int main(int argc, char **argv) { message m; dpeth_t *dep; - int rc, fkeys, sfkeys, tasknr; + int rc; /* SEF local startup. */ - sef_local_startup(); - - (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]); - env_setargs(argc, argv); - - /* Request function key for debug dumps */ - fkeys = sfkeys = 0; bit_set(sfkeys, 8); - if ((fkey_map(&fkeys, &sfkeys)) != OK) - printf("%s: couldn't program Shift+F8 key (%d)\n", DevName, errno); - -#ifdef ETH_IGN_PROTO - { - static u16_t eth_ign_proto = 0; - long val; - val = 0xFFFF; - env_parse("ETH_IGN_PROTO", "x", 0, &val, 0x0000L, 0xFFFFL); - eth_ign_proto = htons((u16_t) val); - } -#endif - - /* Try to notify inet that we are present (again) */ - rc = _pm_findproc("inet", &tasknr); - if (rc == OK) - notify(tasknr); + sef_local_startup(); while (TRUE) { if ((rc = sef_receive(ANY, &m)) != OK) panic(dep->de_name, RecvErrMsg, rc); @@ -680,10 +660,48 @@ PUBLIC int main(int argc, char **argv) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the dpeth driver. */ + dpeth_t *dep; + int rc, fkeys, sfkeys, tasknr; + + (progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]); + + /* Request function key for debug dumps */ + fkeys = sfkeys = 0; bit_set(sfkeys, 8); + if ((fkey_map(&fkeys, &sfkeys)) != OK) + printf("%s: couldn't program Shift+F8 key (%d)\n", DevName, errno); + +#ifdef ETH_IGN_PROTO + { + static u16_t eth_ign_proto = 0; + long val; + val = 0xFFFF; + env_parse("ETH_IGN_PROTO", "x", 0, &val, 0x0000L, 0xFFFFL); + eth_ign_proto = htons((u16_t) val); + } +#endif + + /* Try to notify inet that we are present (again) */ + rc = _pm_findproc("inet", &tasknr); + if (rc == OK) + notify(tasknr); + + return(OK); +} + /** dp.c **/ diff --git a/drivers/e1000/e1000.c b/drivers/e1000/e1000.c index 22c5a4ebb..28ed13d30 100644 --- a/drivers/e1000/e1000.c +++ b/drivers/e1000/e1000.c @@ -64,6 +64,9 @@ _PROTOTYPE( PRIVATE void mess_reply, (message *req, message *reply) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); +EXTERN int env_argc; +EXTERN char **env_argv; /*===========================================================================* * main * @@ -71,40 +74,12 @@ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); int main(int argc, char *argv[]) { message m; - int i, r; - u32_t tasknr; - e1000_t *e; - long v; + int r; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - /* Verify command-line arguments. */ - if (argc < 1) - { - panic("e1000", "no program name given in argc/argv", NO_NUM); - } - else - (progname = strrchr(argv[0],'/')) ? progname++ : (progname = argv[0]); - - /* Clear state. */ - memset(e1000_table, 0, sizeof(e1000_table)); - - /* Perform calibration. */ - if((r = micro_delay_calibrate()) != OK) - { - panic("e1000", "rmicro_delay_calibrate failed", r); - } - /* Try to notify inet that we are present (again) */ - if ((r = ds_retrieve_u32("inet", &tasknr)) == OK) - { - notify(tasknr); - } - else if (r != ESRCH) - { - printf("e1000: ds_retrieve_u32 failed for 'inet': %d\n", r); - } - /* * Enter the main driver loop. */ @@ -150,12 +125,55 @@ int main(int argc, char *argv[]) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the e1000 driver. */ + int r; + u32_t tasknr; + + /* Verify command-line arguments. */ + if (env_argc < 1) + { + panic("e1000", "no program name given in argc/argv", NO_NUM); + } + else + (progname = strrchr(env_argv[0],'/')) ? progname++ + : (progname = env_argv[0]); + + /* Clear state. */ + memset(e1000_table, 0, sizeof(e1000_table)); + + /* Perform calibration. */ + if((r = micro_delay_calibrate()) != OK) + { + panic("e1000", "rmicro_delay_calibrate failed", r); + } + /* Try to notify inet that we are present (again) */ + if ((r = ds_retrieve_u32("inet", &tasknr)) == OK) + { + notify(tasknr); + } + else if (r != ESRCH) + { + printf("e1000: ds_retrieve_u32 failed for 'inet': %d\n", r); + } + + return(OK); +} + /*===========================================================================* * e1000_init * *===========================================================================*/ diff --git a/drivers/filter/main.c b/drivers/filter/main.c index 834f4e212..1d7fd5a64 100644 --- a/drivers/filter/main.c +++ b/drivers/filter/main.c @@ -73,6 +73,12 @@ static cp_grant_id_t grant_id; /* IO_GRANT */ /* Data buffers. */ static char *buf_array, *buffer; /* contiguous buffer */ +/* SEF functions and variables. */ +FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); +EXTERN int env_argc; +EXTERN char **env_argv; + /*===========================================================================* * carry * *===========================================================================*/ @@ -384,17 +390,6 @@ static void got_signal(void) exit(0); } -/*===========================================================================* - * sef_local_startup * - *===========================================================================*/ -static void sef_local_startup(void) -{ - /* No live update support for now. */ - - /* Let SEF perform startup. */ - sef_startup(); -} - /*===========================================================================* * main * *===========================================================================*/ @@ -404,21 +399,9 @@ int main(int argc, char *argv[]) int r; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - r = parse_arguments(argc, argv); - if(r != OK) { - printf("Filter: wrong argument!\n"); - return 1; - } - - if ((buf_array = flt_malloc(BUF_SIZE, NULL, 0)) == NULL) - panic(__FILE__, "no memory available", NO_NUM); - - sum_init(); - - driver_init(); - for (;;) { /* Wait for request. */ if(sef_receive(ANY, &m_in) != OK) { @@ -466,3 +449,43 @@ int main(int argc, char *argv[]) return 0; } + +/*===========================================================================* + * sef_local_startup * + *===========================================================================*/ +PRIVATE void sef_local_startup(void) +{ + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + + /* No live update support for now. */ + + /* Let SEF perform startup. */ + sef_startup(); +} + +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the filter driver. */ + int r; + + r = parse_arguments(env_argc, env_argv); + if(r != OK) { + printf("Filter: wrong argument!\n"); + return 1; + } + + if ((buf_array = flt_malloc(BUF_SIZE, NULL, 0)) == NULL) + panic(__FILE__, "no memory available", NO_NUM); + + sum_init(); + + driver_init(); + + return(OK); +} + diff --git a/drivers/floppy/floppy.c b/drivers/floppy/floppy.c index 3788d8a3d..00700d310 100644 --- a/drivers/floppy/floppy.c +++ b/drivers/floppy/floppy.c @@ -292,6 +292,7 @@ static phys_bytes floppy_buf_phys; /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) ); EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) ); EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) ); @@ -300,14 +301,45 @@ PUBLIC int last_transfer_opcode; /*===========================================================================* * floppy_task * *===========================================================================*/ -PUBLIC void main() +PUBLIC int main() { - struct floppy *fp; - int s; - /* SEF local startup. */ sef_local_startup(); + /* Call the generic receive loop. */ + driver_task(&f_dtab, DRIVER_STD); + + return(OK); +} + +/*===========================================================================* + * sef_local_startup * + *===========================================================================*/ +PRIVATE void sef_local_startup() +{ + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + + /* Register live update callbacks. */ + sef_setcb_lu_prepare(sef_cb_lu_prepare); + sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid); + sef_setcb_lu_state_dump(sef_cb_lu_state_dump); + + /* Let SEF perform startup. */ + sef_startup(); +} + +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the floppy driver. */ + struct floppy *fp; + int s; + /* Initialize the floppy structure and the timers. */ system_hz = sys_hz(); @@ -337,21 +369,7 @@ PUBLIC void main() /* Ignore signals */ signal(SIGHUP, SIG_IGN); - driver_task(&f_dtab, DRIVER_STD); -} - -/*===========================================================================* - * sef_local_startup * - *===========================================================================*/ -PRIVATE void sef_local_startup() -{ - /* Register live update callbacks. */ - sef_setcb_lu_prepare(sef_cb_lu_prepare); - sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid); - sef_setcb_lu_state_dump(sef_cb_lu_state_dump); - - /* Let SEF perform startup. */ - sef_startup(); + return(OK); } /*===========================================================================* diff --git a/drivers/floppy/floppy.h b/drivers/floppy/floppy.h index 6d737ab7e..49e16225e 100644 --- a/drivers/floppy/floppy.h +++ b/drivers/floppy/floppy.h @@ -2,6 +2,6 @@ #include "../libdriver/driver.h" #include "../libdriver/drvlib.h" -_PROTOTYPE(void main, (void)); +_PROTOTYPE(int main, (void)); diff --git a/drivers/fxp/fxp.c b/drivers/fxp/fxp.c index 576f2f27b..1d3dbba6e 100644 --- a/drivers/fxp/fxp.c +++ b/drivers/fxp/fxp.c @@ -303,6 +303,9 @@ PRIVATE void handle_hw_intr(void) /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); +EXTERN int env_argc; +EXTERN char **env_argv; /*===========================================================================* * main * @@ -310,42 +313,12 @@ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); int main(int argc, char *argv[]) { message m; - int i, r; - u32_t tasknr; - long v; - vir_bytes ft = sizeof(*fxp_table)*FXP_PORT_NR; + int r; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - system_hz = sys_hz(); - - if (argc < 1) - panic("FXP", "A head which at this time has no name", NO_NUM); - (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]); - - v= 0; -#if 0 - (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); -#endif - eth_ign_proto= htons((u16_t) v); - - if(!(fxp_table = alloc_contig(ft, 0, &fxp_table_phys))) - panic("FXP","couldn't allocate table", r); - - memset(fxp_table, 0, ft); - - if((r=micro_delay_calibrate()) != OK) - panic("FXP","rmicro_delay_calibrate failed", r); - - /* Try to notify inet that we are present (again) */ - r= ds_retrieve_u32("inet", &tasknr); - if (r == OK) - notify(tasknr); - else if (r != ESRCH) - printf("fxp: ds_retrieve_u32 failed for 'inet': %d\n", r); - - while (TRUE) { if ((r= sef_receive(ANY, &m)) != OK) @@ -401,12 +374,59 @@ int main(int argc, char *argv[]) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the fxp driver. */ + int r; + u32_t tasknr; + long v; + vir_bytes ft; + + ft = sizeof(*fxp_table)*FXP_PORT_NR; + system_hz = sys_hz(); + + if (env_argc < 1) + panic("FXP", "A head which at this time has no name", NO_NUM); + (progname=strrchr(env_argv[0],'/')) ? progname++ + : (progname=env_argv[0]); + + v= 0; +#if 0 + (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); +#endif + eth_ign_proto= htons((u16_t) v); + + if(!(fxp_table = alloc_contig(ft, 0, &fxp_table_phys))) + panic("FXP","couldn't allocate table", r); + + memset(fxp_table, 0, ft); + + if((r=micro_delay_calibrate()) != OK) + panic("FXP","rmicro_delay_calibrate failed", r); + + /* Try to notify inet that we are present (again) */ + r= ds_retrieve_u32("inet", &tasknr); + if (r == OK) + notify(tasknr); + else if (r != ESRCH) + printf("fxp: ds_retrieve_u32 failed for 'inet': %d\n", r); + + return(OK); +} + /*===========================================================================* * fxp_init * *===========================================================================*/ diff --git a/drivers/lance/lance.c b/drivers/lance/lance.c index 5975f9a3d..c6a49e19c 100644 --- a/drivers/lance/lance.c +++ b/drivers/lance/lance.c @@ -267,6 +267,9 @@ phys_bytes lance_buf_phys; /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); +EXTERN int env_argc; +EXTERN char **env_argv; /*===========================================================================* * main * @@ -275,38 +278,12 @@ void main( int argc, char **argv ) { message m; int i,irq,r; - u32_t tasknr; ether_card_t *ec; - long v; -#if LANCE_FKEY - int fkeys, sfkeys; -#endif /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]); - - env_setargs( argc, argv ); - -#if LANCE_FKEY - fkeys = sfkeys = 0; - bit_set( sfkeys, 7 ); - if ( (r = fkey_map(&fkeys, &sfkeys)) != OK ) - printf("Warning: lance couldn't observe Shift+F7 key: %d\n",r); -#endif - - v= 0; - (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); - eth_ign_proto= htons((u16_t) v); - - /* Try to notify inet that we are present (again) */ - r= ds_retrieve_u32("inet", &tasknr); - if (r == OK) - notify(tasknr); - else if (r != ESRCH) - printf("lance: ds_retrieve_u32 failed for 'inet': %d\n", r); - while (TRUE) { for (i=0;im_source); + printf("PCI: do_init: called by '%d'\n", mp->m_source); #endif mp->m_type= 0; @@ -363,7 +360,7 @@ message *mp; for (i= 0; i= NR_DRIVERS) @@ -375,18 +372,18 @@ message *mp; gid= mp->m1_i1; - r= sys_safecopyfrom(mp->m_source, gid, 0, (vir_bytes)&acl[i].acl, - sizeof(acl[i].acl), D); + r= sys_safecopyfrom(mp->m_source, gid, 0, (vir_bytes)&pci_acl[i].acl, + sizeof(pci_acl[i].acl), D); if (r != OK) { printf("PCI: do_set_acl: safecopyfrom failed\n"); reply(mp, r); return; } - acl[i].inuse= 1; + pci_acl[i].inuse= 1; if(debug) printf("PCI: do_acl: setting ACL for %d ('%s') at entry %d\n", - acl[i].acl.rsp_endpoint, acl[i].acl.rsp_label, + pci_acl[i].acl.rsp_endpoint, pci_acl[i].acl.rsp_label, i); reply(mp, OK); @@ -408,9 +405,9 @@ message *mp; for (i= 0; i #include #include #include -#include #include #include "pci.h" @@ -86,6 +85,8 @@ PRIVATE struct pcidev int pd_bar_nr; } pcidev[NR_PCIDEV]; +EXTERN struct pci_acl *pci_acl; + /* pb_flags */ #define PBF_IO 1 /* I/O else memory */ #define PBF_INCOMPLETE 2 /* not allocated */ @@ -149,6 +150,75 @@ FORWARD _PROTOTYPE( void print_capabilities, (int devind) ); FORWARD _PROTOTYPE( int visible, (struct rs_pci *aclp, int devind) ); FORWARD _PROTOTYPE( void print_hyper_cap, (int devind, U8_t capptr) ); +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PUBLIC int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the pci driver. */ + long v; + int i, r; + struct rprocpub rprocpub[NR_BOOT_PROCS]; + + v= 0; + env_parse("pci_debug", "d", 0, &v, 0, 1); + debug= v; + + /* Only Intel (compatible) PCI controllers are supported at the + * moment. + */ + pci_intel_init(); + + /* Map all the services in the boot image. */ + if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0, + (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK) { + panic("pci", "sys_safecopyfrom failed", r); + } + for(i=0;i < NR_BOOT_PROCS;i++) { + if(rprocpub[i].in_use) { + if((r = map_service(&rprocpub[i])) != OK) { + panic("pci", "unable to map service", r); + } + } + } + + return(OK); +} + +/*===========================================================================* + * map_service * + *===========================================================================*/ +PUBLIC int map_service(rpub) +struct rprocpub *rpub; +{ +/* Map a new service by registering a new acl entry if required. */ + int i; + + /* Stop right now if no pci device or class is found. */ + if(rpub->pci_acl.rsp_nr_device == 0 + && rpub->pci_acl.rsp_nr_class == 0) { + return(OK); + } + + /* Find a free acl slot. */ + for (i= 0; i= NR_DRIVERS) + { + printf("PCI: map_service: table is full\n"); + return ENOMEM; + } + + /* Initialize acl slot. */ + pci_acl[i].inuse = 1; + pci_acl[i].acl = rpub->pci_acl; + + return(OK); +} + /*===========================================================================* * helper functions for I/O * *===========================================================================*/ @@ -189,34 +259,6 @@ PUBLIC void pci_outl(U16_t port, U32_t value) { printf("PCI: warning, sys_outl failed: %d\n", s); } -/*===========================================================================* - * pci_init * - *===========================================================================*/ -PUBLIC void pci_init() -{ - static int first_time= 1; - - long v; - - if (!first_time) - return; - - v= 0; - env_parse("pci_debug", "d", 0, &v, 0, 1); - debug= v; - - /* We don't expect to interrupted */ - assert(first_time == 1); - first_time= -1; - - /* Only Intel (compatible) PCI controllers are supported at the - * moment. - */ - pci_intel_init(); - - first_time= 0; -} - /*===========================================================================* * pci_find_dev * *===========================================================================*/ diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 387aca7d7..0f53d0ccf 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -4,6 +4,8 @@ pci.h Created: Jan 2000 by Philip Homburg */ +#include + /* tempory functions: to be replaced later (see pci_intel.h) */ _PROTOTYPE( unsigned pci_inb, (U16_t port) ); _PROTOTYPE( unsigned pci_inw, (U16_t port) ); @@ -61,6 +63,14 @@ struct pci_pcibridge int type; }; +struct pci_acl +{ + int inuse; + struct rs_pci acl; +}; + +#define NR_DRIVERS NR_SYS_PROCS + #define PCI_IB_PIIX 1 /* Intel PIIX compatible ISA bridge */ #define PCI_IB_VIA 2 /* VIA compatible ISA bridge */ #define PCI_IB_AMD 3 /* AMD compatible ISA bridge */ @@ -81,7 +91,9 @@ extern struct pci_intel_ctrl pci_intel_ctrl[]; extern struct pci_isabridge pci_isabridge[]; extern struct pci_pcibridge pci_pcibridge[]; -/* Utility functions */ +/* Function prototypes. */ +_PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); +_PROTOTYPE( int map_service, (struct rprocpub *rpub) ); _PROTOTYPE( int pci_reserve2, (int devind, endpoint_t proc) ); _PROTOTYPE( void pci_release, (endpoint_t proc) ); _PROTOTYPE( int pci_first_dev_a, (struct rs_pci *aclp, int *devindp, diff --git a/drivers/printer/printer.c b/drivers/printer/printer.c index e61153d5f..021921f91 100644 --- a/drivers/printer/printer.c +++ b/drivers/printer/printer.c @@ -117,6 +117,7 @@ FORWARD _PROTOTYPE( void do_signal, (void) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) ); EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) ); EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) ); @@ -129,18 +130,10 @@ PUBLIC void main(void) { /* Main routine of the printer task. */ message pr_mess; /* buffer for all incoming messages */ - struct sigaction sa; - int s; /* SEF local startup. */ sef_local_startup(); - /* Install signal handlers. Ask PM to transform signal into message. */ - sa.sa_handler = SIG_MESS; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - if (sigaction(SIGTERM,&sa,NULL)<0) panic("PRN","sigaction failed", errno); - while (TRUE) { sef_receive(ANY, &pr_mess); @@ -180,6 +173,11 @@ PUBLIC void main(void) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid); @@ -189,6 +187,23 @@ PRIVATE void sef_local_startup() sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the printer driver. */ + struct sigaction sa; + + /* Install signal handlers. Ask PM to transform signal into message. */ + sa.sa_handler = SIG_MESS; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGTERM,&sa,NULL)<0) panic("PRN","sigaction failed", errno); + + return(OK); +} + /*===========================================================================* * do_signal * *===========================================================================*/ diff --git a/drivers/random/main.c b/drivers/random/main.c index 97024a806..bb1d332e3 100644 --- a/drivers/random/main.c +++ b/drivers/random/main.c @@ -26,7 +26,6 @@ FORWARD _PROTOTYPE( struct device *r_prepare, (int device) ); FORWARD _PROTOTYPE( int r_transfer, (int proc_nr, int opcode, u64_t position, iovec_t *iov, unsigned nr_req) ); FORWARD _PROTOTYPE( int r_do_open, (struct driver *dp, message *m_ptr) ); -FORWARD _PROTOTYPE( void r_init, (void) ); FORWARD _PROTOTYPE( int r_ioctl, (struct driver *dp, message *m_ptr) ); FORWARD _PROTOTYPE( void r_geometry, (struct partition *entry) ); FORWARD _PROTOTYPE( void r_random, (struct driver *dp, message *m_ptr) ); @@ -56,6 +55,7 @@ PRIVATE char random_buf[RANDOM_BUF_SIZE]; /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * main * @@ -65,8 +65,9 @@ PUBLIC int main(void) /* SEF local startup. */ sef_local_startup(); - r_init(); /* initialize the memory driver */ - driver_task(&r_dtab, DRIVER_ASYN); /* start driver's main loop */ + /* Call the generic receive loop. */ + driver_task(&r_dtab, DRIVER_ASYN); + return(OK); } @@ -75,6 +76,11 @@ PUBLIC int main(void) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard); @@ -83,6 +89,40 @@ PRIVATE void sef_local_startup() sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the random driver. */ + static struct k_randomness krandom; + int i, s; + + random_init(); + r_random(NULL, NULL); /* also set periodic timer */ + + /* Retrieve first randomness buffer with parameters. */ + if (OK != (s=sys_getrandomness(&krandom))) { + report("RANDOM", "sys_getrandomness failed", s); + exit(1); + } + + /* Do sanity check on parameters. */ + if(krandom.random_sources != RANDOM_SOURCES || + krandom.random_elements != RANDOM_ELEMENTS) { + printf("random: parameters (%d, %d) don't match kernel's (%d, %d)\n", + RANDOM_SOURCES, RANDOM_ELEMENTS, + krandom.random_sources, krandom.random_elements); + exit(1); + } + + /* Feed initial batch. */ + for(i = 0; i < RANDOM_SOURCES; i++) + r_updatebin(i, &krandom.bin[i]); + + return(OK); +} + /*===========================================================================* * r_name * *===========================================================================*/ @@ -199,37 +239,6 @@ message *m_ptr; return(OK); } -/*===========================================================================* - * r_init * - *===========================================================================*/ -PRIVATE void r_init() -{ - static struct k_randomness krandom; - int i, s; - - random_init(); - r_random(NULL, NULL); /* also set periodic timer */ - - /* Retrieve first randomness buffer with parameters. */ - if (OK != (s=sys_getrandomness(&krandom))) { - report("RANDOM", "sys_getrandomness failed", s); - exit(1); - } - - /* Do sanity check on parameters. */ - if(krandom.random_sources != RANDOM_SOURCES || - krandom.random_elements != RANDOM_ELEMENTS) { - printf("random: parameters (%d, %d) don't match kernel's (%d, %d)\n", - RANDOM_SOURCES, RANDOM_ELEMENTS, - krandom.random_sources, krandom.random_elements); - exit(1); - } - - /* Feed initial batch. */ - for(i = 0; i < RANDOM_SOURCES; i++) - r_updatebin(i, &krandom.bin[i]); -} - /*===========================================================================* * r_ioctl * *===========================================================================*/ diff --git a/drivers/readclock/readclock.c b/drivers/readclock/readclock.c index df5dcbd05..3ae06b633 100644 --- a/drivers/readclock/readclock.c +++ b/drivers/readclock/readclock.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -103,6 +104,7 @@ int main(int argc, char **argv) struct sysgetenv sysgetenv; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); if((s=sys_readbios(MACH_ID_ADDR, &mach_id, sizeof(mach_id))) != OK) { diff --git a/drivers/rtl8139/rtl8139.c b/drivers/rtl8139/rtl8139.c index d4b91d771..e709ea43f 100644 --- a/drivers/rtl8139/rtl8139.c +++ b/drivers/rtl8139/rtl8139.c @@ -193,52 +193,23 @@ u32_t system_hz; /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) ); EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) ); EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) ); +EXTERN int env_argc; +EXTERN char **env_argv; /*===========================================================================* - * main * + * main * *===========================================================================*/ int main(int argc, char *argv[]) { - int fkeys, sfkeys; - u32_t inet_proc_nr; - int i, r; - re_t *rep; - long v; + int r; /* SEF local startup. */ - sef_local_startup(); - - system_hz = sys_hz(); - - (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]); - env_setargs(argc, argv); - - v= 0; - (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); - eth_ign_proto= htons((u16_t) v); - - /* Observe some function key for debug dumps. */ - fkeys = sfkeys = 0; bit_set(sfkeys, 9); - if ((r=fkey_map(&fkeys, &sfkeys)) != OK) - printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r); - - /* Claim buffer memory now under Minix, before MM takes it all. */ - for (rep= &re_table[0]; rep < re_table+RE_PORT_NR; rep++) - rl_init_buf(rep); - - /* Try to notify INET that we are present (again). If INET cannot - * be found, assume this is the first time we started and INET is - * not yet alive. - */ - r= ds_retrieve_u32("inet", &inet_proc_nr); - if (r == OK) - notify(inet_proc_nr); - else if (r != ESRCH) - printf("rtl8139: ds_retrieve_u32 failed for 'inet': %d\n", r); + sef_local_startup(); while (TRUE) { @@ -317,6 +288,11 @@ int main(int argc, char *argv[]) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid); @@ -326,6 +302,49 @@ PRIVATE void sef_local_startup() sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the rtl8139 driver. */ + int fkeys, sfkeys; + u32_t inet_proc_nr; + int r; + re_t *rep; + long v; + + system_hz = sys_hz(); + + (progname=strrchr(env_argv[0],'/')) ? progname++ + : (progname=env_argv[0]); + + v= 0; + (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); + eth_ign_proto= htons((u16_t) v); + + /* Observe some function key for debug dumps. */ + fkeys = sfkeys = 0; bit_set(sfkeys, 9); + if ((r=fkey_map(&fkeys, &sfkeys)) != OK) + printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r); + + /* Claim buffer memory now under Minix, before MM takes it all. */ + for (rep= &re_table[0]; rep < re_table+RE_PORT_NR; rep++) + rl_init_buf(rep); + + /* Try to notify INET that we are present (again). If INET cannot + * be found, assume this is the first time we started and INET is + * not yet alive. + */ + r= ds_retrieve_u32("inet", &inet_proc_nr); + if (r == OK) + notify(inet_proc_nr); + else if (r != ESRCH) + printf("rtl8139: ds_retrieve_u32 failed for 'inet': %d\n", r); + + return(OK); +} + /*===========================================================================* * check_int_events * *===========================================================================*/ diff --git a/drivers/rtl8169/rtl8169.c b/drivers/rtl8169/rtl8169.c index e5b46b3a3..867701289 100644 --- a/drivers/rtl8169/rtl8169.c +++ b/drivers/rtl8169/rtl8169.c @@ -286,46 +286,21 @@ u32_t system_hz; /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); +EXTERN int env_argc; +EXTERN char **env_argv; /*===========================================================================* * main * *===========================================================================*/ int main(int argc, char *argv[]) { - u32_t inet_proc_nr; int r; - re_t *rep; - long v; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - system_hz = sys_hz(); - - (progname = strrchr(argv[0], '/')) ? progname++ : (progname = argv[0]); - - env_setargs(argc, argv); - - v = 0; - (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); - eth_ign_proto = htons((u16_t) v); - - /* Claim buffer memory now under Minix, before MM takes it all. */ - for (rep = &re_table[0]; rep < re_table + RE_PORT_NR; rep++) - rl_init_buf(rep); - - /* - * Try to notify INET that we are present (again). If INET cannot - * be found, assume this is the first time we started and INET is - * not yet alive. - */ -#if 0 - r = ds_retrieve_u32("inet", &inet_proc_nr); - if (r == OK) - notify(inet_proc_nr); - else if (r != ESRCH) - printf("rtl8169: ds_retrieve_u32 failed for 'inet': %d\n", r); -#endif while (TRUE) { if ((r = sef_receive(ANY, &m)) != OK) panic("rtl8169", "sef_receive failed", r); @@ -391,12 +366,56 @@ int main(int argc, char *argv[]) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the rtl8169 driver. */ + u32_t inet_proc_nr; + int r; + re_t *rep; + long v; + + system_hz = sys_hz(); + + (progname = strrchr(env_argv[0], '/')) ? progname++ + : (progname = env_argv[0]); + + v = 0; + (void) env_parse("ETH_IGN_PROTO", "x", 0, &v, 0x0000L, 0xFFFFL); + eth_ign_proto = htons((u16_t) v); + + /* Claim buffer memory now under Minix, before MM takes it all. */ + for (rep = &re_table[0]; rep < re_table + RE_PORT_NR; rep++) + rl_init_buf(rep); + + /* + * Try to notify INET that we are present (again). If INET cannot + * be found, assume this is the first time we started and INET is + * not yet alive. + */ +#if 0 + r = ds_retrieve_u32("inet", &inet_proc_nr); + if (r == OK) + notify(inet_proc_nr); + else if (r != ESRCH) + printf("rtl8169: ds_retrieve_u32 failed for 'inet': %d\n", r); +#endif + + return(OK); +} + static void mdio_write(U16_t port, int regaddr, int value) { int i; diff --git a/drivers/sb16/sb16_dsp.c b/drivers/sb16/sb16_dsp.c index 954e05689..d4ade9fb0 100644 --- a/drivers/sb16/sb16_dsp.c +++ b/drivers/sb16/sb16_dsp.c @@ -37,7 +37,6 @@ FORWARD _PROTOTYPE( void dsp_hardware_msg, (void) ); FORWARD _PROTOTYPE( void dsp_status, (message *m_ptr) ); FORWARD _PROTOTYPE( void reply, (int code, int replyee, int process, int status) ); -FORWARD _PROTOTYPE( void init_buffer, (void) ); FORWARD _PROTOTYPE( int dsp_init, (void) ); FORWARD _PROTOTYPE( int dsp_reset, (void) ); FORWARD _PROTOTYPE( int dsp_command, (int value) ); @@ -79,6 +78,7 @@ PRIVATE int reviveProcNr; /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) ); EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) ); EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) ); @@ -90,17 +90,12 @@ PUBLIC int is_status_msg_expected = FALSE; *===========================================================================*/ PUBLIC void main() { - int r, caller, proc_nr, s; + int r, caller, proc_nr; message mess; /* SEF local startup. */ sef_local_startup(); - dprint("sb16_dsp.c: main()\n"); - - /* Get a DMA buffer. */ - init_buffer(); - while(TRUE) { /* Wait for an incoming message */ sef_receive(ANY, &mess); @@ -152,6 +147,11 @@ send_reply: *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid); @@ -161,6 +161,33 @@ PRIVATE void sef_local_startup() sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the rtl8169 driver. */ + unsigned left; + + /* Select a buffer that can safely be used for dma transfers. + * Its absolute address is 'DmaPhys', the normal address is 'DmaPtr'. + */ +#if (CHIP == INTEL) + DmaPtr = DmaBuffer; + sys_umap(SELF, D, (vir_bytes)DmaBuffer, (phys_bytes)sizeof(DmaBuffer), &DmaPhys); + + if((left = dma_bytes_left(DmaPhys)) < DMA_SIZE) { + /* First half of buffer crosses a 64K boundary, can't DMA into that */ + DmaPtr += left; + DmaPhys += left; + } +#else /* CHIP != INTEL */ + panic("SB16DSP","initialization failed, CHIP != INTEL", 0); +#endif /* CHIP == INTEL */ + + return(OK); +} + /*===========================================================================* * dsp_open *===========================================================================*/ @@ -392,33 +419,6 @@ int status; send(replyee, &m); } - -/*===========================================================================* - * init_buffer - *===========================================================================*/ -PRIVATE void init_buffer() -{ -/* Select a buffer that can safely be used for dma transfers. - * Its absolute address is 'DmaPhys', the normal address is 'DmaPtr'. - */ - -#if (CHIP == INTEL) - unsigned left; - - DmaPtr = DmaBuffer; - sys_umap(SELF, D, (vir_bytes)DmaBuffer, (phys_bytes)sizeof(DmaBuffer), &DmaPhys); - - if((left = dma_bytes_left(DmaPhys)) < DMA_SIZE) { - /* First half of buffer crosses a 64K boundary, can't DMA into that */ - DmaPtr += left; - DmaPhys += left; - } -#else /* CHIP != INTEL */ - panic("SB16DSP","init_buffer() failed, CHIP != INTEL", 0); -#endif /* CHIP == INTEL */ -} - - /*===========================================================================* * dsp_init *===========================================================================*/ diff --git a/drivers/sb16/sb16_mixer.c b/drivers/sb16/sb16_mixer.c index 03b698022..87fbf37e1 100644 --- a/drivers/sb16/sb16_mixer.c +++ b/drivers/sb16/sb16_mixer.c @@ -47,7 +47,7 @@ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); * main *===========================================================================*/ PUBLIC void main() { -message mess; + message mess; int err, caller, proc_nr; /* SEF local startup. */ diff --git a/drivers/ti1225/ti1225.c b/drivers/ti1225/ti1225.c index dcb29779d..83e5a8fe8 100644 --- a/drivers/ti1225/ti1225.c +++ b/drivers/ti1225/ti1225.c @@ -51,7 +51,6 @@ PRIVATE struct pcitab pcitab_ti[]= PRIVATE char *progname; PRIVATE int debug; -FORWARD _PROTOTYPE( void init, (void) ); FORWARD _PROTOTYPE( void hw_init, (struct port *pp) ); FORWARD _PROTOTYPE( void map_regs, (struct port *pp, u32_t base) ); FORWARD _PROTOTYPE( void do_int, (struct port *pp) ); @@ -61,33 +60,22 @@ FORWARD _PROTOTYPE( u8_t do_inb, (port_t port) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); +EXTERN int env_argc; +EXTERN char **env_argv; +/*===========================================================================* + * main * + *===========================================================================*/ int main(int argc, char *argv[]) { - int c, r; + int r; message m; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - (progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]); - - if((r=micro_delay_calibrate()) != OK) - panic("ti1225", "micro_delay_calibrate failed", r); - - debug= 0; - while (c= getopt(argc, argv, "d?"), c != -1) - { - switch(c) - { - case '?': panic("ti1225", "Usage: ti1225 [-d]", NO_NUM); - case 'd': debug++; break; - default: panic("ti1225", "getopt failed", NO_NUM); - } - } - - init(); - for (;;) { r= sef_receive(ANY, &m); @@ -104,6 +92,11 @@ int main(int argc, char *argv[]) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard); @@ -112,11 +105,32 @@ PRIVATE void sef_local_startup() sef_startup(); } -PRIVATE void init() +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { - int i, r, first, devind, port; +/* Initialize the ti1225 driver. */ + int c, i, r, first, devind, port; u16_t vid, did; + (progname=strrchr(env_argv[0],'/')) ? progname++ + : (progname=env_argv[0]); + + if((r=micro_delay_calibrate()) != OK) + panic("ti1225", "micro_delay_calibrate failed", r); + + debug= 0; + while (c= getopt(env_argc, env_argv, "d?"), c != -1) + { + switch(c) + { + case '?': panic("ti1225", "Usage: ti1225 [-d]", NO_NUM); + case 'd': debug++; break; + default: panic("ti1225", "getopt failed", NO_NUM); + } + } + pci_init1(progname); first= 1; @@ -167,6 +181,8 @@ PRIVATE void init() continue; hw_init(&ports[i]); } + + return(OK); } PRIVATE void hw_init(pp) diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index e2445b977..51f7d3781 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -149,6 +149,7 @@ extern PUBLIC phys_bytes vid_base; /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * tty_task * @@ -159,23 +160,12 @@ PUBLIC int main(void) message tty_mess; /* buffer for all incoming messages */ unsigned line; - int r, s; + int r; register tty_t *tp; /* SEF local startup. */ sef_local_startup(); - /* Get kernel environment (protected_mode, pc_at and ega are needed). */ - if (OK != (s=sys_getmachine(&machine))) { - panic("TTY","Couldn't obtain kernel environment.", s); - } - - /* Initialize the TTY driver. */ - tty_init(); - - /* Final one-time keyboard initialization. */ - kb_init_once(); - while (TRUE) { int adflag = 0; @@ -338,12 +328,38 @@ PUBLIC int main(void) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the tty driver. */ + int r; + + /* Get kernel environment (protected_mode, pc_at and ega are needed). */ + if (OK != (r=sys_getmachine(&machine))) { + panic("TTY","Couldn't obtain kernel environment.", r); + } + + /* Initialize the TTY driver. */ + tty_init(); + + /* Final one-time keyboard initialization. */ + kb_init_once(); + + return(OK); +} + /*===========================================================================* * got_signal * *===========================================================================*/ diff --git a/include/minix/com.h b/include/minix/com.h index 4cc3bd199..318ee380d 100644 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -352,6 +352,7 @@ # define SYS_RUNCTL (KERNEL_CALL + 46) /* sys_runctl() */ #define NR_SYS_CALLS 47 /* number of system calls */ +#define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS) /* Field names for SYS_MEMSET. */ #define MEM_PTR m2_p1 /* base */ @@ -626,6 +627,7 @@ #define RS_LOOKUP (RS_RQ_BASE + 8) /* lookup server name */ +#define RS_INIT (RS_RQ_BASE + 20) /* service init message */ #define RS_LU_PREPARE (RS_RQ_BASE + 21) /* prepare to update message */ # define RS_CMD_ADDR m1_p1 /* command string */ @@ -638,6 +640,10 @@ # define RS_NAME m1_p1 /* name */ # define RS_NAME_LEN m1_i1 /* namelen */ +# define RS_INIT_RESULT m1_i1 /* init result */ +# define RS_INIT_TYPE m1_i2 /* init type */ +# define RS_INIT_RPROCTAB_GID m1_i3 /* init rproc table gid */ + # define RS_LU_RESULT m1_i1 /* live update result */ # define RS_LU_STATE m1_i2 /* state required to update */ # define RS_LU_PREPARE_MAXTIME m1_i3 /* the max time to prepare */ @@ -959,7 +965,12 @@ #define VCTLP_STATS_EP 2 /* Total. */ -#define VM_NCALLS 41 +#define NR_VM_CALLS 41 +#define VM_CALL_MASK_SIZE BITMAP_CHUNKS(NR_VM_CALLS) + +/* Basic vm calls allowed to every process. */ +#define VM_BASIC_CALLS \ + VM_MMAP, VM_MUNMAP, VM_MUNMAP_TEXT, VM_MAP_PHYS, VM_UNMAP_PHYS /*===========================================================================* * Messages for IPC server * diff --git a/include/minix/config.h b/include/minix/config.h index 3eed5950d..ddea7339e 100644 --- a/include/minix/config.h +++ b/include/minix/config.h @@ -38,6 +38,7 @@ */ #define NR_PROCS _NR_PROCS #define NR_SYS_PROCS _NR_SYS_PROCS +#define NR_SYS_CHUNKS BITMAP_CHUNKS(NR_SYS_PROCS) /* Number of controller tasks (/dev/cN device classes). */ #define NR_CTRLRS 2 diff --git a/include/minix/rs.h b/include/minix/rs.h index c07807dbb..ae784485a 100644 --- a/include/minix/rs.h +++ b/include/minix/rs.h @@ -8,13 +8,25 @@ Interface to the reincarnation server */ #include +#include +/* RSS definitions. */ #define RSS_NR_IRQ 16 #define RSS_NR_IO 16 -#define RSS_NR_PCI_ID 32 -#define RSS_NR_PCI_CLASS 4 -#define RSS_NR_SYSTEM 2 -#define RSS_NR_CONTROL 8 + +/* RSS flags. */ +#define RSS_COPY 0x01 /* Copy the brinary into RS to make it possible + * to restart the driver without accessing FS + */ +#define RSS_IPC_VALID 0x02 /* rss_ipc and rss_ipclen are valid */ +#define RSS_REUSE 0x04 /* Try to reuse previously copied binary */ + +/* Common definitions. */ +#define RS_SYS_CALL_MASK_SIZE 2 +#define RS_NR_CONTROL 8 +#define RS_NR_PCI_DEVICE 32 +#define RS_NR_PCI_CLASS 4 +#define RS_MAX_LABEL_LEN 16 /* Labels are copied over separately. */ struct rss_label @@ -40,38 +52,45 @@ struct rs_start int rss_nr_io; struct { unsigned base; unsigned len; } rss_io[RSS_NR_IO]; int rss_nr_pci_id; - struct { u16_t vid; u16_t did; } rss_pci_id[RSS_NR_PCI_ID]; + struct { u16_t vid; u16_t did; } rss_pci_id[RS_NR_PCI_DEVICE]; int rss_nr_pci_class; - struct { u32_t class; u32_t mask; } rss_pci_class[RSS_NR_PCI_CLASS]; - u32_t rss_system[RSS_NR_SYSTEM]; + struct { u32_t class; u32_t mask; } rss_pci_class[RS_NR_PCI_CLASS]; + u32_t rss_system[RS_SYS_CALL_MASK_SIZE]; struct rss_label rss_label; char *rss_ipc; size_t rss_ipclen; -#define RSS_VM_CALL_SIZE BITMAP_CHUNKS(VM_NCALLS) - bitchunk_t rss_vm[RSS_VM_CALL_SIZE]; + bitchunk_t rss_vm[VM_CALL_MASK_SIZE]; int rss_nr_control; - struct rss_label rss_control[RSS_NR_CONTROL]; + struct rss_label rss_control[RS_NR_CONTROL]; }; -#define RF_COPY 0x01 /* Copy the brinary into RS to make it possible - * to restart the driver without accessing FS - */ -#define RF_IPC_VALID 0x02 /* rss_ipc and rss_ipclen are valid */ -#define RF_REUSE 0x04 /* Try to reuse previously copied binary */ - -#define RSP_LABEL_SIZE 16 -#define RSP_NR_DEVICE 32 -#define RSP_NR_CLASS 4 - /* ACL information for access to PCI devices */ struct rs_pci { - char rsp_label[RSP_LABEL_SIZE]; /* Name of the driver */ + char rsp_label[RS_MAX_LABEL_LEN]; int rsp_endpoint; int rsp_nr_device; - struct { u16_t vid; u16_t did; } rsp_device[RSP_NR_DEVICE]; + struct { u16_t vid; u16_t did; } rsp_device[RS_NR_PCI_DEVICE]; int rsp_nr_class; - struct { u32_t class; u32_t mask; } rsp_class[RSP_NR_CLASS]; + struct { u32_t class; u32_t mask; } rsp_class[RS_NR_PCI_CLASS]; +}; + +/* Definition of a public entry of the system process table. */ +struct rprocpub { + short in_use; /* set when the entry is in use */ + unsigned sys_flags; /* sys flags */ + endpoint_t endpoint; /* process endpoint number */ + + dev_t dev_nr; /* major device number */ + int dev_style; /* device style */ + long period; /* heartbeat period (or zero) */ + + char label[RS_MAX_LABEL_LEN]; /* label of this service */ + char proc_name[RS_MAX_LABEL_LEN]; /* process name of this service */ + + bitchunk_t vm_call_mask[VM_CALL_MASK_SIZE]; /* vm call mask */ + + struct rs_pci pci_acl; /* pci acl */ }; _PROTOTYPE( int minix_rs_lookup, (const char *name, endpoint_t *value)); diff --git a/include/minix/sef.h b/include/minix/sef.h index 26a573475..e2fe145f3 100644 --- a/include/minix/sef.h +++ b/include/minix/sef.h @@ -13,6 +13,61 @@ _PROTOTYPE( int sef_receive, (endpoint_t src, message *m_ptr) ); #define sef_debug_begin() (void)(NULL) #define sef_debug_end() fflush(stdout) +/*===========================================================================* + * SEF Init * + *===========================================================================*/ +/* What to intercept. */ +#define INTERCEPT_SEF_INIT_REQUESTS 1 +#define IS_SEF_INIT_REQUEST(mp) ((mp)->m_type == RS_INIT \ + && (mp)->m_source == RS_PROC_NR) + +/* Type definitions. */ +typedef struct { + int rproctab_gid; +} sef_init_info_t; + +/* Callback type definitions. */ +typedef int(*sef_cb_init_fresh_t)(int type, sef_init_info_t *info); +typedef int(*sef_cb_init_lu_t)(int type, sef_init_info_t *info); +typedef int(*sef_cb_init_restart_t)(int type, sef_init_info_t *info); + +/* Callback registration helpers. */ +_PROTOTYPE( void sef_setcb_init_fresh, (sef_cb_init_fresh_t cb)); +_PROTOTYPE( void sef_setcb_init_lu, (sef_cb_init_lu_t cb)); +_PROTOTYPE( void sef_setcb_init_restart, (sef_cb_init_restart_t cb)); + +/* Predefined callback implementations. */ +_PROTOTYPE( int sef_cb_init_fresh_null, (int type, sef_init_info_t *info) ); +_PROTOTYPE( int sef_cb_init_lu_null, (int type, sef_init_info_t *info) ); +_PROTOTYPE( int sef_cb_init_restart_null, (int type, sef_init_info_t *info) ); + +_PROTOTYPE( int sef_cb_init_restart_fail, (int type, sef_init_info_t *info) ); + +/* Macros for predefined callback implementations. */ +#define SEF_CB_INIT_FRESH_NULL sef_cb_init_fresh_null +#define SEF_CB_INIT_LU_NULL sef_cb_init_lu_null +#define SEF_CB_INIT_RESTART_NULL sef_cb_init_restart_null + +#define SEF_CB_INIT_FRESH_DEFAULT sef_cb_init_fresh_null +#define SEF_CB_INIT_LU_DEFAULT sef_cb_init_lu_null +#define SEF_CB_INIT_RESTART_DEFAULT sef_cb_init_restart_null + +/* Init types. */ +#define SEF_INIT_FRESH 0 /* init fresh */ +#define SEF_INIT_LU 1 /* init after live update */ +#define SEF_INIT_RESTART 2 /* init after restart */ + +/* Debug. */ +#define SEF_INIT_DEBUG_DEFAULT 0 + +#ifndef SEF_INIT_DEBUG +#define SEF_INIT_DEBUG SEF_INIT_DEBUG_DEFAULT +#endif + +#define sef_init_dprint sef_dprint +#define sef_init_debug_begin sef_debug_begin +#define sef_init_debug_end sef_debug_end + /*===========================================================================* * SEF Ping * *===========================================================================*/ diff --git a/include/unistd.h b/include/unistd.h index 18814b544..5c25f64fc 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -49,6 +49,7 @@ #define SI_KPROC_TAB 7 /* copy of kernel process table */ #define SI_CALL_STATS 8 /* system call statistics */ #define SI_PCI_INFO 9 /* get kernel info via PM */ +#define SI_PROCPUB_TAB 10 /* copy of public entries of process table */ /* NULL must be defined in according to POSIX Sec. 2.7.1. */ #define NULL ((void *)0) diff --git a/kernel/const.h b/kernel/const.h index 771291241..ef05149af 100644 --- a/kernel/const.h +++ b/kernel/const.h @@ -30,7 +30,6 @@ ( MAP_CHUNK(map.chunk,bit) |= (1 << CHUNK_OFFSET(bit) ) #define unset_sys_bit(map,bit) \ ( MAP_CHUNK(map.chunk,bit) &= ~(1 << CHUNK_OFFSET(bit) ) -#define NR_SYS_CHUNKS BITMAP_CHUNKS(NR_SYS_PROCS) #define reallock do { int d; d = intr_disabled(); intr_disable(); locklevel++; if(d && locklevel == 1) { minix_panic("reallock while interrupts disabled first time", __LINE__); } } while(0) diff --git a/kernel/main.c b/kernel/main.c index 94df07380..8a76110f7 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -126,7 +126,7 @@ PUBLIC void main() } /* Fill in kernel call mask. */ - for(j = 0; j < CALL_MASK_SIZE; j++) { + for(j = 0; j < SYS_CALL_MASK_SIZE; j++) { priv(rp)->s_k_call_mask[j] = (kcalls == NO_C ? 0 : (~0)); } } diff --git a/kernel/priv.h b/kernel/priv.h index 12d2d8cff..d05a22683 100644 --- a/kernel/priv.h +++ b/kernel/priv.h @@ -40,8 +40,7 @@ struct priv { sys_map_t s_ipc_to; /* allowed destination processes */ /* allowed kernel calls */ -#define CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS) - bitchunk_t s_k_call_mask[CALL_MASK_SIZE]; + bitchunk_t s_k_call_mask[SYS_CALL_MASK_SIZE]; sys_map_t s_notify_pending; /* bit map with pending notifications */ irq_id_t s_int_pending; /* pending hardware interrupts */ diff --git a/kernel/system/do_privctl.c b/kernel/system/do_privctl.c index d32ade0dc..7081d3190 100644 --- a/kernel/system/do_privctl.c +++ b/kernel/system/do_privctl.c @@ -97,7 +97,7 @@ message *m_ptr; /* pointer to request message */ priv(rp)->s_id = priv_id; /* restore privilege id */ priv(rp)->s_proc_nr = proc_nr; /* reassociate process nr */ - for (i=0; i< BITMAP_CHUNKS(NR_SYS_PROCS); i++) /* remove pending: */ + for (i=0; i< NR_SYS_CHUNKS; i++) /* remove pending: */ priv(rp)->s_notify_pending.chunk[i] = 0; /* - notifications */ priv(rp)->s_int_pending = 0; /* - interrupts */ sigemptyset(&priv(rp)->s_sig_pending); /* - signals */ @@ -107,7 +107,7 @@ message *m_ptr; /* pointer to request message */ priv(rp)->s_trap_mask= DEF_SYS_T; /* allowed traps */ ipc_to_m = DEF_SYS_M; /* allowed targets */ kcalls = DEF_SYS_KC; /* allowed kernel calls */ - for(i = 0; i < CALL_MASK_SIZE; i++) { + for(i = 0; i < SYS_CALL_MASK_SIZE; i++) { priv(rp)->s_k_call_mask[i] = (kcalls == NO_C ? 0 : (~0)); } diff --git a/kernel/system/do_safecopy.c b/kernel/system/do_safecopy.c index 22eaa0637..aa171551f 100644 --- a/kernel/system/do_safecopy.c +++ b/kernel/system/do_safecopy.c @@ -113,7 +113,8 @@ endpoint_t *e_granter; /* new granter (magic grants) */ /* Verify actual grantee. */ if(g.cp_u.cp_indirect.cp_who_to != grantee && - grantee != ANY) { + grantee != ANY && + g.cp_u.cp_indirect.cp_who_to != ANY) { kprintf( "verify_grant: indirect grant verify " "failed: bad grantee\n"); @@ -147,7 +148,8 @@ endpoint_t *e_granter; /* new granter (magic grants) */ } /* Verify actual grantee. */ - if(g.cp_u.cp_direct.cp_who_to != grantee && grantee != ANY) { + if(g.cp_u.cp_direct.cp_who_to != grantee && grantee != ANY + && g.cp_u.cp_direct.cp_who_to != ANY) { kprintf( "verify_grant: direct grant verify failed: bad grantee\n"); return EPERM; @@ -180,7 +182,8 @@ endpoint_t *e_granter; /* new granter (magic grants) */ } /* Verify actual grantee. */ - if(g.cp_u.cp_magic.cp_who_to != grantee && grantee != ANY) { + if(g.cp_u.cp_magic.cp_who_to != grantee && grantee != ANY + && g.cp_u.cp_direct.cp_who_to != ANY) { kprintf( "verify_grant: magic grant verify failed: bad grantee\n"); return EPERM; diff --git a/lib/syslib/Makefile.in b/lib/syslib/Makefile.in index e09f9513e..da20eba46 100644 --- a/lib/syslib/Makefile.in +++ b/lib/syslib/Makefile.in @@ -30,6 +30,7 @@ libsys_FILES=" \ sef.c \ sef_liveupdate.c \ sef_ping.c \ + sef_init.c \ sys_abort.c \ sys_cprof.c \ sys_endsig.c \ diff --git a/lib/syslib/safecopies.c b/lib/syslib/safecopies.c index d09a789e5..3159f6f09 100644 --- a/lib/syslib/safecopies.c +++ b/lib/syslib/safecopies.c @@ -37,6 +37,8 @@ } \ } +#define NR_STATIC_GRANTS 2 +PRIVATE cp_grant_t static_grants[NR_STATIC_GRANTS]; PRIVATE cp_grant_t *grants = NULL; PRIVATE int ngrants = 0; @@ -48,12 +50,19 @@ cpf_grow(void) cp_grant_id_t g; int new_size; - new_size = (1+ngrants)*2; - assert(new_size > ngrants); + if(!ngrants) { + /* Use statically allocated grants the first time. */ + new_size = NR_STATIC_GRANTS; + new_grants = static_grants; + } + else { + new_size = (1+ngrants)*2; + assert(new_size > ngrants); - /* Allocate a block of new size. */ - if(!(new_grants=malloc(new_size * sizeof(grants[0])))) { - return; + /* Allocate a block of new size. */ + if(!(new_grants=malloc(new_size * sizeof(grants[0])))) { + return; + } } /* Copy old block to new block. */ @@ -66,12 +75,12 @@ cpf_grow(void) /* Inform kernel about new size (and possibly new location). */ if((sys_setgrant(new_grants, new_size))) { - free(new_grants); + if(new_grants != static_grants) free(new_grants); return; /* Failed - don't grow then. */ } /* Update internal data. */ - if(grants && ngrants > 0) free(grants); + if(grants && ngrants > 0 && grants != static_grants) free(grants); grants = new_grants; ngrants = new_size; } diff --git a/lib/syslib/sef.c b/lib/syslib/sef.c index 3f1d145d3..a2536d8d7 100644 --- a/lib/syslib/sef.c +++ b/lib/syslib/sef.c @@ -18,6 +18,10 @@ PRIVATE char sef_debug_header_buff[SEF_DEBUG_HEADER_MAXLEN]; 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_init_request, (message *m_ptr) ); + /* SEF Live update prototypes. */ EXTERN _PROTOTYPE( void do_sef_lu_before_receive, (void) ); EXTERN _PROTOTYPE( int do_sef_lu_request, (message *m_ptr) ); @@ -39,6 +43,30 @@ PUBLIC void sef_startup() sef_self_endpoint = SELF; sprintf(sef_self_name, "%s", "Unknown"); } + +#if INTERCEPT_SEF_INIT_REQUESTS + /* Intercept SEF Init requests. */ + if(sef_self_endpoint == RS_PROC_NR) { + if((r = do_sef_rs_init()) != OK) { + panic("SEF", "unable to complete init", r); + } + } + else { + message m; + + if((r = receive(RS_PROC_NR, &m)) != OK) { + panic("SEF", "unable to receive from RS", r); + } + if(IS_SEF_INIT_REQUEST(&m)) { + if((r = do_sef_init_request(&m)) != OK) { + panic("SEF", "unable to process init request", r); + } + } + else { + panic("SEF", "unable to receive init request", NO_NUM); + } + } +#endif } /*===========================================================================* diff --git a/lib/syslib/sef_init.c b/lib/syslib/sef_init.c new file mode 100644 index 000000000..a6d8e8de7 --- /dev/null +++ b/lib/syslib/sef_init.c @@ -0,0 +1,137 @@ +#include "syslib.h" +#include +#include + +/* SEF Init callbacks. */ +PRIVATE struct sef_cbs { + sef_cb_init_fresh_t sef_cb_init_fresh; + sef_cb_init_lu_t sef_cb_init_lu; + sef_cb_init_restart_t sef_cb_init_restart; +} sef_cbs = { + SEF_CB_INIT_FRESH_DEFAULT, + SEF_CB_INIT_LU_DEFAULT, + SEF_CB_INIT_RESTART_DEFAULT +}; + +/* SEF Init prototypes for sef_startup(). */ +PUBLIC _PROTOTYPE( int do_sef_rs_init, (void) ); +PUBLIC _PROTOTYPE( int do_sef_init_request, (message *m_ptr) ); + +/* Debug. */ +EXTERN _PROTOTYPE( char* sef_debug_header, (void) ); + +/*===========================================================================* + * do_sef_rs_init * + *===========================================================================*/ +PUBLIC int do_sef_rs_init() +{ +/* Special SEF Init for RS. */ + return sef_cbs.sef_cb_init_fresh(SEF_INIT_FRESH, NULL); +} + +/*===========================================================================* + * do_sef_init_request * + *===========================================================================*/ +PUBLIC int do_sef_init_request(message *m_ptr) +{ +/* Handle a SEF Init request. */ + int r; + 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. */ + type = m_ptr->RS_INIT_TYPE; + info.rproctab_gid = m_ptr->RS_INIT_RPROCTAB_GID; + 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; + } + + /* Report back to RS. XXX FIXME: we should use send, but this would cause + * a deadlock due to the current blocking nature of mapdriver(). + */ + m_ptr->RS_INIT_RESULT = r; + r = asynsend(RS_PROC_NR, m_ptr); + + return r; +} + +/*===========================================================================* + * sef_setcb_init_fresh * + *===========================================================================*/ +PUBLIC void sef_setcb_init_fresh(sef_cb_init_fresh_t cb) +{ + assert(cb != NULL); + sef_cbs.sef_cb_init_fresh = cb; +} + +/*===========================================================================* + * sef_setcb_init_lu * + *===========================================================================*/ +PUBLIC void sef_setcb_init_lu(sef_cb_init_lu_t cb) +{ + assert(cb != NULL); + sef_cbs.sef_cb_init_lu = cb; +} + +/*===========================================================================* + * sef_setcb_init_restart * + *===========================================================================*/ +PUBLIC void sef_setcb_init_restart(sef_cb_init_restart_t cb) +{ + assert(cb != NULL); + sef_cbs.sef_cb_init_restart = cb; +} + +/*===========================================================================* + * sef_cb_init_fresh_null * + *===========================================================================*/ +PUBLIC int sef_cb_init_fresh_null(int type, sef_init_info_t *info) +{ + return(OK); +} + +/*===========================================================================* + * sef_cb_init_lu_null * + *===========================================================================*/ +PUBLIC int sef_cb_init_lu_null(int type, sef_init_info_t *info) +{ + return(OK); +} + +/*===========================================================================* + * sef_cb_init_restart_null * + *===========================================================================*/ +PUBLIC int sef_cb_init_restart_null(int type, sef_init_info_t *info) +{ + return(OK); +} + +/*===========================================================================* + * sef_cb_init_restart_fail * + *===========================================================================*/ +PUBLIC int sef_cb_init_restart_fail(int type, sef_init_info_t *info) +{ + return(ENOSYS); +} + diff --git a/lib/sysutil/env_get_prm.c b/lib/sysutil/env_get_prm.c index c69cdf52c..a67694956 100644 --- a/lib/sysutil/env_get_prm.c +++ b/lib/sysutil/env_get_prm.c @@ -2,8 +2,8 @@ #include #include -PRIVATE int argc = 0; -PRIVATE char **argv = NULL; +PUBLIC int env_argc = 0; +PUBLIC char **env_argv = NULL; FORWARD _PROTOTYPE( char *find_key, (const char *params, const char *key)); @@ -14,8 +14,8 @@ PUBLIC void env_setargs(arg_c, arg_v) int arg_c; char *arg_v[]; { - argc= arg_c; - argv= arg_v; + env_argc= arg_c; + env_argv= arg_v; } /*===========================================================================* @@ -35,15 +35,15 @@ int max_len; /* maximum length of value */ return EINVAL; keylen= strlen(key); - for (i= 1; i max_len) return(E2BIG); strcpy(value, key_value); diff --git a/servers/ds/inc.h b/servers/ds/inc.h index 76c97455e..9aef23a35 100644 --- a/servers/ds/inc.h +++ b/servers/ds/inc.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/servers/ds/main.c b/servers/ds/main.c index 978da669b..6dcacd1d8 100644 --- a/servers/ds/main.c +++ b/servers/ds/main.c @@ -19,7 +19,6 @@ int sys_panic; /* flag to indicate system-wide panic */ extern int errno; /* error number set by system library */ /* Declare some local functions. */ -FORWARD _PROTOTYPE(void init_server, (int argc, char **argv) ); FORWARD _PROTOTYPE(void exit_server, (void) ); FORWARD _PROTOTYPE(void sig_handler, (void) ); FORWARD _PROTOTYPE(void get_work, (message *m_ptr) ); @@ -42,11 +41,9 @@ PUBLIC int main(int argc, char **argv) sigset_t sigset; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - /* Initialize the server, then go to work. */ - init_server(argc, argv); - /* Main loop - get work and do it, forever. */ while (TRUE) { @@ -104,25 +101,16 @@ send_reply: *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_restart_fail); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } -/*===========================================================================* - * init_server * - *===========================================================================*/ -PRIVATE void init_server(int argc, char **argv) -{ -/* Initialize the data store server. */ - int i, s; - struct sigaction sigact; - - /* Initialize DS. */ - ds_init(); -} - /*===========================================================================* * sig_handler * *===========================================================================*/ diff --git a/servers/ds/proto.h b/servers/ds/proto.h index e5d1435de..6844e976f 100644 --- a/servers/ds/proto.h +++ b/servers/ds/proto.h @@ -9,4 +9,6 @@ _PROTOTYPE(int do_retrieve, (message *m_ptr)); _PROTOTYPE(int do_subscribe, (message *m_ptr)); _PROTOTYPE(int do_check, (message *m_ptr)); _PROTOTYPE(int do_getsysinfo, (message *m_ptr)); -_PROTOTYPE(void ds_init, (void)); +_PROTOTYPE(int sef_cb_init_fresh, (int type, sef_init_info_t *info)); +_PROTOTYPE(int map_service, (struct rprocpub *rpub)); + diff --git a/servers/ds/store.c b/servers/ds/store.c index 86018ee26..6fc06f3ae 100644 --- a/servers/ds/store.c +++ b/servers/ds/store.c @@ -14,14 +14,15 @@ PRIVATE _PROTOTYPE(void check_subscribers, (struct data_store *dsp)); /*===========================================================================* - * ds_init * + * sef_cb_init_fresh * *===========================================================================*/ -PUBLIC void ds_init(void) +PUBLIC int sef_cb_init_fresh(int type, sef_init_info_t *info) { - int i; +/* Initialize the data store server. */ + int i, r; + struct rprocpub rprocpub[NR_BOOT_PROCS]; /* Reset data store: data and subscriptions. */ - for(i = 0; i < NR_DS_KEYS; i++) { int b; ds_store[i].ds_flags = 0; @@ -32,7 +33,42 @@ PUBLIC void ds_init(void) for(i = 0; i < NR_DS_SUBS; i++) ds_subs[i].sub_flags = 0; - return; + /* Map all the services in the boot image. */ + if((r = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0, + (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK) { + panic("DS", "sys_safecopyfrom failed", r); + } + for(i=0;i < NR_BOOT_PROCS;i++) { + if(rprocpub[i].in_use) { + if((r = map_service(&rprocpub[i])) != OK) { + panic("DS", "unable to map service", r); + } + } + } + + return(OK); +} + +/*===========================================================================* + * map_service * + *===========================================================================*/ +PUBLIC int map_service(rpub) +struct rprocpub *rpub; +{ +/* Map a new service by registering its label. */ + struct data_store *dsp; + + dsp = &ds_store[nr_in_use]; /* new slot found */ + strcpy(dsp->ds_key, rpub->label); + dsp->ds_flags = DS_IN_USE | DS_TYPE_U32; /* initialize slot */ + nr_in_use++; + + dsp->ds_val.ds_val_u32 = (u32_t) rpub->endpoint; /* store data */ + + /* If anyone has a matching subscription, update them. */ + check_subscribers(dsp); + + return(OK); } PRIVATE int set_owner(dsp, auth) diff --git a/servers/inet/inet.c b/servers/inet/inet.c index c82050f67..d833f6959 100644 --- a/servers/inet/inet.c +++ b/servers/inet/inet.c @@ -95,98 +95,17 @@ FORWARD _PROTOTYPE( void nw_init, (void) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); PUBLIC void main() { mq_t *mq; int r; - int source, m_type, timerand, fd; - u32_t tasknr; - struct fssignon device; - u8_t randbits[32]; - struct timeval tv; + int source, m_type; /* SEF local startup. */ sef_local_startup(); -#if DEBUG - printf("Starting inet...\n"); - printf("%s\n", version); -#endif - -#if HZ_DYNAMIC - system_hz = sys_hz(); -#endif - - /* Read configuration. */ - nw_conf(); - - /* Get a random number */ - timerand= 1; - fd= open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK); - if (fd != -1) - { - r= read(fd, randbits, sizeof(randbits)); - if (r == sizeof(randbits)) - timerand= 0; - else - { - printf("inet: unable to read random data from %s: %s\n", - RANDOM_DEV_NAME, r == -1 ? strerror(errno) : - r == 0 ? "EOF" : "not enough data"); - } - close(fd); - } - else - { - printf("inet: unable to open random device %s: %s\n", - RANDOM_DEV_NAME, strerror(errno)); - } - if (timerand) - { - printf("inet: using current time for random-number seed\n"); - r= gettimeofday(&tv, NULL); - if (r == -1) - { - printf("sysutime failed: %s\n", strerror(errno)); - exit(1); - } - memcpy(randbits, &tv, sizeof(tv)); - } - init_rand256(randbits); - - /* Our new identity as a server. */ - r= ds_retrieve_u32("inet", &tasknr); - if (r != OK) - ip_panic(("inet: ds_retrieve_u32 failed for 'inet': %d", r)); - this_proc= tasknr; - - /* Register the device group. */ - device.dev= ip_dev; - device.style= STYLE_CLONE; - if (svrctl(FSSIGNON, (void *) &device) == -1) { - printf("inet: error %d on registering ethernet devices\n", - errno); - pause(); - } - -#ifdef BUF_CONSISTENCY_CHECK - inet_buf_debug= (getenv("inetbufdebug") && - (strcmp(getenv("inetbufdebug"), "on") == 0)); - inet_buf_debug= 100; - if (inet_buf_debug) - { - ip_warning(( "buffer consistency check enabled" )); - } -#endif - - if (getenv("killerinet")) - { - ip_warning(( "killer inet active" )); - killer_inet= 1; - } - - nw_init(); while (TRUE) { #ifdef BUF_CONSISTENCY_CHECK @@ -269,12 +188,111 @@ PUBLIC void main() *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_restart_fail); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the inet server. */ + int r; + int timerand, fd; + u32_t tasknr; + struct fssignon device; + u8_t randbits[32]; + struct timeval tv; + +#if DEBUG + printf("Starting inet...\n"); + printf("%s\n", version); +#endif + +#if HZ_DYNAMIC + system_hz = sys_hz(); +#endif + + /* Read configuration. */ + nw_conf(); + + /* Get a random number */ + timerand= 1; + fd= open(RANDOM_DEV_NAME, O_RDONLY | O_NONBLOCK); + if (fd != -1) + { + r= read(fd, randbits, sizeof(randbits)); + if (r == sizeof(randbits)) + timerand= 0; + else + { + printf("inet: unable to read random data from %s: %s\n", + RANDOM_DEV_NAME, r == -1 ? strerror(errno) : + r == 0 ? "EOF" : "not enough data"); + } + close(fd); + } + else + { + printf("inet: unable to open random device %s: %s\n", + RANDOM_DEV_NAME, strerror(errno)); + } + if (timerand) + { + printf("inet: using current time for random-number seed\n"); + r= gettimeofday(&tv, NULL); + if (r == -1) + { + printf("sysutime failed: %s\n", strerror(errno)); + exit(1); + } + memcpy(randbits, &tv, sizeof(tv)); + } + init_rand256(randbits); + + /* Our new identity as a server. */ + r= ds_retrieve_u32("inet", &tasknr); + if (r != OK) + ip_panic(("inet: ds_retrieve_u32 failed for 'inet': %d", r)); + this_proc= tasknr; + + /* Register the device group. */ + device.dev= ip_dev; + device.style= STYLE_CLONE; + if (svrctl(FSSIGNON, (void *) &device) == -1) { + printf("inet: error %d on registering ethernet devices\n", + errno); + pause(); + } + +#ifdef BUF_CONSISTENCY_CHECK + inet_buf_debug= (getenv("inetbufdebug") && + (strcmp(getenv("inetbufdebug"), "on") == 0)); + inet_buf_debug= 100; + if (inet_buf_debug) + { + ip_warning(( "buffer consistency check enabled" )); + } +#endif + + if (getenv("killerinet")) + { + ip_warning(( "killer inet active" )); + killer_inet= 1; + } + + nw_init(); + + return(OK); +} + PRIVATE void nw_conf() { read_conf(); diff --git a/servers/ipc/main.c b/servers/ipc/main.c index 2310a245c..d5f4c02a5 100644 --- a/servers/ipc/main.c +++ b/servers/ipc/main.c @@ -25,19 +25,16 @@ int verbose = 0; /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); PUBLIC int main(int argc, char *argv[]) { message m; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - SELF_E = getprocnr(); - - if(verbose) - printf("IPC: self: %d\n", SELF_E); - while (TRUE) { int r; int i; @@ -111,9 +108,28 @@ PUBLIC int main(int argc, char *argv[]) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the ipc server. */ + + SELF_E = getprocnr(); + + if(verbose) + printf("IPC: self: %d\n", SELF_E); + + return(OK); +} + diff --git a/servers/is/dmp_rs.c b/servers/is/dmp_rs.c index 709ffbd46..eb1d1925f 100644 --- a/servers/is/dmp_rs.c +++ b/servers/is/dmp_rs.c @@ -14,6 +14,7 @@ #include "../rs/const.h" #include "../rs/type.h" +PUBLIC struct rprocpub rprocpub[NR_SYS_PROCS]; PUBLIC struct rproc rproc[NR_SYS_PROCS]; FORWARD _PROTOTYPE( char *s_flags_str, (int flags) ); @@ -24,21 +25,24 @@ FORWARD _PROTOTYPE( char *s_flags_str, (int flags) ); PUBLIC void rproc_dmp() { struct rproc *rp; + struct rprocpub *rpub; int i,j, n=0; static int prev_i=0; + getsysinfo(RS_PROC_NR, SI_PROCPUB_TAB, rprocpub); getsysinfo(RS_PROC_NR, SI_PROC_TAB, rproc); printf("Reincarnation Server (RS) system process table dump\n"); printf("----label---- endpoint- -pid- flags -dev- -T- alive_tm starts command\n"); for (i=prev_i; ir_flags & RS_IN_USE) continue; if (++n > 22) break; printf("%13s %9d %5d %5s %3d/%1d %3u %8u %5dx %s", - rp->r_label, rp->r_proc_nr_e, rp->r_pid, - s_flags_str(rp->r_flags), rp->r_dev_nr, rp->r_dev_style, - rp->r_period, rp->r_alive_tm, rp->r_restarts, + rpub->label, rpub->endpoint, rp->r_pid, + s_flags_str(rp->r_flags), rpub->dev_nr, rpub->dev_style, + rpub->period, rp->r_alive_tm, rp->r_restarts, rp->r_cmd ); printf("\n"); @@ -53,10 +57,10 @@ PRIVATE char *s_flags_str(int flags) { static char str[10]; str[0] = (flags & RS_IN_USE) ? 'U' : '-'; - str[1] = (flags & RS_EXITING) ? 'E' : '-'; - str[2] = (flags & RS_REFRESHING) ? 'R' : '-'; - str[3] = (flags & RS_NOPINGREPLY) ? 'N' : '-'; - str[4] = (flags & RS_UPDATING) ? 'u' : '-'; + str[1] = (flags & RS_INITIALIZING) ? 'I' : '-'; + str[2] = (flags & RS_UPDATING) ? 'u' : '-'; + str[3] = (flags & RS_EXITING) ? 'E' : '-'; + str[4] = (flags & RS_NOPINGREPLY) ? 'N' : '-'; str[5] = '\0'; return(str); diff --git a/servers/is/main.c b/servers/is/main.c index c2e88ab00..b1117381c 100644 --- a/servers/is/main.c +++ b/servers/is/main.c @@ -19,13 +19,13 @@ int callnr; /* system call number */ extern int errno; /* error number set by system library */ /* Declare some local functions. */ -FORWARD _PROTOTYPE(void init_server, (int argc, char **argv) ); FORWARD _PROTOTYPE(void sig_handler, (void) ); FORWARD _PROTOTYPE(void get_work, (void) ); FORWARD _PROTOTYPE(void reply, (int whom, int result) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * main * @@ -40,11 +40,9 @@ PUBLIC int main(int argc, char **argv) sigset_t sigset; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - /* Initialize the server, then go to work. */ - init_server(argc, argv); - /* Main loop - get work and do it, forever. */ while (TRUE) { /* Wait for incoming message, sets 'callnr' and 'who'. */ @@ -87,6 +85,11 @@ PUBLIC int main(int argc, char **argv) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_lu(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_fresh); + /* Register live update callbacks. */ sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard); @@ -96,11 +99,11 @@ PRIVATE void sef_local_startup() } /*===========================================================================* - * init_server * + * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE void init_server(int argc, char **argv) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { -/* Initialize the information service. */ +/* Initialize the information server. */ struct sigaction sigact; /* Install signal handler. Ask PM to transform signal into message. */ @@ -112,6 +115,8 @@ PRIVATE void init_server(int argc, char **argv) /* Set key mappings. */ map_unmap_fkeys(TRUE /*map*/); + + return(OK); } /*===========================================================================* diff --git a/servers/iso9660fs/main.c b/servers/iso9660fs/main.c index 6bff616d7..a2e84f8b5 100644 --- a/servers/iso9660fs/main.c +++ b/servers/iso9660fs/main.c @@ -9,11 +9,11 @@ #include "glo.h" /* Declare some local functions. */ -FORWARD _PROTOTYPE(void init_server, (void) ); FORWARD _PROTOTYPE(void get_work, (message *m_in) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * main * @@ -25,16 +25,6 @@ PUBLIC int main(void) { /* SEF local startup. */ sef_local_startup(); - /* Initialize the server, then go to work. */ - init_server(); - - fs_m_in.m_type = FS_READY; - - if (send(FS_PROC_NR, &fs_m_in) != OK) { - printf("ISOFS (%d): Error sending login to VFS\n", SELF_E); - return -1; - } - for (;;) { /* Wait for request message. */ @@ -76,6 +66,10 @@ PUBLIC int main(void) { *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_restart_fail); + /* No live update support for now. */ /* Let SEF perform startup. */ @@ -83,11 +77,12 @@ PRIVATE void sef_local_startup() } /*===========================================================================* - * init_server * + * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE void init_server(void) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { - int i; +/* Initialize the iso9660fs server. */ + int i, r; /* Init driver mapping */ for (i = 0; i < NR_DEVICES; ++i) @@ -96,6 +91,14 @@ PRIVATE void init_server(void) SELF_E = getprocnr(); /* hash_init(); */ /* Init the table with the ids */ setenv("TZ","",1); /* Used to calculate the time */ + + fs_m_in.m_type = FS_READY; + + if ((r = send(FS_PROC_NR, &fs_m_in)) != OK) { + panic("ISOFS", "Error sending login to VFS", r); + } + + return(OK); } /*===========================================================================* diff --git a/servers/mfs/main.c b/servers/mfs/main.c index d946b4d03..a4bee343a 100644 --- a/servers/mfs/main.c +++ b/servers/mfs/main.c @@ -10,12 +10,12 @@ /* Declare some local functions. */ -FORWARD _PROTOTYPE(void init_server, (void) ); FORWARD _PROTOTYPE(void get_work, (message *m_in) ); FORWARD _PROTOTYPE(void cch_check, (void) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * main * @@ -30,18 +30,9 @@ PUBLIC int main(int argc, char *argv[]) message m; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - /* Initialize the server, then go to work. */ - init_server(); - - fs_m_in.m_type = FS_READY; - - if (send(FS_PROC_NR, &fs_m_in) != OK) { - printf("MFS(%d): Error sending login to VFS\n", SELF_E); - return(-1); - } - while(!unmountdone || !exitsignaled) { endpoint_t src; @@ -94,6 +85,10 @@ PUBLIC int main(int argc, char *argv[]) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_restart_fail); + /* No live update support for now. */ /* Let SEF perform startup. */ @@ -101,11 +96,12 @@ PRIVATE void sef_local_startup() } /*===========================================================================* - * init_server * + * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE void init_server(void) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { - int i; +/* Initialize the Minix file server. */ + int i, r; /* Init inode table */ for (i = 0; i < NR_INODES; ++i) { @@ -122,6 +118,14 @@ PRIVATE void init_server(void) SELF_E = getprocnr(); buf_pool(); fs_block_size = _MIN_BLOCK_SIZE; + + fs_m_in.m_type = FS_READY; + + if ((r = send(FS_PROC_NR, &fs_m_in)) != OK) { + panic("MFS", "Error sending login to VFS", r); + } + + return(OK); } diff --git a/servers/mfs/mount.c b/servers/mfs/mount.c index f030a3f13..4a9a58dc8 100644 --- a/servers/mfs/mount.c +++ b/servers/mfs/mount.c @@ -52,7 +52,7 @@ PUBLIC int fs_readsuper() r = ds_retrieve_u32(fs_dev_label, &tasknr); if (r != OK) { printf("%s:%d fs_readsuper: ds_retrieve_u32 failed for '%s': %d\n", - fs_dev_label, __FILE__, __LINE__, r); + __FILE__, __LINE__, fs_dev_label, r); return(EINVAL); } diff --git a/servers/pfs/main.c b/servers/pfs/main.c index f386b0797..d52a506fa 100644 --- a/servers/pfs/main.c +++ b/servers/pfs/main.c @@ -7,11 +7,11 @@ #include "inode.h" #include "drivers.h" -FORWARD _PROTOTYPE(void init_server, (void) ); FORWARD _PROTOTYPE(void get_work, (message *m_in) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * main * @@ -26,11 +26,9 @@ PUBLIC int main(int argc, char *argv[]) message m; /* SEF local startup. */ + env_setargs(argc, argv); sef_local_startup(); - /* Initialize the server, then go to work. */ - init_server(); - while(!exitsignaled || busy) { endpoint_t src; @@ -71,6 +69,10 @@ PUBLIC int main(int argc, char *argv[]) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_restart_fail); + /* No live update support for now. */ /* Let SEF perform startup. */ @@ -78,10 +80,11 @@ PRIVATE void sef_local_startup() } /*===========================================================================* - * init_server * + * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE void init_server(void) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { +/* Initialize the pipe file server. */ int i; /* Initialize main loop parameters. */ @@ -102,6 +105,8 @@ PRIVATE void init_server(void) SELF_E = getprocnr(); buf_pool(); + + return(OK); } diff --git a/servers/pm/main.c b/servers/pm/main.c index 6967536ea..ede2edcb2 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -41,15 +41,17 @@ EXTERN unsigned long calls_stats[NCALLS]; #endif FORWARD _PROTOTYPE( void get_work, (void) ); -FORWARD _PROTOTYPE( void pm_init, (void) ); FORWARD _PROTOTYPE( int get_nice_value, (int queue) ); FORWARD _PROTOTYPE( void handle_fs_reply, (void) ); #define click_to_round_k(n) \ ((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024)) +extern int unmap_ok; + /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * main * @@ -64,8 +66,6 @@ PUBLIC int main() /* SEF local startup. */ sef_local_startup(); - pm_init(); /* initialize process manager tables */ - /* This is PM's main loop- get work and do it, forever and forever. */ while (TRUE) { get_work(); /* wait for an PM system call */ @@ -166,6 +166,10 @@ send_reply: *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_restart_fail); + /* No live update support for now. */ /* Let SEF perform startup. */ @@ -173,55 +177,9 @@ PRIVATE void sef_local_startup() } /*===========================================================================* - * get_work * + * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE void get_work() -{ -/* Wait for the next message and extract useful information from it. */ - if (sef_receive(ANY, &m_in) != OK) - panic(__FILE__,"PM sef_receive error", NO_NUM); - who_e = m_in.m_source; /* who sent the message */ - if(pm_isokendpt(who_e, &who_p) != OK) - panic(__FILE__, "PM got message from invalid endpoint", who_e); - call_nr = m_in.m_type; /* system call number */ - - /* Process slot of caller. Misuse PM's own process slot if the kernel is - * calling. This can happen in case of synchronous alarms (CLOCK) or or - * event like pending kernel signals (SYSTEM). - */ - mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p]; - if(who_p >= 0 && mp->mp_endpoint != who_e) { - panic(__FILE__, "PM endpoint number out of sync with source", - mp->mp_endpoint); - } -} - -/*===========================================================================* - * setreply * - *===========================================================================*/ -PUBLIC void setreply(proc_nr, result) -int proc_nr; /* process to reply to */ -int result; /* result of call (usually OK or error #) */ -{ -/* Fill in a reply message to be sent later to a user process. System calls - * may occasionally fill in other fields, this is only for the main return - * value, and for setting the "must send reply" flag. - */ - register struct mproc *rmp = &mproc[proc_nr]; - - if(proc_nr < 0 || proc_nr >= NR_PROCS) - panic(__FILE__,"setreply arg out of range", proc_nr); - - rmp->mp_reply.reply_res = result; - rmp->mp_flags |= REPLY; /* reply pending */ -} - -extern int unmap_ok; - -/*===========================================================================* - * pm_init * - *===========================================================================*/ -PRIVATE void pm_init() +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the process manager. * Memory use info is collected from the boot monitor, the kernel, and @@ -351,6 +309,52 @@ PRIVATE void pm_init() */ unmap_ok = 1; _minix_unmapzero(); + + return(OK); +} + +/*===========================================================================* + * get_work * + *===========================================================================*/ +PRIVATE void get_work() +{ +/* Wait for the next message and extract useful information from it. */ + if (sef_receive(ANY, &m_in) != OK) + panic(__FILE__,"PM sef_receive error", NO_NUM); + who_e = m_in.m_source; /* who sent the message */ + if(pm_isokendpt(who_e, &who_p) != OK) + panic(__FILE__, "PM got message from invalid endpoint", who_e); + call_nr = m_in.m_type; /* system call number */ + + /* Process slot of caller. Misuse PM's own process slot if the kernel is + * calling. This can happen in case of synchronous alarms (CLOCK) or or + * event like pending kernel signals (SYSTEM). + */ + mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p]; + if(who_p >= 0 && mp->mp_endpoint != who_e) { + panic(__FILE__, "PM endpoint number out of sync with source", + mp->mp_endpoint); + } +} + +/*===========================================================================* + * setreply * + *===========================================================================*/ +PUBLIC void setreply(proc_nr, result) +int proc_nr; /* process to reply to */ +int result; /* result of call (usually OK or error #) */ +{ +/* Fill in a reply message to be sent later to a user process. System calls + * may occasionally fill in other fields, this is only for the main return + * value, and for setting the "must send reply" flag. + */ + register struct mproc *rmp = &mproc[proc_nr]; + + if(proc_nr < 0 || proc_nr >= NR_PROCS) + panic(__FILE__,"setreply arg out of range", proc_nr); + + rmp->mp_reply.reply_res = result; + rmp->mp_flags |= REPLY; /* reply pending */ } /*===========================================================================* diff --git a/servers/rs/const.h b/servers/rs/const.h index a9ce99c66..c060553b4 100644 --- a/servers/rs/const.h +++ b/servers/rs/const.h @@ -5,16 +5,12 @@ /* Space reserved for program and arguments. */ #define MAX_COMMAND_LEN 512 /* maximum argument string length */ -#define MAX_LABEL_LEN 16 /* Unique name of (this instance of) - * the service - */ #define MAX_SCRIPT_LEN 256 /* maximum restart script name length */ #define MAX_NR_ARGS 4 /* maximum number of arguments */ #define MAX_IPC_LIST 256 /* Max size of list for IPC target * process names */ -#define MAX_VM_LIST 256 /* Flag values. */ #define RS_IN_USE 0x001 /* set when process slot is in use */ @@ -25,19 +21,22 @@ #define RS_CRASHED 0x040 /* service crashed */ #define RS_LATEREPLY 0x080 /* no reply sent to RS_DOWN caller yet */ #define RS_SIGNALED 0x100 /* service crashed */ -#define RS_UPDATING 0x200 /* set when update must be done */ +#define RS_INITIALIZING 0x200 /* set when init is in progress */ +#define RS_UPDATING 0x400 /* set when update is in progress */ /* Sys flag values. */ -#define SF_CORE_PROC 0x001 /* set for core system processes +#define SF_CORE_SRV 0x001 /* set for core system services * XXX FIXME: This should trigger a system - * panic when a CORE_PROC service cannot + * panic when a CORE_SRV service cannot * be restarted. We need better error-handling * in RS to change this. */ +#define SF_SYNCH_BOOT 0X002 /* set when process needs synch boot init */ #define SF_NEED_COPY 0x004 /* set when process needs copy to restart */ #define SF_USE_COPY 0x008 /* set when process has a copy in memory */ /* Constants determining RS period and binary exponential backoff. */ +#define RS_INIT_T 600 /* allow T ticks for init */ #define RS_DELTA_T 60 /* check every T ticks */ #define BACKOFF_BITS (sizeof(long)*8) /* bits in backoff field */ #define MAX_BACKOFF 30 /* max backoff in RS_DELTA_T */ @@ -55,8 +54,8 @@ /* Definitions for boot info tables. */ #define NULL_BOOT_NR NR_BOOT_PROCS /* marks a null boot entry */ #define DEFAULT_BOOT_NR NR_BOOT_PROCS /* marks the default boot entry */ -#define SYS_ALL_C (NR_SYS_CALLS+0) /* specifies all calls */ -#define SYS_NULL_C (NR_SYS_CALLS+1) /* marks a null call entry */ +#define SYS_ALL_C (-1) /* specifies all calls */ +#define SYS_NULL_C (-2) /* marks a null call entry */ /* Define privilege flags for the various process types. */ #define SRV_F (SYS_PROC | PREEMPTIBLE) /* system services */ @@ -79,9 +78,10 @@ | spi_to(VM_PROC_NR) ) /* root user proc */ /* Define sys flags for the various process types. */ -#define SRV_SF (SF_CORE_PROC | SF_NEED_COPY) /* system services */ +#define SRV_SF (SF_CORE_SRV | SF_NEED_COPY) /* system services */ #define SRVC_SF (SRV_SF | SF_USE_COPY) /* system services with a copy */ #define DSRV_SF (0) /* dynamic system services */ +#define VM_SF (SRV_SF | SF_SYNCH_BOOT) /* vm */ #endif /* RS_CONST_H */ diff --git a/servers/rs/glo.h b/servers/rs/glo.h index 9d9f4dd8a..c2eb506f1 100644 --- a/servers/rs/glo.h +++ b/servers/rs/glo.h @@ -27,6 +27,7 @@ extern struct boot_image_dev boot_image_dev_table[]; * services (servers and drivers), and thus is not directly indexed by * slot number. */ +EXTERN struct rprocpub rprocpub[NR_SYS_PROCS]; /* public entries */ EXTERN struct rproc rproc[NR_SYS_PROCS]; EXTERN struct rproc *rproc_ptr[NR_PROCS]; /* mapping for fast access */ @@ -37,6 +38,11 @@ EXTERN struct rproc *rproc_ptr[NR_PROCS]; /* mapping for fast access */ */ EXTERN int exec_pipe[2]; +/* Global init descriptor. This descriptor holds data to initialize system + * services. + */ +EXTERN sef_init_info_t rinit; + /* Global update descriptor. This descriptor holds data when a live update * is in progress. */ diff --git a/servers/rs/main.c b/servers/rs/main.c index 2986dc169..b61a03f20 100644 --- a/servers/rs/main.c +++ b/servers/rs/main.c @@ -25,9 +25,7 @@ FORWARD _PROTOTYPE(void boot_image_info_lookup, ( endpoint_t endpoint, struct boot_image *image, struct boot_image **ip, struct boot_image_priv **pp, struct boot_image_sys **sp, struct boot_image_dev **dp) ); -FORWARD _PROTOTYPE(void fill_call_mask, ( int *calls, int tot_nr_calls, - bitchunk_t *call_mask, int call_base) ); -FORWARD _PROTOTYPE(void init_server, (void) ); +FORWARD _PROTOTYPE(void catch_boot_init_ready, (endpoint_t endpoint) ); FORWARD _PROTOTYPE(void sig_handler, (void) ); FORWARD _PROTOTYPE(void get_work, (message *m) ); FORWARD _PROTOTYPE(void reply, (int whom, message *m_out) ); @@ -36,16 +34,12 @@ FORWARD _PROTOTYPE(void reply, (int whom, message *m_out) ); PRIVATE int boot_image_buffer_size; PRIVATE char *boot_image_buffer; -/* Macro to identify a system service in the boot image. This rules out - * kernel tasks and the root system process (RS). - */ -#define isbootsrvprocn(n) (!iskerneln((n)) && !isrootsysn((n))) - /* Flag set when memory unmapping can be done. */ EXTERN int unmap_ok; /* SEF functions and variables. */ -FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * main * @@ -59,15 +53,10 @@ PUBLIC int main(void) message m; /* request message */ int call_nr, who_e,who_p; /* call number and caller */ int result; /* result to return */ - sigset_t sigset; /* system signal set */ - int s; /* SEF local startup. */ sef_local_startup(); - /* Initialize the server, then go to work. */ - init_server(); - /* Main loop - get work and do it, forever. */ while (TRUE) { @@ -83,8 +72,8 @@ PUBLIC int main(void) /* Now determine what to do. Four types of requests are expected: * - Heartbeat messages (notifications from registered system services) * - System notifications (POSIX signals or synchronous alarm) - * - Ready to update messages (reply messages from registered services) * - User requests (control messages to manage system services) + * - Ready messages (reply messages from registered services) */ /* Notification messages are control messages and do not need a reply. @@ -107,21 +96,7 @@ PUBLIC int main(void) } } - /* See if this is a ready to update message. - * If the message was expected, update the originating process - */ - else if(call_nr == RS_LU_PREPARE) { - result = do_upd_ready(&m); - - /* Send reply only if something went wrong. */ - if (result != OK) { - m.m_type = result; - reply(who_e, &m); - } - } - - /* If this is neither a ready to update message nor a notification - * message, it is a normal request. + /* If we get this far, this is a normal request. * Handle the request and send a reply to the caller. */ else { @@ -136,6 +111,7 @@ PUBLIC int main(void) /* Handler functions are responsible for permission checking. */ switch(call_nr) { + /* User requests. */ case RS_UP: result = do_up(&m); break; case RS_DOWN: result = do_down(&m); break; case RS_REFRESH: result = do_refresh(&m); break; @@ -144,6 +120,9 @@ PUBLIC int main(void) case RS_UPDATE: result = do_update(&m); break; case GETSYSINFO: result = do_getsysinfo(&m); break; case RS_LOOKUP: result = do_lookup(&m); break; + /* Ready messages. */ + case RS_INIT: result = do_init_ready(&m); break; + case RS_LU_PREPARE: result = do_upd_ready(&m); break; default: printf("Warning, RS got unexpected request %d from %d\n", m.m_type, m.m_source); @@ -164,12 +143,359 @@ PUBLIC int main(void) *===========================================================================*/ PRIVATE void sef_local_startup() { - /* No live update support for now. */ + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); /* RS can only start fresh. */ /* Let SEF perform startup. */ sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the reincarnation server. */ + struct sigaction sa; + struct boot_image *ip; + int s,i,j; + int nr_image_srvs, nr_image_priv_srvs, nr_uncaught_init_srvs; + struct rproc *rp; + struct rprocpub *rpub; + struct boot_image image[NR_BOOT_PROCS]; + struct mproc mproc[NR_PROCS]; + struct exec header; + struct boot_image_priv *boot_image_priv; + struct boot_image_sys *boot_image_sys; + struct boot_image_dev *boot_image_dev; + + /* See if we run in verbose mode. */ + env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1); + + /* Initialize the global init descriptor. */ + rinit.rproctab_gid = cpf_grant_direct(ANY, (vir_bytes) rprocpub, + sizeof(rprocpub), CPF_READ); + if(!GRANT_VALID(rinit.rproctab_gid)) { + panic("RS", "unable to create rprocpub table grant", rinit.rproctab_gid); + } + + /* Initialize the global update descriptor. */ + rupdate.flags = 0; + + /* Get a copy of the boot image table. */ + if ((s = sys_getimage(image)) != OK) { + panic("RS", "unable to get copy of boot image table", s); + } + + /* Determine the number of system services in the boot image table and + * compute the size required for the boot image buffer. + */ + nr_image_srvs = 0; + boot_image_buffer_size = 0; + for(i=0;iendpoint))) { + continue; + } + nr_image_srvs++; + + /* Lookup the corresponding entry in the boot image sys table. */ + boot_image_info_lookup(ip->endpoint, image, + NULL, NULL, &boot_image_sys, NULL); + + /* If we must keep a copy of this system service, read the header + * and increase the size of the boot image buffer. + */ + if(boot_image_sys->flags & SF_USE_COPY) { + if((s = sys_getaoutheader(&header, i)) != OK) { + panic("RS", "unable to get copy of a.out header", s); + } + boot_image_buffer_size += header.a_hdrlen + + header.a_text + header.a_data; + } + } + + /* Determine the number of entries in the boot image priv table and make sure + * it matches the number of system services in the boot image table. + */ + nr_image_priv_srvs = 0; + for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { + boot_image_priv = &boot_image_priv_table[i]; + + /* System services only. */ + if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { + continue; + } + nr_image_priv_srvs++; + } + if(nr_image_srvs != nr_image_priv_srvs) { + panic("RS", "boot image table and boot image priv table mismatch", + NO_NUM); + } + + /* Allocate boot image buffer. */ + if(boot_image_buffer_size > 0) { + boot_image_buffer = rs_startup_sbrk(boot_image_buffer_size); + if(boot_image_buffer == (char *) -1) { + panic("RS", "unable to allocate boot image buffer", NO_NUM); + } + } + + /* Reset the system process table. */ + for (rp=BEG_RPROC_ADDR; rpr_flags = 0; + rp->r_pub = &rprocpub[rp - rproc]; + rp->r_pub->in_use = FALSE; + } + + /* Initialize the system process table in 4 steps, each of them following + * the appearance of system services in the boot image priv table. + * - Step 1: get a copy of the executable image of every system service that + * requires it while it is not yet running. + * In addition, set priviliges, sys properties, and dev properties (if any) + * for every system service. + */ + for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { + boot_image_priv = &boot_image_priv_table[i]; + + /* System services only. */ + if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { + continue; + } + + /* Lookup the corresponding entries in other tables. */ + boot_image_info_lookup(boot_image_priv->endpoint, image, + &ip, NULL, &boot_image_sys, &boot_image_dev); + rp = &rproc[boot_image_priv - boot_image_priv_table]; + rpub = rp->r_pub; + + /* + * Get a copy of the executable image if required. + */ + rp->r_exec_len = 0; + rp->r_exec = NULL; + if(boot_image_sys->flags & SF_USE_COPY) { + exec_image_copy(ip - image, ip, rp); + } + + /* + * Set privileges. + */ + /* Get label. */ + strcpy(rpub->label, boot_image_priv->label); + + if(boot_image_priv->endpoint != RS_PROC_NR) { + /* Force a static priv id for system services in the boot image. */ + rp->r_priv.s_id = static_priv_id( + _ENDPOINT_P(boot_image_priv->endpoint)); + + /* Initialize privilege bitmaps. */ + rp->r_priv.s_flags = boot_image_priv->flags; /* priv flags */ + rp->r_priv.s_trap_mask = boot_image_priv->trap_mask; /* traps */ + memcpy(&rp->r_priv.s_ipc_to, &boot_image_priv->ipc_to, + sizeof(rp->r_priv.s_ipc_to)); /* targets */ + + /* Initialize kernel call mask bitmap from unordered set. */ + fill_call_mask(boot_image_priv->k_calls, NR_SYS_CALLS, + rp->r_priv.s_k_call_mask, KERNEL_CALL, TRUE); + + /* Set the privilege structure. */ + if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv))) + != OK) { + panic("RS", "unable to set privilege structure", s); + } + } + + /* Synch the privilege structure with the kernel. */ + if ((s = sys_getpriv(&(rp->r_priv), ip->endpoint)) != OK) { + panic("RS", "unable to synch privilege structure", s); + } + + /* + * Set sys properties. + */ + rpub->sys_flags = boot_image_sys->flags; /* sys flags */ + + /* + * Set dev properties. + */ + rpub->dev_nr = boot_image_dev->dev_nr; /* major device number */ + rpub->dev_style = boot_image_dev->dev_style; /* device style */ + rpub->period = boot_image_dev->period; /* heartbeat period */ + + /* Get process name. */ + strcpy(rpub->proc_name, ip->proc_name); + + /* Get command settings. */ + rp->r_cmd[0]= '\0'; + rp->r_argv[0] = rp->r_cmd; + rp->r_argv[1] = NULL; + rp->r_argc = 1; + rp->r_script[0]= '\0'; + + /* Initialize vm call mask bitmap from unordered set. */ + fill_call_mask(boot_image_priv->vm_calls, NR_VM_CALLS, + rpub->vm_call_mask, VM_RQ_BASE, TRUE); + + /* Get some settings from the boot image table. */ + rp->r_nice = ip->priority; + rpub->endpoint = ip->endpoint; + + /* Set some defaults. */ + rp->r_uid = 0; /* root */ + rp->r_check_tm = 0; /* not checked yet */ + getuptime(&rp->r_alive_tm); /* currently alive */ + rp->r_stop_tm = 0; /* not exiting yet */ + rp->r_restarts = 0; /* no restarts so far */ + rp->r_set_resources = 0; /* don't set resources */ + + /* Mark as in use. */ + rp->r_flags = RS_IN_USE; + rproc_ptr[_ENDPOINT_P(rpub->endpoint)]= rp; + rpub->in_use = TRUE; + } + + /* - Step 2: allow every system service in the boot image to run. + */ + nr_uncaught_init_srvs = 0; + for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { + boot_image_priv = &boot_image_priv_table[i]; + + /* System services only. */ + if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { + continue; + } + + /* Ignore RS. */ + if(boot_image_priv->endpoint == RS_PROC_NR) { + continue; + } + + /* Lookup the corresponding slot in the system process table. */ + rp = &rproc[boot_image_priv - boot_image_priv_table]; + rpub = rp->r_pub; + + /* Allow the service to run. */ + if ((s = sys_privctl(rpub->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) { + panic("RS", "unable to initialize privileges", s); + } + + /* Initialize service. We assume every service will always get + * back to us here at boot time. + */ + if(boot_image_priv->flags & SYS_PROC) { + if ((s = init_service(rp, SEF_INIT_FRESH)) != OK) { + panic("RS", "unable to initialize service", s); + } + if(rpub->sys_flags & SF_SYNCH_BOOT) { + /* Catch init ready message now to synchronize. */ + catch_boot_init_ready(rpub->endpoint); + } + else { + /* Catch init ready message later. */ + nr_uncaught_init_srvs++; + } + } + } + + /* - Step 3: let every system service complete initialization by + * catching all the init ready messages left. + */ + while(nr_uncaught_init_srvs) { + catch_boot_init_ready(ANY); + nr_uncaught_init_srvs--; + } + + /* - Step 4: all the system services in the boot image are now running. + * Complete the initialization of the system process table in collaboration + * with other system processes. + */ + if ((s = getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc)) != OK) { + panic("RS", "unable to get copy of PM process table", s); + } + for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { + boot_image_priv = &boot_image_priv_table[i]; + + /* System services only. */ + if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { + continue; + } + + /* Lookup the corresponding slot in the system process table. */ + rp = &rproc[boot_image_priv - boot_image_priv_table]; + rpub = rp->r_pub; + + /* Get pid from PM process table. */ + rp->r_pid = NO_PID; + for (j = 0; j < NR_PROCS; j++) { + if (mproc[j].mp_endpoint == rpub->endpoint) { + rp->r_pid = mproc[j].mp_pid; + break; + } + } + if(j == NR_PROCS) { + panic("RS", "unable to get pid", NO_NUM); + } + } + + /* + * Now complete RS initialization process in collaboration with other + * system services. + */ + /* Let the rest of the system know about our dynamically allocated buffer. */ + if(boot_image_buffer_size > 0) { + boot_image_buffer = rs_startup_sbrk_synch(boot_image_buffer_size); + if(boot_image_buffer == (char *) -1) { + panic("RS", "unable to synch boot image buffer", NO_NUM); + } + } + + /* Set alarm to periodically check service status. */ + if (OK != (s=sys_setalarm(RS_DELTA_T, 0))) + panic("RS", "couldn't set alarm", s); + + /* Install signal handlers. Ask PM to transform signal into message. */ + sa.sa_handler = SIG_MESS; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGCHLD,&sa,NULL)<0) panic("RS","sigaction failed", errno); + if (sigaction(SIGTERM,&sa,NULL)<0) panic("RS","sigaction failed", errno); + + /* Initialize the exec pipe. */ + if (pipe(exec_pipe) == -1) + panic("RS", "pipe failed", errno); + if (fcntl(exec_pipe[0], F_SETFD, + fcntl(exec_pipe[0], F_GETFD) | FD_CLOEXEC) == -1) + { + panic("RS", "fcntl set FD_CLOEXEC on pipe input failed", errno); + } + if (fcntl(exec_pipe[1], F_SETFD, + fcntl(exec_pipe[1], F_GETFD) | FD_CLOEXEC) == -1) + { + panic("RS", "fcntl set FD_CLOEXEC on pipe output failed", errno); + } + if (fcntl(exec_pipe[0], F_SETFL, + fcntl(exec_pipe[0], F_GETFL) | O_NONBLOCK) == -1) + { + panic("RS", "fcntl set O_NONBLOCK on pipe input failed", errno); + } + + /* Map out our own text and data. This is normally done in crtso.o + * but RS is an exception - we don't get to talk to VM so early on. + * That's why we override munmap() and munmap_text() in utility.c. + * + * _minix_unmapzero() is the same code in crtso.o that normally does + * it on startup. It's best that it's there as crtso.o knows exactly + * what the ranges are of the filler data. + */ + unmap_ok = 1; + _minix_unmapzero(); + + return(OK); +} + /*===========================================================================* * exec_image_copy * *===========================================================================*/ @@ -293,344 +619,36 @@ struct boot_image_dev **dp; } /*===========================================================================* - * fill_call_mask * + * catch_boot_init_ready * *===========================================================================*/ -PRIVATE void fill_call_mask(calls, tot_nr_calls, call_mask, call_base) -int *calls; /* the unordered set of calls */ -int tot_nr_calls; /* the total number of calls */ -bitchunk_t *call_mask; /* the call mask to fill in */ -int call_base; /* the base offset for the calls */ +PRIVATE void catch_boot_init_ready(endpoint) +endpoint_t endpoint; { -/* Fill a call mask from an unordered set of calls. */ - int i; - bitchunk_t fv; - int call_mask_size, nr_calls; - - call_mask_size = BITMAP_CHUNKS(tot_nr_calls); - - /* Count the number of calls to fill in. */ - nr_calls = 0; - for(i=0; calls[i] != SYS_NULL_C; i++) { - nr_calls++; - } - - /* See if all calls are allowed and call mask must be completely filled. */ - fv = 0; - if(nr_calls == 1 && calls[0] == SYS_ALL_C) { - fv = (~0); - } - - /* Fill or clear call mask. */ - for(i=0; i < call_mask_size; i++) { - call_mask[i] = fv; - } - - /* Not all calls allowed? Enter calls bit by bit. */ - if(!fv) { - for(i=0; i < nr_calls; i++) { - SET_BIT(call_mask, calls[i] - call_base); - } - } -} - -/*===========================================================================* - * init_server * - *===========================================================================*/ -PRIVATE void init_server(void) -{ -/* Initialize the reincarnation server. */ - struct sigaction sa; - struct boot_image *ip; - int s,i,j; - int nr_image_srvs, nr_image_priv_srvs; +/* Block and catch an init ready message from the given source. */ + int r; + message m; struct rproc *rp; - struct boot_image image[NR_BOOT_PROCS]; - struct mproc mproc[NR_PROCS]; - struct exec header; - struct boot_image_priv *boot_image_priv; - struct boot_image_sys *boot_image_sys; - struct boot_image_dev *boot_image_dev; + int result; - /* See if we run in verbose mode. */ - env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1); + /* Receive init ready message. */ + if ((r = receive(endpoint, &m)) != OK) { + panic("RS", "unable to receive init reply", r); + } + if(m.m_type != RS_INIT) { + panic("RS", "unexpected reply from service", m.m_source); + } + result = m.RS_INIT_RESULT; + rp = rproc_ptr[_ENDPOINT_P(m.m_source)]; - /* Initialize the global update descriptor. */ - rupdate.flags = 0; - - /* Get a copy of the boot image table. */ - if ((s = sys_getimage(image)) != OK) { - panic("RS", "unable to get copy of boot image table", s); + /* Check result. */ + if(result != OK) { + panic("RS", "unable to complete init for service", m.m_source); } - /* Determine the number of system services in the boot image table and - * compute the size required for the boot image buffer. - */ - nr_image_srvs = 0; - boot_image_buffer_size = 0; - for(i=0;iendpoint))) { - continue; - } - nr_image_srvs++; - - /* Lookup the corresponding entry in the boot image sys table. */ - boot_image_info_lookup(ip->endpoint, image, - NULL, NULL, &boot_image_sys, NULL); - - /* If we must keep a copy of this system service, read the header - * and increase the size of the boot image buffer. - */ - if(boot_image_sys->flags & SF_USE_COPY) { - if((s = sys_getaoutheader(&header, i)) != OK) { - panic("RS", "unable to get copy of a.out header", s); - } - boot_image_buffer_size += header.a_hdrlen - + header.a_text + header.a_data; - } - } - - /* Determine the number of entries in the boot image priv table and make sure - * it matches the number of system services in the boot image table. - */ - nr_image_priv_srvs = 0; - for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { - boot_image_priv = &boot_image_priv_table[i]; - - /* System services only. */ - if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) { - continue; - } - nr_image_priv_srvs++; - } - if(nr_image_srvs != nr_image_priv_srvs) { - panic("RS", "boot image table and boot image priv table mismatch", - NO_NUM); - } - - /* Allocate boot image buffer. */ - if(boot_image_buffer_size > 0) { - boot_image_buffer = rs_startup_sbrk(boot_image_buffer_size); - if(boot_image_buffer == (char *) -1) { - panic("RS", "unable to allocate boot image buffer", NO_NUM); - } - } - - /* Initialize the system process table in 3 steps, each of them following - * the appearance of system services in the boot image priv table. - * - Step 1: get a copy of the executable image of every system service that - * requires it while it is not yet running. - * In addition, set priviliges, sys properties, and dev properties (if any) - * for every system service. - */ - for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { - boot_image_priv = &boot_image_priv_table[i]; - - /* System services only. */ - if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) { - continue; - } - - /* Lookup the corresponding entries in other tables. */ - boot_image_info_lookup(boot_image_priv->endpoint, image, - &ip, NULL, &boot_image_sys, &boot_image_dev); - rp = &rproc[boot_image_priv - boot_image_priv_table]; - - /* - * Get a copy of the executable image if required. - */ - rp->r_exec_len = 0; - rp->r_exec = NULL; - if(boot_image_sys->flags & SF_USE_COPY) { - exec_image_copy(ip - image, ip, rp); - } - - /* - * Set privileges. - * XXX FIXME: We should also let RS set vm calls allowed for each sys - * service by using vm_set_priv(). We need a more uniform privilege - * management scheme in VM for this change. - */ - /* Get label. */ - strcpy(rp->r_label, boot_image_priv->label); - - /* Force a static privilege id for system services in the boot image. */ - rp->r_priv.s_id = static_priv_id(_ENDPOINT_P(boot_image_priv->endpoint)); - - /* Initialize privilege bitmaps. */ - rp->r_priv.s_flags = boot_image_priv->flags; /* privilege flags */ - rp->r_priv.s_trap_mask = boot_image_priv->trap_mask; /* allowed traps */ - memcpy(&rp->r_priv.s_ipc_to, &boot_image_priv->ipc_to, - sizeof(rp->r_priv.s_ipc_to)); /* allowed targets */ - - /* Initialize call mask bitmap from unordered set. */ - fill_call_mask(boot_image_priv->k_calls, NR_SYS_CALLS, - rp->r_priv.s_k_call_mask, KERNEL_CALL); - - /* Set the privilege structure. */ - if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv))) - != OK) { - panic("RS", "unable to set privilege structure", s); - } - - /* Synch the privilege structure with the kernel. */ - if ((s = sys_getpriv(&(rp->r_priv), ip->endpoint)) != OK) { - panic("RS", "unable to synch privilege structure", s); - } - - /* - * Set sys properties. - */ - rp->r_sys_flags = boot_image_sys->flags; /* sys flags */ - - /* - * Set dev properties. - */ - rp->r_dev_nr = boot_image_dev->dev_nr; /* major device number */ - rp->r_dev_style = boot_image_dev->dev_style; /* device style */ - rp->r_period = boot_image_dev->period; /* heartbeat period */ - - /* Get process name. */ - strcpy(rp->r_proc_name, ip->proc_name); - - /* Get command settings. */ - rp->r_cmd[0]= '\0'; - rp->r_argv[0] = rp->r_cmd; - rp->r_argv[1] = NULL; - rp->r_argc = 1; - rp->r_script[0]= '\0'; - - /* Get some settings from the boot image table. */ - rp->r_nice = ip->priority; - rp->r_proc_nr_e = ip->endpoint; - - /* Set some defaults. */ - rp->r_uid = 0; /* root */ - rp->r_check_tm = 0; /* not checked yet */ - getuptime(&rp->r_alive_tm); /* currently alive */ - rp->r_stop_tm = 0; /* not exiting yet */ - rp->r_restarts = 0; /* no restarts so far */ - rp->r_set_resources = 0; /* don't set resources */ - - /* Mark as in use. */ - rp->r_flags = RS_IN_USE; - rproc_ptr[_ENDPOINT_P(rp->r_proc_nr_e)]= rp; - } - - /* - Step 2: allow every system service in the boot image to run. - */ - for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { - boot_image_priv = &boot_image_priv_table[i]; - - /* System services only. */ - if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) { - continue; - } - - /* Lookup the corresponding entry in the boot image table. */ - boot_image_info_lookup(boot_image_priv->endpoint, image, - &ip, NULL, NULL, NULL); - - /* Allow the service to run. */ - if ((s = sys_privctl(ip->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) { - panic("RS", "unable to initialize privileges", s); - } - } - - /* - Step 3: all the system services in the boot image are now running. - * Complete the initialization of the system process table in collaboration - * with other system processes. - */ - if ((s = getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc)) != OK) { - panic("RS", "unable to get copy of PM process table", s); - } - for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { - boot_image_priv = &boot_image_priv_table[i]; - - /* System services only. */ - if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) { - continue; - } - - /* Lookup the corresponding slot in the system process table. */ - rp = &rproc[boot_image_priv - boot_image_priv_table]; - - /* Get pid from PM process table. */ - rp->r_pid = NO_PID; - for (j = 0; j < NR_PROCS; j++) { - if (mproc[j].mp_endpoint == rp->r_proc_nr_e) { - rp->r_pid = mproc[j].mp_pid; - break; - } - } - if(j == NR_PROCS) { - panic("RS", "unable to get pid", NO_NUM); - } - - /* Publish the new system service. - * XXX FIXME. Possible race condition. We should publish labels before - * allowing other processes to run. - */ - s = publish_service(rp); - if (s != OK) { - panic("RS", "unable to publish boot system service", s); - } - } - - /* - * Now complete RS initialization process in collaboration with other - * system services. - */ - /* Let the rest of the system know about our dynamically allocated buffer. */ - if(boot_image_buffer_size > 0) { - boot_image_buffer = rs_startup_sbrk_synch(boot_image_buffer_size); - if(boot_image_buffer == (char *) -1) { - panic("RS", "unable to synch boot image buffer", NO_NUM); - } - } - - /* Set alarm to periodically check service status. */ - if (OK != (s=sys_setalarm(RS_DELTA_T, 0))) - panic("RS", "couldn't set alarm", s); - - /* Install signal handlers. Ask PM to transform signal into message. */ - sa.sa_handler = SIG_MESS; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - if (sigaction(SIGCHLD,&sa,NULL)<0) panic("RS","sigaction failed", errno); - if (sigaction(SIGTERM,&sa,NULL)<0) panic("RS","sigaction failed", errno); - - /* Initialize the exec pipe. */ - if (pipe(exec_pipe) == -1) - panic("RS", "pipe failed", errno); - if (fcntl(exec_pipe[0], F_SETFD, - fcntl(exec_pipe[0], F_GETFD) | FD_CLOEXEC) == -1) - { - panic("RS", "fcntl set FD_CLOEXEC on pipe input failed", errno); - } - if (fcntl(exec_pipe[1], F_SETFD, - fcntl(exec_pipe[1], F_GETFD) | FD_CLOEXEC) == -1) - { - panic("RS", "fcntl set FD_CLOEXEC on pipe output failed", errno); - } - if (fcntl(exec_pipe[0], F_SETFL, - fcntl(exec_pipe[0], F_GETFL) | O_NONBLOCK) == -1) - { - panic("RS", "fcntl set O_NONBLOCK on pipe input failed", errno); - } - - /* Map out our own text and data. This is normally done in crtso.o - * but RS is an exception - we don't get to talk to VM so early on. - * That's why we override munmap() and munmap_text() in utility.c. - * - * _minix_unmapzero() is the same code in crtso.o that normally does - * it on startup. It's best that it's there as crtso.o knows exactly - * what the ranges are of the filler data. - */ - unmap_ok = 1; - _minix_unmapzero(); + /* Mark the slot as no longer initializing. */ + rp->r_flags &= ~RS_INITIALIZING; + rp->r_check_tm = 0; + getuptime(&rp->r_alive_tm); } /*===========================================================================* diff --git a/servers/rs/manager.c b/servers/rs/manager.c index 679841c87..3d9fbd02f 100644 --- a/servers/rs/manager.c +++ b/servers/rs/manager.c @@ -73,12 +73,14 @@ char *label; { int control_allowed = 0; register struct rproc *rp; + register struct rprocpub *rpub; int c; char *progname; /* Find name of binary for given label. */ for (rp = BEG_RPROC_ADDR; rp < END_RPROC_ADDR; rp++) { - if (strcmp(rp->r_label, label) == 0) { + rpub = rp->r_pub; + if (strcmp(rpub->label, label) == 0) { break; } } @@ -91,7 +93,8 @@ char *label; /* Check if label is listed in caller's isolation policy. */ for (rp = BEG_RPROC_ADDR; rp < END_RPROC_ADDR; rp++) { - if (rp->r_proc_nr_e == endpoint) { + rpub = rp->r_pub; + if (rpub->endpoint == endpoint) { break; } } @@ -141,6 +144,7 @@ message *m_ptr; /* request message pointer */ /* A request was made to start a new system service. */ register struct rproc *rp; /* system process table */ + register struct rprocpub *rpub; /* public entry */ int slot_nr; /* local table entry */ int arg_count; /* number of arguments */ char *cmd_ptr; /* parse command string */ @@ -152,6 +156,7 @@ message *m_ptr; /* request message pointer */ int r; endpoint_t ep; struct rproc *tmp_rp; + struct rprocpub *tmp_rpub; struct rs_start rs_start; /* This call requires special privileges. */ @@ -168,6 +173,7 @@ message *m_ptr; /* request message pointer */ printf("RS: do_up: system process table full\n"); return ENOMEM; } + rpub = rp->r_pub; /* Ok, there is space. Get the request structure. */ s= sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->RS_CMD_ADDR, @@ -210,38 +216,36 @@ message *m_ptr; /* request message pointer */ else cmd_ptr= rp->r_argv[0]; len= strlen(cmd_ptr); - if (len > P_NAME_LEN-1) - len= P_NAME_LEN-1; /* truncate name */ - memcpy(rp->r_proc_name, cmd_ptr, len); - rp->r_proc_name[len]= '\0'; + if (len > RS_MAX_LABEL_LEN-1) + len= RS_MAX_LABEL_LEN-1; /* truncate name */ + memcpy(rpub->proc_name, cmd_ptr, len); + rpub->proc_name[len]= '\0'; if(rs_verbose) printf("RS: do_up: using proc_name (from binary %s) '%s'\n", - rp->r_argv[0], rp->r_proc_name); + rp->r_argv[0], rpub->proc_name); if(rs_start.rss_label.l_len > 0) { /* RS_UP caller has supplied a custom label for this service. */ int s = copy_label(m_ptr->m_source, &rs_start.rss_label, - rp->r_label, sizeof(rp->r_label)); + rpub->label, sizeof(rpub->label)); if(s != OK) return s; if(rs_verbose) - printf("RS: do_up: using label (custom) '%s'\n", rp->r_label); + printf("RS: do_up: using label (custom) '%s'\n", rpub->label); } else { /* Default label for the service. */ - label = rp->r_proc_name; + label = rpub->proc_name; len= strlen(label); - if (len > MAX_LABEL_LEN-1) - len= MAX_LABEL_LEN-1; /* truncate name */ - memcpy(rp->r_label, label, len); - rp->r_label[len]= '\0'; + memcpy(rpub->label, label, len); + rpub->label[len]= '\0'; if(rs_verbose) printf("RS: do_up: using label (from proc_name) '%s'\n", - rp->r_label); + rpub->label); } if(rs_start.rss_nr_control > 0) { int i, s; - if (rs_start.rss_nr_control > RSS_NR_CONTROL) + if (rs_start.rss_nr_control > RS_NR_CONTROL) { printf("RS: do_up: too many control labels\n"); return EINVAL; @@ -269,10 +273,11 @@ message *m_ptr; /* request message pointer */ continue; if (tmp_rp == rp) continue; /* Our slot */ - if (strcmp(tmp_rp->r_label, rp->r_label) == 0) + tmp_rpub = tmp_rp->r_pub; + if (strcmp(tmp_rpub->label, rpub->label) == 0) { printf("RS: found duplicate label '%s': slot %d\n", - rp->r_label, slot_nr); + rpub->label, slot_nr); return EBUSY; } } @@ -289,11 +294,11 @@ message *m_ptr; /* request message pointer */ rp->r_uid= rs_start.rss_uid; rp->r_nice= rs_start.rss_nice; - if (rs_start.rss_flags & RF_IPC_VALID) + if (rs_start.rss_flags & RSS_IPC_VALID) { if (rs_start.rss_ipclen+1 > sizeof(rp->r_ipc_list)) { - printf("rs: ipc list too long for '%s'\n", rp->r_label); + printf("rs: ipc list too long for '%s'\n", rpub->label); return EINVAL; } s=sys_datacopy(m_ptr->m_source, (vir_bytes) rs_start.rss_ipc, @@ -304,20 +309,22 @@ message *m_ptr; /* request message pointer */ else rp->r_ipc_list[0]= '\0'; - rp->r_sys_flags = DSRV_SF; + rpub->sys_flags = DSRV_SF; rp->r_exec= NULL; - if (rs_start.rss_flags & RF_COPY) { + if (rs_start.rss_flags & RSS_COPY) { int exst_cpy; struct rproc *rp2; + struct rprocpub *rpub2; exst_cpy = 0; - if(rs_start.rss_flags & RF_REUSE) { + if(rs_start.rss_flags & RSS_REUSE) { int i; for(i = 0; i < NR_SYS_PROCS; i++) { rp2 = &rproc[i]; - if(strcmp(rp->r_proc_name, rp2->r_proc_name) == 0 && - (rp2->r_sys_flags & SF_USE_COPY)) { + rpub2 = rproc[i].r_pub; + if(strcmp(rpub->proc_name, rpub2->proc_name) == 0 && + (rpub2->sys_flags & SF_USE_COPY)) { /* We have found the same binary that's * already been copied */ exst_cpy = 1; @@ -334,7 +341,7 @@ message *m_ptr; /* request message pointer */ if (s != OK) return s; - rp->r_sys_flags |= SF_USE_COPY; + rpub->sys_flags |= SF_USE_COPY; } /* All dynamically created services get the same privilege flags, and @@ -375,40 +382,42 @@ message *m_ptr; /* request message pointer */ rp->r_priv.s_io_tab[i].ior_limit); } - if (rs_start.rss_nr_pci_id > RSS_NR_PCI_ID) + if (rs_start.rss_nr_pci_id > RS_NR_PCI_DEVICE) { printf("RS: do_up: too many PCI device IDs\n"); return EINVAL; } - rp->r_nr_pci_id= rs_start.rss_nr_pci_id; - for (i= 0; ir_nr_pci_id; i++) + rpub->pci_acl.rsp_nr_device = rs_start.rss_nr_pci_id; + for (i= 0; ipci_acl.rsp_nr_device; i++) { - rp->r_pci_id[i].vid= rs_start.rss_pci_id[i].vid; - rp->r_pci_id[i].did= rs_start.rss_pci_id[i].did; + rpub->pci_acl.rsp_device[i].vid= rs_start.rss_pci_id[i].vid; + rpub->pci_acl.rsp_device[i].did= rs_start.rss_pci_id[i].did; if(rs_verbose) printf("RS: do_up: PCI %04x/%04x\n", - rp->r_pci_id[i].vid, rp->r_pci_id[i].did); + rpub->pci_acl.rsp_device[i].vid, + rpub->pci_acl.rsp_device[i].did); } - if (rs_start.rss_nr_pci_class > RSS_NR_PCI_CLASS) + if (rs_start.rss_nr_pci_class > RS_NR_PCI_CLASS) { printf("RS: do_up: too many PCI class IDs\n"); return EINVAL; } - rp->r_nr_pci_class= rs_start.rss_nr_pci_class; - for (i= 0; ir_nr_pci_class; i++) + rpub->pci_acl.rsp_nr_class= rs_start.rss_nr_pci_class; + for (i= 0; ipci_acl.rsp_nr_class; i++) { - rp->r_pci_class[i].class= rs_start.rss_pci_class[i].class; - rp->r_pci_class[i].mask= rs_start.rss_pci_class[i].mask; + rpub->pci_acl.rsp_class[i].class= rs_start.rss_pci_class[i].class; + rpub->pci_acl.rsp_class[i].mask= rs_start.rss_pci_class[i].mask; if(rs_verbose) printf("RS: do_up: PCI class %06x mask %06x\n", - rp->r_pci_class[i].class, rp->r_pci_class[i].mask); + rpub->pci_acl.rsp_class[i].class, + rpub->pci_acl.rsp_class[i].mask); } /* Copy 'system' call number bits */ if (sizeof(rs_start.rss_system[0]) == sizeof(rp->r_call_mask[0]) && sizeof(rs_start.rss_system) == sizeof(rp->r_call_mask)) { - for (i= 0; ir_call_mask[i]= rs_start.rss_system[i]; } else @@ -419,21 +428,25 @@ message *m_ptr; /* request message pointer */ } /* Initialize some fields. */ - rp->r_period = rs_start.rss_period; - rp->r_dev_nr = rs_start.rss_major; - rp->r_dev_style = STYLE_DEV; + rpub->period = rs_start.rss_period; + rpub->dev_nr = rs_start.rss_major; + rpub->dev_style = STYLE_DEV; rp->r_restarts = -1; /* will be incremented */ rp->r_set_resources= 1; /* set resources */ - if (sizeof(rp->r_vm) == sizeof(rs_start.rss_vm) && - sizeof(rp->r_vm[0]) == sizeof(rs_start.rss_vm[0])) + if (sizeof(rpub->vm_call_mask) == sizeof(rs_start.rss_vm) && + sizeof(rpub->vm_call_mask[0]) == sizeof(rs_start.rss_vm[0])) { - memcpy(rp->r_vm, rs_start.rss_vm, sizeof(rp->r_vm)); + int basic_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C }; + memcpy(rpub->vm_call_mask, rs_start.rss_vm, + sizeof(rpub->vm_call_mask)); + fill_call_mask(basic_vmc, NR_VM_CALLS, + rpub->vm_call_mask, VM_RQ_BASE, FALSE); } else { - printf("RS: do_up: internal inconsistency: bad size of r_vm\n"); - memset(rp->r_vm, '\0', sizeof(rp->r_vm)); + printf("RS: internal inconsistency: bad size of vm_call_mask\n"); + memset(rpub->vm_call_mask, '\0', sizeof(rpub->vm_call_mask)); } /* All information was gathered. Now try to start the system service. */ @@ -449,9 +462,10 @@ message *m_ptr; /* request message pointer */ PUBLIC int do_down(message *m_ptr) { register struct rproc *rp; + register struct rprocpub *rpub; size_t len; int s, proc; - char label[MAX_LABEL_LEN]; + char label[RS_MAX_LABEL_LEN]; /* This call requires special privileges. */ if (!caller_is_root(m_ptr->m_source)) return(EPERM); @@ -466,7 +480,11 @@ PUBLIC int do_down(message *m_ptr) label[len]= '\0'; for (rp=BEG_RPROC_ADDR; rpr_flags & RS_IN_USE && strcmp(rp->r_label, label) == 0) { + rpub = rp->r_pub; + if (rp->r_flags & RS_IN_USE && strcmp(rpub->label, label) == 0) { + /* Core system services should never go down. */ + if (rpub->sys_flags & SF_CORE_SRV) return(EPERM); + if(rs_verbose) printf("RS: stopping '%s' (%d)\n", label, rp->r_pid); stop_service(rp,RS_EXITING); @@ -494,9 +512,10 @@ PUBLIC int do_down(message *m_ptr) PUBLIC int do_restart(message *m_ptr) { register struct rproc *rp; + register struct rprocpub *rpub; size_t len; int s, proc, r; - char label[MAX_LABEL_LEN]; + char label[RS_MAX_LABEL_LEN]; endpoint_t ep; len= m_ptr->RS_CMD_LEN; @@ -515,7 +534,8 @@ PUBLIC int do_restart(message *m_ptr) } for (rp=BEG_RPROC_ADDR; rpr_flags & RS_IN_USE) && strcmp(rp->r_label, label) == 0) { + rpub = rp->r_pub; + if ((rp->r_flags & RS_IN_USE) && strcmp(rpub->label, label) == 0) { if(rs_verbose) printf("RS: restarting '%s' (%d)\n", label, rp->r_pid); if (rp->r_pid >= 0) { @@ -545,9 +565,10 @@ PUBLIC int do_restart(message *m_ptr) PUBLIC int do_refresh(message *m_ptr) { register struct rproc *rp; + register struct rprocpub *rpub; size_t len; int s; - char label[MAX_LABEL_LEN]; + char label[RS_MAX_LABEL_LEN]; len= m_ptr->RS_CMD_LEN; if (len >= sizeof(label)) @@ -565,9 +586,15 @@ PUBLIC int do_refresh(message *m_ptr) } for (rp=BEG_RPROC_ADDR; rpr_flags & RS_IN_USE && strcmp(rp->r_label, label) == 0) { + rpub = rp->r_pub; + if (rp->r_flags & RS_IN_USE && strcmp(rpub->label, label) == 0) { + /* Only system processes not including RS can refresh. */ + if(!(rp->r_priv.s_flags & SYS_PROC) || rpub->endpoint == RS_PROC_NR) { + return EPERM; + } + if(rs_verbose) { - printf("RS: refreshing %s (%d)\n", rp->r_label, rp->r_pid); + printf("RS: refreshing %s (%d)\n", rpub->label, rp->r_pid); } stop_service(rp,RS_REFRESHING); return(OK); @@ -593,15 +620,65 @@ PUBLIC int do_shutdown(message *m_ptr) return(OK); } + +/*===========================================================================* + * do_init_ready * + *===========================================================================*/ +PUBLIC int do_init_ready(message *m_ptr) +{ + int who_p; + struct rproc *rp; + struct rprocpub *rpub; + int result; + + who_p = _ENDPOINT_P(m_ptr->m_source); + rp = rproc_ptr[who_p]; + rpub = rp->r_pub; + result = m_ptr->RS_INIT_RESULT; + + /* Make sure the originating service was requested to initialize. */ + if(! (rp->r_flags & RS_INITIALIZING) ) { + if(rs_verbose) { + printf("RS: do_init_ready: got unexpected init ready msg from %d\n", + m_ptr->m_source); + } + return(EINVAL); + } + + /* Mark the slot as no longer initializing. */ + rp->r_flags &= ~RS_INITIALIZING; + rp->r_check_tm = 0; + getuptime(&rp->r_alive_tm); + + /* Check if something went wrong and the service failed to init. + * In that case, kill it and make sure it won't be restarted. + */ + if(result != OK) { + if(rs_verbose) + printf("RS: initialization failed for service %d: %d\n", + rpub->endpoint, result); + rp->r_flags |= RS_EXITING; + kill(rp->r_pid, SIGKILL); + } + else { + if(rs_verbose) + printf("RS: initialization succeeded for service %d\n", + rpub->endpoint); + } + + return(EDONTREPLY); +} + /*===========================================================================* * do_update * *===========================================================================*/ PUBLIC int do_update(message *m_ptr) { register struct rproc *rp; + register struct rprocpub *rpub; size_t len; int s; - char label[MAX_LABEL_LEN]; + char label[RS_MAX_LABEL_LEN]; int lu_state; int prepare_maxtime; @@ -614,6 +691,12 @@ PUBLIC int do_update(message *m_ptr) if (s != OK) return(s); label[len]= '\0'; + /* This call requires special privileges. */ + if (! (caller_can_control(m_ptr->m_source, label) || + caller_is_root(m_ptr->m_source))) { + return(EPERM); + } + /* Retrieve live update state. */ lu_state = m_ptr->RS_LU_STATE; if(lu_state == SEF_LU_STATE_NULL) { @@ -641,20 +724,26 @@ PUBLIC int do_update(message *m_ptr) /* Try to start the update process. */ for (rp=BEG_RPROC_ADDR; rpr_flags & RS_IN_USE && strcmp(rp->r_label, label) == 0) { + rpub = rp->r_pub; + if (rp->r_flags & RS_IN_USE && strcmp(rpub->label, label) == 0) { + /* Only system processes not including RS can update. */ + if(!(rp->r_priv.s_flags & SYS_PROC) || rpub->endpoint == RS_PROC_NR) { + return EPERM; + } + if(rs_verbose) { - printf("RS: updating %s (%d)\n", rp->r_label, rp->r_pid); + printf("RS: updating %s (%d)\n", rpub->label, rp->r_pid); } - + rp->r_flags |= RS_UPDATING; rupdate.flags |= RS_UPDATING; getuptime(&rupdate.prepare_tm); rupdate.prepare_maxtime = prepare_maxtime; rupdate.rp = rp; - + m_ptr->m_type = RS_LU_PREPARE; - asynsend(rp->r_proc_nr_e, m_ptr); /* request to prepare for update */ - + asynsend(rpub->endpoint, m_ptr); /* request to update */ + return(OK); } } @@ -679,7 +768,7 @@ PUBLIC int do_upd_ready(message *m_ptr) rp = rproc_ptr[who_p]; result = m_ptr->RS_LU_RESULT; - /* Make sure the originating process was requested to prepare for update. */ + /* Make sure the originating service was requested to prepare for update. */ if(! (rp->r_flags & RS_UPDATING) ) { if(rs_verbose) { printf("RS: do_upd_ready: got unexpected update ready msg from %d\n", @@ -688,7 +777,7 @@ PUBLIC int do_upd_ready(message *m_ptr) return(EINVAL); } - /* Check if something went wrong and the process failed to prepare + /* Check if something went wrong and the service failed to prepare * for the update. In that case, end the update process. */ if(result != OK) { @@ -696,17 +785,17 @@ PUBLIC int do_upd_ready(message *m_ptr) switch(result) { case EACCES: printf("RS: update failed: %s\n", - "process does not support live update"); + "service does not support live update"); break; case EINVAL: printf("RS: update failed: %s\n", - "process does not support the required state"); + "service does not support the required state"); break; case EBUSY: printf("RS: update failed: %s\n", - "process is not able to prepare for the update now"); + "service is not able to prepare for the update now"); break; case EGENERIC: @@ -721,7 +810,7 @@ PUBLIC int do_upd_ready(message *m_ptr) break; } - return ENOTREADY; + return(OK); } /* Kill the process now and mark it for refresh, the new version will @@ -731,7 +820,7 @@ PUBLIC int do_upd_ready(message *m_ptr) rp->r_flags |= RS_REFRESHING; kill(rp->r_pid, SIGKILL); - return(OK); + return(EDONTREPLY); } /*===========================================================================* @@ -742,6 +831,9 @@ PRIVATE void update_period(message *m_ptr) clock_t now = m_ptr->NOTIFY_TIMESTAMP; short has_update_timed_out; message m; + struct rprocpub *rpub; + + rpub = rupdate.rp->r_pub; /* See if a timeout has occurred. */ has_update_timed_out = (now - rupdate.prepare_tm > rupdate.prepare_maxtime); @@ -754,7 +846,7 @@ PRIVATE void update_period(message *m_ptr) /* Prepare cancel request. */ m.m_type = RS_LU_PREPARE; m.RS_LU_STATE = SEF_LU_STATE_NULL; - asynsend(rupdate.rp->r_proc_nr_e, &m); + asynsend(rpub->endpoint, &m); } } @@ -766,15 +858,12 @@ PRIVATE void end_update(clock_t now) /* End the update process and mark the affected service as no longer under * update. Eventual late ready to update message (if any) will simply be * ignored and the service can continue executing. - * Also, if the service has a period, update the alive and check timestamps - * of the service to force a status request in the next period. + * We reset the check timestamp, so that if the service has a period a status + * request will be forced in the next period. */ rupdate.flags &= ~RS_UPDATING; rupdate.rp->r_flags &= ~RS_UPDATING; - if(rupdate.rp->r_period > 0 ) { - rupdate.rp->r_alive_tm = now; - rupdate.rp->r_check_tm = now - rupdate.rp->r_period - 1; - } + rupdate.rp->r_check_tm = 0; } /*===========================================================================* @@ -783,6 +872,7 @@ PRIVATE void end_update(clock_t now) PUBLIC void do_exit(message *m_ptr) { register struct rproc *rp; + register struct rprocpub *rpub; pid_t exit_pid; int exit_status, r, slot_nr; endpoint_t ep; @@ -841,16 +931,17 @@ PUBLIC void do_exit(message *m_ptr) * This should always succeed. */ for (rp=BEG_RPROC_ADDR; rpr_pub; if ((rp->r_flags & RS_IN_USE) && rp->r_pid == exit_pid) { int proc; - proc = _ENDPOINT_P(rp->r_proc_nr_e); + proc = _ENDPOINT_P(rpub->endpoint); rproc_ptr[proc] = NULL; /* invalidate */ rp->r_pid= -1; /* If PCI properties are set, inform the PCI driver. */ - if(rp->r_nr_pci_id || rp->r_nr_pci_class) { - pci_del_acl(rp->r_proc_nr_e); + if(rpub->pci_acl.rsp_nr_device || rpub->pci_acl.rsp_nr_class) { + pci_del_acl(rpub->endpoint); } if ((rp->r_flags & RS_EXITING) || shutting_down) { @@ -868,7 +959,6 @@ PUBLIC void do_exit(message *m_ptr) short is_updating = rp->r_flags & RS_UPDATING; /* Refresh */ - rp->r_restarts = -1; /* reset counter */ if (rp->r_script[0] != '\0') run_script(rp); else { @@ -911,7 +1001,7 @@ rp->r_restarts= 0; rp->r_cmd, rp->r_backoff); rp->r_backoff = 1 << MIN(rp->r_restarts,(BACKOFF_BITS-2)); rp->r_backoff = MIN(rp->r_backoff,MAX_BACKOFF); - if ((rp->r_sys_flags & SF_USE_COPY) && rp->r_backoff > 1) + if ((rpub->sys_flags & SF_USE_COPY) && rp->r_backoff > 1) rp->r_backoff= 1; } else { @@ -937,9 +1027,11 @@ PUBLIC void do_period(m_ptr) message *m_ptr; { register struct rproc *rp; + register struct rprocpub *rpub; clock_t now = m_ptr->NOTIFY_TIMESTAMP; int s; endpoint_t ep; + long period; /* If an update is in progress, check its status. */ if(rupdate.flags & RS_UPDATING) { @@ -950,8 +1042,15 @@ message *m_ptr; * updating. */ for (rp=BEG_RPROC_ADDR; rpr_pub; if ((rp->r_flags & RS_IN_USE) && !(rp->r_flags & RS_UPDATING)) { + /* Compute period. */ + period = rpub->period; + if(rp->r_flags & RS_INITIALIZING) { + period = RS_INIT_T; + } + /* If the service is to be revived (because it repeatedly exited, * and was not directly restarted), the binary backoff field is * greater than zero. @@ -975,7 +1074,7 @@ message *m_ptr; /* There seems to be no special conditions. If the service has a * period assigned check its status. */ - else if (rp->r_period > 0) { + else if (period > 0) { /* Check if an answer to a status request is still pending. If * the service didn't respond within time, kill it to simulate @@ -983,12 +1082,15 @@ message *m_ptr; * be restarted automatically. */ if (rp->r_alive_tm < rp->r_check_tm) { - if (now - rp->r_alive_tm > 2*rp->r_period && + if (now - rp->r_alive_tm > 2*period && rp->r_pid > 0 && !(rp->r_flags & RS_NOPINGREPLY)) { if(rs_verbose) printf("RS: service %d reported late\n", - rp->r_proc_nr_e); + rpub->endpoint); rp->r_flags |= RS_NOPINGREPLY; + if(rp->r_flags & RS_INITIALIZING) { + rp->r_flags |= RS_EXITING; /* don't restart */ + } kill(rp->r_pid, SIGKILL); /* simulate crash */ } } @@ -996,12 +1098,12 @@ message *m_ptr; /* No answer pending. Check if a period expired since the last * check and, if so request the system service's status. */ - else if (now - rp->r_check_tm > rp->r_period) { + else if (now - rp->r_check_tm > rpub->period) { #if 0 if(rs_verbose) - printf("RS: status request sent to %d\n", rp->r_proc_nr_e); + printf("RS: status request sent to %d\n", rpub->endpoint); #endif - notify(rp->r_proc_nr_e); /* request status */ + notify(rpub->endpoint); /* request status */ rp->r_check_tm = now; /* mark time */ } } @@ -1029,17 +1131,20 @@ endpoint_t *endpoint; int child_proc_nr_e, child_proc_nr_n; /* child process slot */ pid_t child_pid; /* child's process id */ char *file_only; - int s, use_copy, slot_nr; + int s, use_copy, slot_nr, init_type; bitchunk_t *vm_mask; message m; char * null_env = NULL; + struct rprocpub *rpub; - use_copy= (rp->r_sys_flags & SF_USE_COPY); + rpub = rp->r_pub; + use_copy= (rpub->sys_flags & SF_USE_COPY); /* See if we are not using a copy but we do need one to start the service. */ - if(!use_copy && (rp->r_sys_flags & SF_NEED_COPY)) { + if(!use_copy && (rpub->sys_flags & SF_NEED_COPY)) { printf("RS: unable to start service %s without an in-memory copy\n", - rp->r_label); + rpub->label); + free_slot(rp); return(EPERM); } @@ -1097,13 +1202,14 @@ endpoint_t *endpoint; child_proc_nr_n = _ENDPOINT_P(child_proc_nr_e); rp->r_flags = RS_IN_USE | flags; /* mark slot in use */ rp->r_restarts += 1; /* raise nr of restarts */ - rp->r_proc_nr_e = child_proc_nr_e; /* set child details */ + rpub->endpoint = child_proc_nr_e; /* set child details */ rp->r_pid = child_pid; rp->r_check_tm = 0; /* not checked yet */ getuptime(&rp->r_alive_tm); /* currently alive */ rp->r_stop_tm = 0; /* not exiting yet */ rp->r_backoff = 0; /* not to be restarted */ rproc_ptr[child_proc_nr_n] = rp; /* mapping for fast access */ + rpub->in_use = TRUE; /* public entry is now in use */ /* If any of the calls below fail, the RS_EXITING flag is set. This implies * that the process will be removed from RS's process table once it has @@ -1136,7 +1242,7 @@ endpoint_t *endpoint; init_privs(rp, &rp->r_priv); /* Tell VM about allowed calls. */ - vm_mask = &rp->r_vm[0]; + vm_mask = &rpub->vm_call_mask[0]; if ((s = vm_set_priv(child_proc_nr_e, vm_mask)) < 0) { report("RS", "vm_set_priv call failed", s); kill(child_pid, SIGKILL); @@ -1155,7 +1261,7 @@ endpoint_t *endpoint; } /* If PCI properties are set, inform the PCI driver about the new service. */ - if(rp->r_nr_pci_id || rp->r_nr_pci_class) { + if(rpub->pci_acl.rsp_nr_device || rpub->pci_acl.rsp_nr_class) { init_pci(rp, child_proc_nr_e); } @@ -1166,7 +1272,7 @@ endpoint_t *endpoint; } /* Allow the service to run. - * XXX FIXME: we should let the service run only after publishing information + * XXX: We should let the service run/init only after publishing information * about the new system service, but this is not currently possible due to * the blocking nature of mapdriver() that expects the service to be running. * The current solution is not race-free. This hack can go once service @@ -1179,6 +1285,12 @@ endpoint_t *endpoint; return(s); /* return error */ } + /* Initialize service. */ + init_type = rp->r_restarts > 0 ? SEF_INIT_RESTART : SEF_INIT_FRESH; + if((s = init_service(rp, init_type)) != OK) { + panic("RS", "unable to initialize service", s); + } + /* The purpose of non-blocking forks is to avoid involving VFS in the forking * process, because VFS may be blocked on a sendrec() to a MFS that is * waiting for a endpoint update for a dead driver. We have just published @@ -1193,16 +1305,16 @@ endpoint_t *endpoint; setuid(0); /* Map the new service. */ - if (rp->r_dev_nr > 0) { /* set driver map */ - if ((s=mapdriver(rp->r_label, - rp->r_dev_nr, rp->r_dev_style, !!use_copy /* force */)) < 0) { + if (rpub->dev_nr > 0) { /* set driver map */ + if ((s=mapdriver(rpub->label, + rpub->dev_nr, rpub->dev_style, !!use_copy /* force */)) < 0) { report("RS", "couldn't map driver (continuing)", errno); } } if(rs_verbose) printf("RS: started '%s', major %d, pid %d, endpoint %d, proc %d\n", - rp->r_cmd, rp->r_dev_nr, child_pid, + rp->r_cmd, rpub->dev_nr, child_pid, child_proc_nr_e, child_proc_nr_n); /* The system service now has been successfully started. The only thing @@ -1254,6 +1366,10 @@ message *m_ptr; src_addr = (vir_bytes) rproc; len = sizeof(struct rproc) * NR_SYS_PROCS; break; + case SI_PROCPUB_TAB: + src_addr = (vir_bytes) rprocpub; + len = sizeof(struct rprocpub) * NR_SYS_PROCS; + break; default: return(EINVAL); } @@ -1281,9 +1397,15 @@ PRIVATE pid_t fork_nb() PRIVATE int share_exec(rp_dst, rp_src) struct rproc *rp_dst, *rp_src; { + struct rprocpub *rpub_src; + struct rprocpub *rpub_dst; + + rpub_src = rp_src->r_pub; + rpub_dst = rp_dst->r_pub; + if(rs_verbose) { printf("RS: share_exec: sharing exec image from %s to %s\n", - rp_src->r_label, rp_dst->r_label); + rpub_src->label, rpub_dst->label); } /* Share exec image from rp_src to rp_dst. */ @@ -1350,10 +1472,13 @@ PRIVATE void free_slot(rp) struct rproc *rp; { int slot_nr, has_shared_exec; + struct rprocpub *rpub; struct rproc *other_rp; + rpub = rp->r_pub; + /* Free memory if necessary. */ - if(rp->r_sys_flags & SF_USE_COPY) { + if(rpub->sys_flags & SF_USE_COPY) { /* Search for some other slot sharing the same exec image. */ has_shared_exec = FALSE; for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) { @@ -1367,7 +1492,8 @@ struct rproc *rp; /* If nobody uses our copy of the exec image, we can get rid of it. */ if(!has_shared_exec) { if(rs_verbose) { - printf("RS: free_slot: free exec image from %s\n", rp->r_label); + printf("RS: free_slot: free exec image from %s\n", + rpub->label); } free(rp->r_exec); rp->r_exec = NULL; @@ -1377,7 +1503,8 @@ struct rproc *rp; /* Mark slot as no longer in use.. */ rp->r_flags = 0; - rproc_ptr[_ENDPOINT_P(rp->r_proc_nr_e)] = NULL; + rpub->in_use = FALSE; + rproc_ptr[_ENDPOINT_P(rpub->endpoint)] = NULL; } /*===========================================================================* @@ -1386,12 +1513,14 @@ struct rproc *rp; PRIVATE void run_script(rp) struct rproc *rp; { - int r, proc_nr_e; + int r, endpoint; pid_t pid; char *reason; char incarnation_str[20]; /* Enough for a counter? */ char *envp[1] = { NULL }; + struct rprocpub *rpub; + rpub = rp->r_pub; if (rp->r_flags & RS_REFRESHING) reason= "restart"; else if (rp->r_flags & RS_NOPINGREPLY) @@ -1406,14 +1535,14 @@ struct rproc *rp; { printf( "RS: run_script: can't find reason for termination of '%s'\n", - rp->r_label); + rpub->label); return; } sprintf(incarnation_str, "%d", rp->r_restarts); if(rs_verbose) { printf("RS: calling script '%s'\n", rp->r_script); - printf("RS: sevice name: '%s'\n", rp->r_label); + printf("RS: sevice name: '%s'\n", rpub->label); printf("RS: reason: '%s'\n", reason); printf("RS: incarnation: '%s'\n", incarnation_str); } @@ -1425,20 +1554,20 @@ struct rproc *rp; printf("RS: run_script: fork failed: %s\n", strerror(errno)); break; case 0: - execle(rp->r_script, rp->r_script, rp->r_label, reason, + execle(rp->r_script, rp->r_script, rpub->label, reason, incarnation_str, NULL, envp); printf("RS: run_script: execl '%s' failed: %s\n", rp->r_script, strerror(errno)); exit(1); default: /* Set the privilege structure for the child process. */ - proc_nr_e = getnprocnr(pid); - if ((r = sys_privctl(proc_nr_e, SYS_PRIV_SET_USER, NULL)) + endpoint = getnprocnr(pid); + if ((r = sys_privctl(endpoint, SYS_PRIV_SET_USER, NULL)) != OK) { printf("RS: run_script: can't set privileges: %d\n",r); } - /* Allow the process to run. */ - if ((r = sys_privctl(proc_nr_e, SYS_PRIV_ALLOW, NULL)) != OK) { + /* Allow the service to run. */ + if ((r = sys_privctl(endpoint, SYS_PRIV_ALLOW, NULL)) != OK) { printf("RS: run_script: process can't run: %d\n",r); } /* Do not wait for the child */ @@ -1473,7 +1602,7 @@ char *caller_label; if (q == p) continue; len= q-p; - if (len > MAX_LABEL_LEN) + if (len > RS_MAX_LABEL_LEN) { printf( "rs:get_next_label: bad ipc list entry '.*s' for %s: too long\n", @@ -1499,35 +1628,38 @@ struct priv *privp; /* Add IPC send permissions to a process based on that process's IPC * list. */ - char label[MAX_LABEL_LEN+1], *p; + char label[RS_MAX_LABEL_LEN+1], *p; struct rproc *tmp_rp; - endpoint_t proc_nr_e; + struct rprocpub *tmp_rpub; + endpoint_t endpoint; int r; int slot_nr, priv_id; struct priv priv; + struct rprocpub *rpub; + rpub = rp->r_pub; p = rp->r_ipc_list; - while ((p = get_next_label(p, label, rp->r_label)) != NULL) { + while ((p = get_next_label(p, label, rpub->label)) != NULL) { if (strcmp(label, "SYSTEM") == 0) - proc_nr_e= SYSTEM; + endpoint= SYSTEM; else if (strcmp(label, "USER") == 0) - proc_nr_e= INIT_PROC_NR; /* all user procs */ + endpoint= INIT_PROC_NR; /* all user procs */ else if (strcmp(label, "PM") == 0) - proc_nr_e= PM_PROC_NR; + endpoint= PM_PROC_NR; else if (strcmp(label, "VFS") == 0) - proc_nr_e= FS_PROC_NR; + endpoint= FS_PROC_NR; else if (strcmp(label, "RS") == 0) - proc_nr_e= RS_PROC_NR; + endpoint= RS_PROC_NR; else if (strcmp(label, "LOG") == 0) - proc_nr_e= LOG_PROC_NR; + endpoint= LOG_PROC_NR; else if (strcmp(label, "TTY") == 0) - proc_nr_e= TTY_PROC_NR; + endpoint= TTY_PROC_NR; else if (strcmp(label, "DS") == 0) - proc_nr_e= DS_PROC_NR; + endpoint= DS_PROC_NR; else if (strcmp(label, "VM") == 0) - proc_nr_e= VM_PROC_NR; + endpoint= VM_PROC_NR; else { /* Try to find process */ @@ -1537,7 +1669,8 @@ struct priv *privp; tmp_rp = &rproc[slot_nr]; if (!(tmp_rp->r_flags & RS_IN_USE)) continue; - if (strcmp(tmp_rp->r_label, label) == 0) + tmp_rpub = tmp_rp->r_pub; + if (strcmp(tmp_rpub->label, label) == 0) break; } if (slot_nr >= NR_SYS_PROCS) @@ -1547,10 +1680,10 @@ struct priv *privp; "add_forward_ipc: unable to find '%s'\n", label); continue; } - proc_nr_e= tmp_rp->r_proc_nr_e; + endpoint= tmp_rpub->endpoint; } - if ((r = sys_getpriv(&priv, proc_nr_e)) < 0) + if ((r = sys_getpriv(&priv, endpoint)) < 0) { printf( "add_forward_ipc: unable to get priv_id for '%s': %d\n", @@ -1576,8 +1709,9 @@ struct priv *privp; * add these permissions now because the current process may not yet * have existed at the time that the other process was initialized. */ - char label[MAX_LABEL_LEN+1], *p; + char label[RS_MAX_LABEL_LEN+1], *p; struct rproc *rrp; + struct rprocpub *rrpub; int priv_id, found; for (rrp=BEG_RPROC_ADDR; rrpr_ipc_list[0]) { found = 0; + rrpub = rrp->r_pub; p = rrp->r_ipc_list; - while ((p = get_next_label(p, label, rp->r_label)) != - NULL) { - if (!strcmp(rp->r_label, label)) { + while ((p = get_next_label(p, label, + rrpub->label)) != NULL) { + if (!strcmp(rrpub->label, label)) { found = 1; break; } @@ -1628,7 +1763,7 @@ struct priv *privp; src_bits_per_word= 8*sizeof(rp->r_call_mask[0]); dst_bits_per_word= 8*sizeof(privp->s_k_call_mask[0]); - for (src_word= 0; src_word < RSS_NR_SYSTEM; src_word++) + for (src_word= 0; src_word < RS_SYS_CALL_MASK_SIZE; src_word++) { for (src_bit= 0; src_bit < src_bits_per_word; src_bit++) { @@ -1642,7 +1777,7 @@ struct priv *privp; #endif dst_word= call_nr / dst_bits_per_word; mask= (1UL << (call_nr % dst_bits_per_word)); - if (dst_word >= CALL_MASK_SIZE) + if (dst_word >= SYS_CALL_MASK_SIZE) { printf( "RS: init_privs: call number %d doesn't fit\n", @@ -1682,53 +1817,13 @@ int endpoint; size_t len; int i, r; struct rs_pci rs_pci; + struct rprocpub *rpub; - if (strcmp(rp->r_label, "pci") == 0) - { - if(rs_verbose) - printf("RS: init_pci: not when starting 'pci'\n"); - return; - } - - len= strlen(rp->r_label); - if (len+1 > sizeof(rs_pci.rsp_label)) - { - if(rs_verbose) - printf("RS: init_pci: label '%s' too long for rsp_label\n", - rp->r_label); - return; - } - strcpy(rs_pci.rsp_label, rp->r_label); + rpub = rp->r_pub; + rs_pci = rpub->pci_acl; + strcpy(rs_pci.rsp_label, rpub->label); rs_pci.rsp_endpoint= endpoint; - rs_pci.rsp_nr_device= rp->r_nr_pci_id; - if (rs_pci.rsp_nr_device > RSP_NR_DEVICE) - { - printf("RS: init_pci: too many PCI devices (max %d) " - "truncating\n", - RSP_NR_DEVICE); - rs_pci.rsp_nr_device= RSP_NR_DEVICE; - } - for (i= 0; ir_pci_id[i].vid; - rs_pci.rsp_device[i].did= rp->r_pci_id[i].did; - } - - rs_pci.rsp_nr_class= rp->r_nr_pci_class; - if (rs_pci.rsp_nr_class > RSP_NR_CLASS) - { - printf("RS: init_pci: too many PCI classes " - "(max %d) truncating\n", - RSP_NR_CLASS); - rs_pci.rsp_nr_class= RSP_NR_CLASS; - } - for (i= 0; ir_pci_class[i].class; - rs_pci.rsp_class[i].mask= rp->r_pci_class[i].mask; - } - if(rs_verbose) printf("RS: init_pci: calling pci_set_acl\n"); @@ -1754,6 +1849,7 @@ message *m_ptr; static char namebuf[100]; int len, r; struct rproc *rrp; + struct rprocpub *rrpub; len = m_ptr->RS_NAME_LEN; @@ -1774,8 +1870,9 @@ message *m_ptr; for (rrp=BEG_RPROC_ADDR; rrpr_flags & RS_IN_USE)) continue; - if (!strcmp(rrp->r_label, namebuf)) { - m_ptr->RS_ENDPOINT = rrp->r_proc_nr_e; + rrpub = rrp->r_pub; + if (!strcmp(rrpub->label, namebuf)) { + m_ptr->RS_ENDPOINT = rrpub->endpoint; return OK; } } diff --git a/servers/rs/proto.h b/servers/rs/proto.h index 7bccb85ae..09b3a9f17 100644 --- a/servers/rs/proto.h +++ b/servers/rs/proto.h @@ -18,13 +18,17 @@ _PROTOTYPE( int do_restart, (message *m)); _PROTOTYPE( int do_lookup, (message *m)); _PROTOTYPE( int do_shutdown, (message *m)); _PROTOTYPE( void do_period, (message *m)); +_PROTOTYPE( int do_init_ready, (message *m)); _PROTOTYPE( int do_update, (message *m)); _PROTOTYPE( int do_upd_ready, (message *m)); _PROTOTYPE( void do_exit, (message *m)); _PROTOTYPE( int do_getsysinfo, (message *m)); /* utility.c */ +_PROTOTYPE( int init_service, (struct rproc *rp, int type)); _PROTOTYPE( int publish_service, (struct rproc *rp)); +_PROTOTYPE(void fill_call_mask, ( int *calls, int tot_nr_calls, + bitchunk_t *call_mask, int call_base, int is_init)); /* memory.c */ _PROTOTYPE( void* rs_startup_sbrk, (size_t size)); diff --git a/servers/rs/service.c b/servers/rs/service.c index 9a8f6c934..cc4884420 100644 --- a/servers/rs/service.c +++ b/servers/rs/service.c @@ -196,12 +196,12 @@ PRIVATE int parse_arguments(int argc, char **argv) } if (req_nr == RS_UP) { - rs_start.rss_flags= RF_IPC_VALID; + rs_start.rss_flags= RSS_IPC_VALID; if (c_flag) - rs_start.rss_flags |= RF_COPY; + rs_start.rss_flags |= RSS_COPY; if(r_flag) - rs_start.rss_flags |= RF_REUSE; + rs_start.rss_flags |= RSS_REUSE; if (do_run) { @@ -610,10 +610,10 @@ PRIVATE void do_pci_device(config_t *cpe) fatal("do_pci_device: bad ID '%s' at %s:%d", cpe->word, cpe->file, cpe->line); } - if (rs_start.rss_nr_pci_id >= RSS_NR_PCI_ID) + if (rs_start.rss_nr_pci_id >= RS_NR_PCI_DEVICE) { fatal("do_pci_device: too many device IDs (max %d)", - RSS_NR_PCI_ID); + RS_NR_PCI_DEVICE); } rs_start.rss_pci_id[rs_start.rss_nr_pci_id].vid= vid; rs_start.rss_pci_id[rs_start.rss_nr_pci_id].did= did; @@ -662,10 +662,10 @@ PRIVATE void do_pci_class(config_t *cpe) cpe->word, cpe->file, cpe->line); } class_id= (baseclass << 16) | (subclass << 8) | interface; - if (rs_start.rss_nr_pci_class >= RSS_NR_PCI_CLASS) + if (rs_start.rss_nr_pci_class >= RS_NR_PCI_CLASS) { fatal("do_pci_class: too many class IDs (max %d)", - RSS_NR_PCI_CLASS); + RS_NR_PCI_CLASS); } rs_start.rss_pci_class[rs_start.rss_nr_pci_class].class= class_id; @@ -877,10 +877,10 @@ PRIVATE void do_system(config_t *cpe) word= call_nr / bits_per_word; mask= (1UL << (call_nr % bits_per_word)); - if (word >= RSS_NR_SYSTEM) + if (word >= RS_SYS_CALL_MASK_SIZE) { fatal( - "do_system: RSS_NR_SYSTEM is too small (%d needed)", + "RS_SYS_CALL_MASK_SIZE is too small (%d needed)", word+1); } rs_start.rss_system[word] |= mask; @@ -904,10 +904,10 @@ PRIVATE void do_control(config_t *cpe) fatal("do_control: unexpected string at %s:%d", cpe->file, cpe->line); } - if (nr_control >= RSS_NR_CONTROL) + if (nr_control >= RS_NR_CONTROL) { fatal( - "do_control: RSS_NR_CONTROL is too small (%d needed)", + "do_control: RS_NR_CONTROL is too small (%d needed)", nr_control+1); } diff --git a/servers/rs/table.c b/servers/rs/table.c index 84eb51f00..de4c40e70 100644 --- a/servers/rs/table.c +++ b/servers/rs/table.c @@ -8,50 +8,78 @@ #include "inc.h" -/* Define kernel calls that processes are allowed to make. This is not looking - * very nice, but we need to define the access rights on a per call basis. +/* Define kernel calls that processes are allowed to make. * * Calls are unordered lists, converted by RS to bitmasks * once at runtime. */ -#define FS_KC SYS_KILL, SYS_VIRCOPY, SYS_SAFECOPYFROM, SYS_SAFECOPYTO, \ +#define FS_KC SYS_KILL, SYS_VIRCOPY, SYS_SAFECOPYFROM, SYS_SAFECOPYTO, \ SYS_UMAP, SYS_GETINFO, SYS_EXIT, SYS_TIMES, SYS_SETALARM, \ SYS_PRIVCTL, SYS_TRACE , SYS_SETGRANT, SYS_PROFBUF, SYS_SYSCTL #define DRV_KC FS_KC, SYS_SEGCTL, SYS_IRQCTL, SYS_INT86, SYS_DEVIO, \ SYS_SDEVIO, SYS_VDEVIO, SYS_SETGRANT, SYS_PROFBUF, SYS_SYSCTL PRIVATE int - fs_kc[] = { FS_KC, SYS_NULL_C }, - pm_kc[] = { SYS_ALL_C, SYS_NULL_C }, - ds_kc[] = { SYS_ALL_C, SYS_NULL_C }, - vm_kc[] = { SYS_ALL_C, SYS_NULL_C }, - drv_kc[] = { DRV_KC, SYS_NULL_C }, - tty_kc[] = { DRV_KC, SYS_PHYSCOPY, SYS_ABORT, SYS_IOPENABLE, + pm_kc[] = { SYS_ALL_C, SYS_NULL_C }, + vfs_kc[] = { FS_KC, SYS_NULL_C }, + rs_kc[] = { SYS_ALL_C, SYS_NULL_C }, + ds_kc[] = { SYS_ALL_C, SYS_NULL_C }, + vm_kc[] = { SYS_ALL_C, SYS_NULL_C }, + tty_kc[] = { DRV_KC, SYS_PHYSCOPY, SYS_ABORT, SYS_IOPENABLE, SYS_READBIOS, SYS_NULL_C }, - mem_kc[] = { DRV_KC, SYS_PHYSCOPY, SYS_IOPENABLE, SYS_NULL_C }, + mem_kc[] = { DRV_KC, SYS_PHYSCOPY, SYS_IOPENABLE, SYS_NULL_C}, + log_kc[] = { DRV_KC, SYS_NULL_C }, + mfs_kc[] = { FS_KC, SYS_NULL_C }, + pfs_kc[] = { FS_KC, SYS_NULL_C }, rusr_kc[] = { SYS_NULL_C }, + no_kc[] = { SYS_NULL_C }; /* no kernel call */ - no_kc[] = { SYS_NULL_C }; /* no kernel call */ +/* Define VM calls that processes are allowed to make. + * + * Calls are unordered lists, converted by RS to bitmasks + * once at runtime. + */ +PRIVATE int + pm_vmc[] = { VM_BASIC_CALLS, VM_EXIT, VM_FORK, VM_BRK, VM_EXEC_NEWMEM, + VM_PUSH_SIG, VM_WILLEXIT, VM_ADDDMA, VM_DELDMA, VM_GETDMA, + VM_NOTIFY_SIG, SYS_NULL_C }, + vfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C }, + rs_vmc[] = { VM_BASIC_CALLS, VM_RS_SET_PRIV, SYS_NULL_C }, + ds_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C }, + vm_vmc[] = { SYS_NULL_C }, + tty_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C }, + mem_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C }, + log_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C }, + mfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C }, + pfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C }, + rusr_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C }, + no_vmc[] = { SYS_NULL_C }; /* no vm call */ -/* Definition of the boot image priv table. */ +/* Definition of the boot image priv table. The order of entries in this table + * reflects the order boot system services are made runnable and initialized + * at boot time. + */ PUBLIC struct boot_image_priv boot_image_priv_table[] = { - /*endpoint, label, flags, traps, ipcto, kcalls */ - { VM_PROC_NR, "vm", VM_F, SRV_T, SRV_M, vm_kc }, - { PM_PROC_NR, "pm", SRV_F, SRV_T, SRV_M, pm_kc }, - { FS_PROC_NR, "vfs", SRV_F, SRV_T, SRV_M, fs_kc }, - { DS_PROC_NR, "ds", SRV_F, SRV_T, SRV_M, ds_kc }, - { TTY_PROC_NR, "tty", SRV_F, SRV_T, SRV_M, tty_kc }, - { MEM_PROC_NR, "memory", SRV_F, SRV_T, SRV_M, mem_kc }, - { LOG_PROC_NR, "log", SRV_F, SRV_T, SRV_M, drv_kc }, - { MFS_PROC_NR, "fs_imgrd", SRV_F, SRV_T, SRV_M, fs_kc }, - { PFS_PROC_NR, "pfs", SRV_F, SRV_T, SRV_M, fs_kc }, - { INIT_PROC_NR, "init", RUSR_F, RUSR_T, RUSR_M, rusr_kc }, - { NULL_BOOT_NR, "", 0, 0, 0, no_kc } /* null entry */ + /*endpoint, label, flags, traps, ipcto, kcalls, vmcalls */ + { RS_PROC_NR, "rs", RSYS_F, RSYS_T, RSYS_M, rs_kc, rs_vmc }, + { VM_PROC_NR, "vm", VM_F, SRV_T, SRV_M, vm_kc, vm_vmc }, + { PM_PROC_NR, "pm", SRV_F, SRV_T, SRV_M, pm_kc, pm_vmc }, + { VFS_PROC_NR, "vfs", SRV_F, SRV_T, SRV_M, vfs_kc, vfs_vmc }, + { DS_PROC_NR, "ds", SRV_F, SRV_T, SRV_M, ds_kc, ds_vmc }, + { TTY_PROC_NR, "tty", SRV_F, SRV_T, SRV_M, tty_kc, tty_vmc }, + { MEM_PROC_NR, "memory", SRV_F, SRV_T, SRV_M, mem_kc, mem_vmc }, + { LOG_PROC_NR, "log", SRV_F, SRV_T, SRV_M, log_kc, log_vmc }, + { MFS_PROC_NR, "fs_imgrd", SRV_F, SRV_T, SRV_M, mfs_kc, mfs_vmc }, + { PFS_PROC_NR, "pfs", SRV_F, SRV_T, SRV_M, pfs_kc, pfs_vmc }, + { INIT_PROC_NR, "init", RUSR_F, RUSR_T, RUSR_M, rusr_kc, rusr_vmc }, + { NULL_BOOT_NR, "", 0, 0, 0, no_kc, no_vmc } }; /* Definition of the boot image sys table. */ PUBLIC struct boot_image_sys boot_image_sys_table[] = { /*endpoint, flags */ + { RS_PROC_NR, SRV_SF }, + { VM_PROC_NR, VM_SF }, { LOG_PROC_NR, SRVC_SF }, { MFS_PROC_NR, SRVC_SF }, { PFS_PROC_NR, SRVC_SF }, diff --git a/servers/rs/type.h b/servers/rs/type.h index aebd82224..3fce4533f 100644 --- a/servers/rs/type.h +++ b/servers/rs/type.h @@ -6,12 +6,13 @@ /* Definition of an entry of the boot image priv table. */ struct boot_image_priv { endpoint_t endpoint; /* process endpoint number */ - char label[MAX_LABEL_LEN]; /* label to assign to this service */ + char label[RS_MAX_LABEL_LEN]; /* label to assign to this service */ int flags; /* privilege flags */ short trap_mask; /* allowed system call traps */ int ipc_to; /* send mask protection */ - int *k_calls; /* kernel call protection */ + int *k_calls; /* allowed kernel calls */ + int *vm_calls; /* allowed vm calls */ }; /* Definition of an entry of the boot image sys table. */ @@ -32,49 +33,37 @@ struct boot_image_dev { /* Definition of an entry of the system process table. */ struct rproc { - endpoint_t r_proc_nr_e; /* process endpoint number */ + struct rprocpub *r_pub; /* pointer to the corresponding public entry */ pid_t r_pid; /* process id, -1 if the process is not there */ - dev_t r_dev_nr; /* major device number */ - int r_dev_style; /* device style */ int r_restarts; /* number of restarts (initially zero) */ long r_backoff; /* number of periods to wait before revive */ unsigned r_flags; /* status and policy flags */ - unsigned r_sys_flags; /* sys flags */ - long r_period; /* heartbeat period (or zero) */ clock_t r_check_tm; /* timestamp of last check */ clock_t r_alive_tm; /* timestamp of last heartbeat */ clock_t r_stop_tm; /* timestamp of SIGTERM signal */ endpoint_t r_caller; /* RS_LATEREPLY caller */ - char *r_exec; /* Executable image */ - size_t r_exec_len; /* Length of image */ - - char r_label[MAX_LABEL_LEN]; /* label of this service */ - char r_proc_name[P_NAME_LEN]; /* process name of this service */ char r_cmd[MAX_COMMAND_LEN]; /* raw command plus arguments */ char r_script[MAX_SCRIPT_LEN]; /* name of the restart script executable */ char *r_argv[MAX_NR_ARGS+2]; /* parsed arguments vector */ int r_argc; /* number of arguments */ - /* Resources */ - int r_set_resources; + char *r_exec; /* Executable image */ + size_t r_exec_len; /* Length of image */ + + int r_set_resources; /* set when resources must be set. */ struct priv r_priv; /* Privilege structure to be passed to the * kernel. */ uid_t r_uid; int r_nice; - int r_nr_pci_id; /* Number of PCI devices IDs */ - struct { u16_t vid; u16_t did; } r_pci_id[RSS_NR_PCI_ID]; - int r_nr_pci_class; /* Number of PCI class IDs */ - struct { u32_t class; u32_t mask; } r_pci_class[RSS_NR_PCI_CLASS]; - u32_t r_call_mask[RSS_NR_SYSTEM]; + u32_t r_call_mask[RS_SYS_CALL_MASK_SIZE]; char r_ipc_list[MAX_IPC_LIST]; - bitchunk_t r_vm[RSS_VM_CALL_SIZE]; int r_nr_control; - char r_control[RSS_NR_CONTROL][MAX_LABEL_LEN]; + char r_control[RS_NR_CONTROL][RS_MAX_LABEL_LEN]; }; /* Definition of the global update descriptor. */ diff --git a/servers/rs/utility.c b/servers/rs/utility.c index 5caf96c58..e58f3fdad 100644 --- a/servers/rs/utility.c +++ b/servers/rs/utility.c @@ -8,6 +8,30 @@ #include +/*===========================================================================* + * init_service * + *===========================================================================*/ +PUBLIC int init_service(rp, type) +struct rproc *rp; /* pointer to process slot */ +int type; /* type of initialization */ +{ + int r; + message m; + struct rprocpub *rpub; + + rpub = rp->r_pub; + + rp->r_flags |= RS_INITIALIZING; /* now initializing */ + rp->r_check_tm = rp->r_alive_tm + 1; /* expect reply within period */ + + m.m_type = RS_INIT; + m.RS_INIT_TYPE = type; + m.RS_INIT_RPROCTAB_GID = rinit.rproctab_gid; + r = asynsend(rpub->endpoint, &m); + + return r; +} + /*===========================================================================* * publish_service * *===========================================================================*/ @@ -16,17 +40,62 @@ struct rproc *rp; /* pointer to process slot */ { /* A new system service has been started. Publish the necessary information. */ int s; + struct rprocpub *rpub; + + rpub = rp->r_pub; /* Register its label with DS. */ - s= ds_publish_u32(rp->r_label, rp->r_proc_nr_e); + s= ds_publish_u32(rpub->label, rpub->endpoint); if (s != OK) { return s; } if (rs_verbose) { printf("RS: publish_service: DS label registration done: %s -> %d\n", - rp->r_label, rp->r_proc_nr_e); + rpub->label, rpub->endpoint); } return(OK); } +/*===========================================================================* + * fill_call_mask * + *===========================================================================*/ +PUBLIC void fill_call_mask(calls, tot_nr_calls, call_mask, call_base, is_init) +int *calls; /* the unordered set of calls */ +int tot_nr_calls; /* the total number of calls */ +bitchunk_t *call_mask; /* the call mask to fill in */ +int call_base; /* the base offset for the calls */ +int is_init; /* set when initializing a call mask */ +{ +/* Fill a call mask from an unordered set of calls. */ + int i; + int call_mask_size, nr_calls; + + call_mask_size = BITMAP_CHUNKS(tot_nr_calls); + + /* Count the number of calls to fill in. */ + nr_calls = 0; + for(i=0; calls[i] != SYS_NULL_C; i++) { + nr_calls++; + } + + /* See if all calls are allowed and call mask must be completely filled. */ + if(nr_calls == 1 && calls[0] == SYS_ALL_C) { + for(i=0; i < call_mask_size; i++) { + call_mask[i] = (~0); + } + } + else { + /* When initializing, reset the mask first. */ + if(is_init) { + for(i=0; i < call_mask_size; i++) { + call_mask[i] = 0; + } + } + /* Enter calls bit by bit. */ + for(i=0; i < nr_calls; i++) { + SET_BIT(call_mask, calls[i] - call_base); + } + } +} + diff --git a/servers/vfs/main.c b/servers/vfs/main.c index 0c06e53d1..1d7431f9d 100644 --- a/servers/vfs/main.c +++ b/servers/vfs/main.c @@ -39,13 +39,13 @@ EXTERN unsigned long calls_stats[NCALLS]; #endif -FORWARD _PROTOTYPE( void fs_init, (void) ); FORWARD _PROTOTYPE( void get_work, (void) ); FORWARD _PROTOTYPE( void init_root, (void) ); FORWARD _PROTOTYPE( void service_pm, (void) ); /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * main * @@ -61,14 +61,6 @@ PUBLIC int main(void) /* SEF local startup. */ sef_local_startup(); - fs_init(); - - SANITYCHECK; - -#if DO_SANITYCHECKS - FIXME("VFS: DO_SANITYCHECKS is on"); -#endif - /* This is the main loop that gets work, processes it, and sends replies. */ while (TRUE) { SANITYCHECK; @@ -228,12 +220,106 @@ PUBLIC int main(void) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_restart_fail); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } +/*===========================================================================* + * sef_cb_init_fresh * + *===========================================================================*/ +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) +{ +/* Initialize the virtual file server. */ + int s; + register struct fproc *rfp; + struct vmnt *vmp; + struct vnode *root_vp; + message mess; + + /* Clear endpoint field */ + last_login_fs_e = NONE; + mount_m_in.m1_p3 = (char *) NONE; + + /* Initialize the process table with help of the process manager messages. + * Expect one message for each system process with its slot number and pid. + * When no more processes follow, the magic process number NONE is sent. + * Then, stop and synchronize with the PM. + */ + do { + if (OK != (s=sef_receive(PM_PROC_NR, &mess))) + panic(__FILE__,"FS couldn't receive from PM", s); + + if (mess.m_type != PM_INIT) + panic(__FILE__, "unexpected message from PM", mess.m_type); + + if (NONE == mess.PM_PROC) break; + + rfp = &fproc[mess.PM_SLOT]; + rfp->fp_pid = mess.PM_PID; + rfp->fp_endpoint = mess.PM_PROC; + rfp->fp_realuid = (uid_t) SYS_UID; + rfp->fp_effuid = (uid_t) SYS_UID; + rfp->fp_realgid = (gid_t) SYS_GID; + rfp->fp_effgid = (gid_t) SYS_GID; + rfp->fp_umask = ~0; + rfp->fp_grant = GRANT_INVALID; + rfp->fp_blocked_on = FP_BLOCKED_ON_NONE; + rfp->fp_revived = NOT_REVIVING; + + } while (TRUE); /* continue until process NONE */ + mess.m_type = OK; /* tell PM that we succeeded */ + s = send(PM_PROC_NR, &mess); /* send synchronization message */ + + /* All process table entries have been set. Continue with FS initialization. + * Certain relations must hold for the file system to work at all. Some + * extra block_size requirements are checked at super-block-read-in time. + */ + if (OPEN_MAX > 127) panic(__FILE__,"OPEN_MAX > 127", NO_NUM); + + /* The following initializations are needed to let dev_opcl succeed .*/ + fp = (struct fproc *) NULL; + who_e = who_p = FS_PROC_NR; + + build_dmap(); /* build device table and map boot driver */ + init_root(); /* init root device and load super block */ + init_select(); /* init select() structures */ + + + vmp = &vmnt[0]; /* Should be the root filesystem */ + if (vmp->m_dev == NO_DEV) + panic(__FILE__, "vfs: no root filesystem", NO_NUM); + root_vp= vmp->m_root_node; + + /* The root device can now be accessed; set process directories. */ + for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) { + FD_ZERO(&(rfp->fp_filp_inuse)); + if (rfp->fp_pid != PID_FREE) { + + dup_vnode(root_vp); + rfp->fp_rd = root_vp; + dup_vnode(root_vp); + rfp->fp_wd = root_vp; + + } else rfp->fp_endpoint = NONE; + } + + system_hz = sys_hz(); + + SANITYCHECK; + +#if DO_SANITYCHECKS + FIXME("VFS: DO_SANITYCHECKS is on"); +#endif + + return(OK); +} + /*===========================================================================* * get_work * *===========================================================================*/ @@ -347,88 +433,6 @@ int result; /* result of the call (usually OK or error #) */ result, whom, s); } -/*===========================================================================* - * fs_init * - *===========================================================================*/ -PRIVATE void fs_init() -{ -/* Initialize global variables, tables, etc. */ - int s; - register struct fproc *rfp; - struct vmnt *vmp; - struct vnode *root_vp; - message mess; - - /* Clear endpoint field */ - last_login_fs_e = NONE; - mount_m_in.m1_p3 = (char *) NONE; - - /* Initialize the process table with help of the process manager messages. - * Expect one message for each system process with its slot number and pid. - * When no more processes follow, the magic process number NONE is sent. - * Then, stop and synchronize with the PM. - */ - do { - if (OK != (s=sef_receive(PM_PROC_NR, &mess))) - panic(__FILE__,"FS couldn't receive from PM", s); - - if (mess.m_type != PM_INIT) - panic(__FILE__, "unexpected message from PM", mess.m_type); - - if (NONE == mess.PM_PROC) break; - - rfp = &fproc[mess.PM_SLOT]; - rfp->fp_pid = mess.PM_PID; - rfp->fp_endpoint = mess.PM_PROC; - rfp->fp_realuid = (uid_t) SYS_UID; - rfp->fp_effuid = (uid_t) SYS_UID; - rfp->fp_realgid = (gid_t) SYS_GID; - rfp->fp_effgid = (gid_t) SYS_GID; - rfp->fp_umask = ~0; - rfp->fp_grant = GRANT_INVALID; - rfp->fp_blocked_on = FP_BLOCKED_ON_NONE; - rfp->fp_revived = NOT_REVIVING; - - } while (TRUE); /* continue until process NONE */ - mess.m_type = OK; /* tell PM that we succeeded */ - s = send(PM_PROC_NR, &mess); /* send synchronization message */ - - /* All process table entries have been set. Continue with FS initialization. - * Certain relations must hold for the file system to work at all. Some - * extra block_size requirements are checked at super-block-read-in time. - */ - if (OPEN_MAX > 127) panic(__FILE__,"OPEN_MAX > 127", NO_NUM); - - /* The following initializations are needed to let dev_opcl succeed .*/ - fp = (struct fproc *) NULL; - who_e = who_p = FS_PROC_NR; - - build_dmap(); /* build device table and map boot driver */ - init_root(); /* init root device and load super block */ - init_select(); /* init select() structures */ - - - vmp = &vmnt[0]; /* Should be the root filesystem */ - if (vmp->m_dev == NO_DEV) - panic(__FILE__, "vfs:fs_init: no root filesystem", NO_NUM); - root_vp= vmp->m_root_node; - - /* The root device can now be accessed; set process directories. */ - for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) { - FD_ZERO(&(rfp->fp_filp_inuse)); - if (rfp->fp_pid != PID_FREE) { - - dup_vnode(root_vp); - rfp->fp_rd = root_vp; - dup_vnode(root_vp); - rfp->fp_wd = root_vp; - - } else rfp->fp_endpoint = NONE; - } - - system_hz = sys_hz(); -} - /*===========================================================================* * init_root * *===========================================================================*/ diff --git a/servers/vm/fork.c b/servers/vm/fork.c index 195146438..091c5a324 100644 --- a/servers/vm/fork.c +++ b/servers/vm/fork.c @@ -144,8 +144,7 @@ PUBLIC int do_fork(message *msg) vmc->vm_flags &= (VMF_INUSE|VMF_SEPARATE|VMF_HASPT); /* inherit the priv call bitmaps */ - memcpy(&vmc->vm_call_priv_mask, &vmp->vm_call_priv_mask, - sizeof(vmc->vm_call_priv_mask)); + memcpy(&vmc->vm_call_mask, &vmp->vm_call_mask, sizeof(vmc->vm_call_mask)); /* Tell kernel about the (now successful) FORK. */ if((r=sys_fork(vmp->vm_endpoint, childproc, diff --git a/servers/vm/main.c b/servers/vm/main.c index 65d38517d..7524eb344 100644 --- a/servers/vm/main.c +++ b/servers/vm/main.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -40,21 +41,11 @@ extern int missing_spares; #include "../../kernel/config.h" #include "../../kernel/proc.h" -typedef u32_t mask_t; -#define MINEPM 0 -#define MAXMASK (sizeof(mask_t)*8) -#define ANYEPM (MINEPM+MAXMASK-1) -#define NEEDACL (MINEPM+MAXMASK-2) -#define MAXEPM (NEEDACL-1) -#define EPM(e) ((1L) << ((e)-MINEPM)) -#define EPMOK(mask, ep) (((mask) & EPM(ANYEPM)) || ((ep) >= MINEPM && (ep) <= MAXEPM && (EPM(ep) & (mask)))) - /* Table of calls and a macro to test for being in range. */ struct { - mask_t vmc_callers; /* bitmap of endpoint numbers */ int (*vmc_func)(message *); /* Call handles message. */ char *vmc_name; /* Human-readable string. */ -} vm_calls[VM_NCALLS]; +} vm_calls[NR_VM_CALLS]; /* Macro to verify call range and map 'high' range to 'base' range * (starting at 0) in one. Evaluates to zero-based call number if call @@ -64,11 +55,14 @@ struct { (c) < VM_RQ_BASE + ELEMENTS(vm_calls)) ? \ ((c) - VM_RQ_BASE) : -1) -FORWARD _PROTOTYPE(void vm_init, (void)); +FORWARD _PROTOTYPE(int map_service, (struct rprocpub *rpub)); FORWARD _PROTOTYPE(int vm_acl_ok, (endpoint_t caller, int call)); +extern int unmap_ok; + /* SEF functions and variables. */ FORWARD _PROTOTYPE( void sef_local_startup, (void) ); +FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) ); /*===========================================================================* * main * @@ -81,19 +75,6 @@ PUBLIC int main(void) /* SEF local startup. */ sef_local_startup(); -#if SANITYCHECKS - incheck = nocheck = 0; - FIXME("VM SANITYCHECKS are on"); -#endif - - vm_paged = 1; - env_parse("vm_paged", "d", 0, &vm_paged, 0, 1); -#if SANITYCHECKS - env_parse("vm_sanitychecklevel", "d", 0, &vm_sanitychecklevel, 0, SCL_MAX); -#endif - - vm_init(); - /* This is VM's main loop. */ while (TRUE) { int r, c; @@ -171,26 +152,41 @@ PUBLIC int main(void) *===========================================================================*/ PRIVATE void sef_local_startup() { + /* Register init callbacks. */ + sef_setcb_init_fresh(sef_cb_init_fresh); + sef_setcb_init_restart(sef_cb_init_restart_fail); + /* No live update support for now. */ /* Let SEF perform startup. */ sef_startup(); } -extern int unmap_ok; - /*===========================================================================* - * vm_init * + * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE void vm_init(void) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { +/* Initialize the vm server. */ int s, i; int click, clicksforgotten = 0; struct memory mem_chunks[NR_MEMS]; struct boot_image image[NR_BOOT_PROCS]; struct boot_image *ip; + struct rprocpub rprocpub[NR_BOOT_PROCS]; phys_bytes limit = 0; +#if SANITYCHECKS + incheck = nocheck = 0; + FIXME("VM SANITYCHECKS are on"); +#endif + + vm_paged = 1; + env_parse("vm_paged", "d", 0, &vm_paged, 0, 1); +#if SANITYCHECKS + env_parse("vm_sanitychecklevel", "d", 0, &vm_sanitychecklevel, 0, SCL_MAX); +#endif + /* Get chunks of available memory. */ get_mem_chunks(mem_chunks); @@ -285,7 +281,7 @@ PRIVATE void vm_init(void) vmp->vm_arch.vm_seg[D].mem_len; if(pt_new(&vmp->vm_pt) != OK) - vm_panic("vm_init: no new pagetable", NO_NUM); + vm_panic("VM: no new pagetable", NO_NUM); #define BASICSTACK VM_PAGE_SIZE old_stacktop = CLICK2ABS(vmp->vm_arch.vm_seg[S].mem_vir + vmp->vm_arch.vm_seg[S].mem_len); @@ -314,17 +310,11 @@ PRIVATE void vm_init(void) } /* Set up table of calls. */ -#define CALLMAP(code, func, thecaller) { int i; \ +#define CALLMAP(code, func) { int i; \ if((i=CALLNUMBER(code)) < 0) { vm_panic(#code " invalid", (code)); } \ - if(i >= VM_NCALLS) { vm_panic(#code " invalid", (code)); } \ + if(i >= NR_VM_CALLS) { vm_panic(#code " invalid", (code)); } \ vm_calls[i].vmc_func = (func); \ vm_calls[i].vmc_name = #code; \ - if(((thecaller) < MINEPM || (thecaller) > MAXEPM) \ - && (thecaller) != ANYEPM \ - && (thecaller) != NEEDACL ) { \ - vm_panic(#thecaller " invalid", (code)); \ - } \ - vm_calls[i].vmc_callers |= EPM(thecaller); \ } /* Set call table to 0. This invalidates all calls (clear @@ -332,35 +322,35 @@ PRIVATE void vm_init(void) */ memset(vm_calls, 0, sizeof(vm_calls)); - /* Requests from PM (restricted to be from PM only). */ - CALLMAP(VM_EXIT, do_exit, PM_PROC_NR); - CALLMAP(VM_FORK, do_fork, PM_PROC_NR); - CALLMAP(VM_BRK, do_brk, PM_PROC_NR); - CALLMAP(VM_EXEC_NEWMEM, do_exec_newmem, PM_PROC_NR); - CALLMAP(VM_PUSH_SIG, do_push_sig, PM_PROC_NR); - CALLMAP(VM_WILLEXIT, do_willexit, PM_PROC_NR); - CALLMAP(VM_ADDDMA, do_adddma, PM_PROC_NR); - CALLMAP(VM_DELDMA, do_deldma, PM_PROC_NR); - CALLMAP(VM_GETDMA, do_getdma, PM_PROC_NR); - CALLMAP(VM_NOTIFY_SIG, do_notify_sig, PM_PROC_NR); + /* Basic VM calls. */ + CALLMAP(VM_MMAP, do_mmap); + CALLMAP(VM_MUNMAP, do_munmap); + CALLMAP(VM_MUNMAP_TEXT, do_munmap); + CALLMAP(VM_MAP_PHYS, do_map_phys); + CALLMAP(VM_UNMAP_PHYS, do_unmap_phys); - /* Requests from RS */ - CALLMAP(VM_RS_SET_PRIV, do_rs_set_priv, RS_PROC_NR); + /* Calls from PM. */ + CALLMAP(VM_EXIT, do_exit); + CALLMAP(VM_FORK, do_fork); + CALLMAP(VM_BRK, do_brk); + CALLMAP(VM_EXEC_NEWMEM, do_exec_newmem); + CALLMAP(VM_PUSH_SIG, do_push_sig); + CALLMAP(VM_WILLEXIT, do_willexit); + CALLMAP(VM_ADDDMA, do_adddma); + CALLMAP(VM_DELDMA, do_deldma); + CALLMAP(VM_GETDMA, do_getdma); + CALLMAP(VM_NOTIFY_SIG, do_notify_sig); - /* Requests from userland (source unrestricted). */ - CALLMAP(VM_MMAP, do_mmap, ANYEPM); - CALLMAP(VM_MUNMAP, do_munmap, ANYEPM); - CALLMAP(VM_MUNMAP_TEXT, do_munmap, ANYEPM); - CALLMAP(VM_MAP_PHYS, do_map_phys, ANYEPM); /* Does its own checking. */ - CALLMAP(VM_UNMAP_PHYS, do_unmap_phys, ANYEPM); + /* Calls from RS */ + CALLMAP(VM_RS_SET_PRIV, do_rs_set_priv); - /* Requests from userland (anyone can call but need an ACL bit). */ - CALLMAP(VM_REMAP, do_remap, NEEDACL); - CALLMAP(VM_GETPHYS, do_get_phys, NEEDACL); - CALLMAP(VM_SHM_UNMAP, do_shared_unmap, NEEDACL); - CALLMAP(VM_GETREF, do_get_refcount, NEEDACL); - CALLMAP(VM_CTL, do_ctl, NEEDACL); - CALLMAP(VM_QUERY_EXIT, do_query_exit, NEEDACL); + /* Generic calls. */ + CALLMAP(VM_REMAP, do_remap); + CALLMAP(VM_GETPHYS, do_get_phys); + CALLMAP(VM_SHM_UNMAP, do_shared_unmap); + CALLMAP(VM_GETREF, do_get_refcount); + CALLMAP(VM_CTL, do_ctl); + CALLMAP(VM_QUERY_EXIT, do_query_exit); /* Sanity checks */ if(find_kernel_top() >= VM_PROCSTART) @@ -372,6 +362,41 @@ PRIVATE void vm_init(void) /* Unmap our own low pages. */ unmap_ok = 1; _minix_unmapzero(); + + /* Map all the services in the boot image. */ + if((s = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0, + (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK) { + panic("VM", "sys_safecopyfrom failed", s); + } + for(i=0;i < NR_BOOT_PROCS;i++) { + if(rprocpub[i].in_use) { + if((s = map_service(&rprocpub[i])) != OK) { + vm_panic("unable to map service", s); + } + } + } + + return(OK); +} + +/*===========================================================================* + * map_service * + *===========================================================================*/ +PRIVATE int map_service(rpub) +struct rprocpub *rpub; +{ +/* Map a new service by initializing its call mask. */ + int r, proc_nr; + + if ((r = vm_isokendpt(rpub->endpoint, &proc_nr)) != OK) { + return r; + } + + /* Copy the call mask. */ + memcpy(&vmproc[proc_nr].vm_call_mask, &rpub->vm_call_mask, + sizeof(vmproc[proc_nr].vm_call_mask)); + + return(OK); } /*===========================================================================* @@ -381,23 +406,14 @@ PRIVATE int vm_acl_ok(endpoint_t caller, int call) { int n, r; - /* Some calls are always allowed by some, or all, processes. */ - if(EPMOK(vm_calls[call].vmc_callers, caller)) { - return OK; - } - if ((r = vm_isokendpt(caller, &n)) != OK) vm_panic("VM: from strange source.", caller); - /* Other calls need an ACL bit. */ - if (!(vm_calls[call].vmc_callers & EPM(NEEDACL))) { - return EPERM; - } - if (!GET_BIT(vmproc[n].vm_call_priv_mask, call)) { - printf("VM: no ACL for %s for %d\n", - vm_calls[call].vmc_name, caller); + /* See if the call is allowed. */ + if (!GET_BIT(vmproc[n].vm_call_mask, call)) { return EPERM; } return OK; } + diff --git a/servers/vm/rs.c b/servers/vm/rs.c index 5c1a74538..1eb194f61 100644 --- a/servers/vm/rs.c +++ b/servers/vm/rs.c @@ -46,8 +46,8 @@ PUBLIC int do_rs_set_priv(message *m) if (m->VM_RS_BUF) { r = sys_datacopy(m->m_source, (vir_bytes) m->VM_RS_BUF, - SELF, (vir_bytes) vmp->vm_call_priv_mask, - sizeof(vmp->vm_call_priv_mask)); + SELF, (vir_bytes) vmp->vm_call_mask, + sizeof(vmp->vm_call_mask)); if (r != OK) return r; } diff --git a/servers/vm/vmproc.h b/servers/vm/vmproc.h index 47beedaa7..dc840956b 100644 --- a/servers/vm/vmproc.h +++ b/servers/vm/vmproc.h @@ -32,8 +32,7 @@ struct vmproc { /* Heap for brk() to extend. */ struct vir_region *vm_heap; -#define VM_CALL_PRIV_MASK_SIZE BITMAP_CHUNKS(VM_NCALLS) - bitchunk_t vm_call_priv_mask[VM_CALL_PRIV_MASK_SIZE]; + bitchunk_t vm_call_mask[VM_CALL_MASK_SIZE]; /* State for requests pending to be done to vfs on behalf of * this process.