From d1fd04e72a1406e3961828207e17b6121f69df1d Mon Sep 17 00:00:00 2001 From: Cristiano Giuffrida Date: Fri, 8 Jan 2010 01:20:42 +0000 Subject: [PATCH] Initialization protocol for system services. SYSLIB CHANGES: - SEF framework now supports a new SEF Init request type from RS. 3 different callbacks are available (init_fresh, init_lu, init_restart) to specify initialization code when a service starts fresh, starts after a live update, or restarts. SYSTEM SERVICE CHANGES: - Initialization code for system services is now enclosed in a callback SEF will automatically call at init time. The return code of the callback will tell RS whether the initialization completed successfully. - Each init callback can access information passed by RS to initialize. As of now, each system service has access to the public entries of RS's system process table to gather all the information required to initialize. This design eliminates many existing or potential races at boot time and provides a uniform initialization interface to system services. The same interface will be reused for the upcoming publish/subscribe model to handle dynamic registration / deregistration of system services. VM CHANGES: - Uniform privilege management for all system services. Every service uses the same call mask format. For boot services, VM copies the call mask from init data. For dynamic services, VM still receives the call mask via rs_set_priv call that will be soon replaced by the upcoming publish/subscribe model. RS CHANGES: - The system process table has been reorganized and split into private entries and public entries. Only the latter ones are exposed to system services. - VM call masks are now entirely configured in rs/table.c - RS has now its own slot in the system process table. Only kernel tasks and user processes not included in the boot image are now left out from the system process table. - RS implements the initialization protocol for system services. - For services in the boot image, RS blocks till initialization is complete and panics when failure is reported back. Services are initialized in their order of appearance in the boot image priv table and RS blocks to implements synchronous initialization for every system service having the flag SF_SYNCH_BOOT set. - For services started dynamically, the initialization protocol is implemented as though it were the first ping for the service. In this case, if the system service fails to report back (or reports failure), RS brings the service down rather than trying to restart it. --- drivers/amddev/amddev.c | 21 +- drivers/at_wini/at_wini.c | 56 ++-- drivers/atl2/atl2.c | 61 ++-- drivers/audio/framework/audio_fw.c | 17 +- drivers/bios_wini/bios_wini.c | 30 +- drivers/dp8390/dp8390.c | 76 +++-- drivers/dpeth/dp.c | 68 ++-- drivers/e1000/e1000.c | 78 +++-- drivers/filter/main.c | 71 ++-- drivers/floppy/floppy.c | 56 ++-- drivers/floppy/floppy.h | 2 +- drivers/fxp/fxp.c | 84 +++-- drivers/lance/lance.c | 71 ++-- drivers/log/log.c | 46 ++- drivers/memory/memory.c | 114 ++++--- drivers/orinoco/orinoco.c | 64 ++-- drivers/pci/main.c | 41 ++- drivers/pci/pci.c | 100 ++++-- drivers/pci/pci.h | 14 +- drivers/printer/printer.c | 31 +- drivers/random/main.c | 77 +++-- drivers/readclock/readclock.c | 2 + drivers/rtl8139/rtl8139.c | 89 +++-- drivers/rtl8169/rtl8169.c | 77 +++-- drivers/sb16/sb16_dsp.c | 68 ++-- drivers/sb16/sb16_mixer.c | 2 +- drivers/ti1225/ti1225.c | 60 ++-- drivers/tty/tty.c | 40 ++- include/minix/com.h | 13 +- include/minix/config.h | 1 + include/minix/rs.h | 65 ++-- include/minix/sef.h | 55 ++++ include/unistd.h | 1 + kernel/const.h | 1 - kernel/main.c | 2 +- kernel/priv.h | 3 +- kernel/system/do_privctl.c | 4 +- kernel/system/do_safecopy.c | 9 +- lib/syslib/Makefile.in | 1 + lib/syslib/safecopies.c | 23 +- lib/syslib/sef.c | 28 ++ lib/syslib/sef_init.c | 137 ++++++++ lib/sysutil/env_get_prm.c | 18 +- servers/ds/inc.h | 1 + servers/ds/main.c | 22 +- servers/ds/proto.h | 4 +- servers/ds/store.c | 46 ++- servers/inet/inet.c | 184 ++++++----- servers/ipc/main.c | 26 +- servers/is/dmp_rs.c | 18 +- servers/is/main.c | 19 +- servers/iso9660fs/main.c | 31 +- servers/mfs/main.c | 32 +- servers/mfs/mount.c | 2 +- servers/pfs/main.c | 17 +- servers/pm/main.c | 106 +++--- servers/rs/const.h | 20 +- servers/rs/glo.h | 6 + servers/rs/main.c | 512 +++++++++++++++-------------- servers/rs/manager.c | 453 +++++++++++++++---------- servers/rs/proto.h | 4 + servers/rs/service.c | 22 +- servers/rs/table.c | 76 +++-- servers/rs/type.h | 31 +- servers/rs/utility.c | 73 +++- servers/vfs/main.c | 186 ++++++----- servers/vm/fork.c | 3 +- servers/vm/main.c | 174 +++++----- servers/vm/rs.c | 4 +- servers/vm/vmproc.h | 3 +- 70 files changed, 2460 insertions(+), 1492 deletions(-) create mode 100644 lib/syslib/sef_init.c 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,29 +227,13 @@ 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(); - /* Install signal handlers. Ask PM to transform signal into message. */ - system_hz = sys_hz(); - - init_buffer(); - - w_identify_wakeup_ticks = WAKEUP_TICKS; - wakeup_ticks = WAKEUP_TICKS; - - sa.sa_handler = SIG_MESS; - sigemptyset(&sa.sa_mask); - 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); - init_params(); - signal(SIGTERM, SIG_IGN); + /* Call the generic receive loop. */ driver_task(&w_dtab, DRIVER_STD); + return(OK); } @@ -257,6 +242,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); sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid); @@ -266,6 +256,34 @@ 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 at_wini driver. */ + struct sigaction sa; + + /* Install signal handlers. Ask PM to transform signal into message. */ + system_hz = sys_hz(); + + init_buffer(); + + w_identify_wakeup_ticks = WAKEUP_TICKS; + wakeup_ticks = WAKEUP_TICKS; + + sa.sa_handler = SIG_MESS; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGTERM,&sa,NULL)<0) panic("AT","sigaction failed", errno); + + /* Set special disk parameters. */ + init_params(); + signal(SIGTERM, SIG_IGN); + + return(OK); +} + /*===========================================================================* * 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. */ - sef_local_startup(); - - system_hz = sys_hz(); - - (progname = strrchr(argv[0], '/')) ? progname++ : (progname = argv[0]); - env_setargs(argc, argv); + sef_local_startup(); - 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 * - *===========================================================================*/ -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 * + * sef_cb_init_fresh * *===========================================================================*/ -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,186 +143,25 @@ 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(); } /*===========================================================================* - * exec_image_copy * - *===========================================================================*/ -PRIVATE void exec_image_copy(boot_proc_idx, ip, rp) -int boot_proc_idx; -struct boot_image *ip; -struct rproc *rp; -{ -/* Copy the executable image of the given boot process. */ - int s; - struct exec header; - static char *boot_image_ptr = NULL; - - if(boot_image_ptr == NULL) { - boot_image_ptr = boot_image_buffer; - } - s = NO_NUM; - - /* Get a.out header. */ - if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < sizeof(header) - || (s = sys_getaoutheader(&header, boot_proc_idx)) != OK) { - panic("RS", "unable to get copy of a.out header", s); - } - memcpy(boot_image_ptr, &header, header.a_hdrlen); - boot_image_ptr += header.a_hdrlen; - - /* Get text segment. */ - if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < header.a_text - || (s = rs_startup_segcopy(ip->endpoint, T, D, (vir_bytes) boot_image_ptr, - header.a_text)) != OK) { - panic("RS", "unable to get copy of text segment", s); - } - boot_image_ptr += header.a_text; - - /* Get data segment. */ - if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < header.a_data - || (s = rs_startup_segcopy(ip->endpoint, D, D, (vir_bytes) boot_image_ptr, - header.a_data)) != OK) { - panic("RS", "unable to get copy of data segment", s); - } - boot_image_ptr += header.a_data; - - /* Set the executable image for the given boot process. */ - rp->r_exec_len = header.a_hdrlen + header.a_text + header.a_data; - rp->r_exec = boot_image_ptr - rp->r_exec_len; -} - -/*===========================================================================* - * boot_image_info_lookup * - *===========================================================================*/ -PRIVATE void boot_image_info_lookup(endpoint, image, ip, pp, sp, dp) -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; -{ -/* Lookup entries in boot image tables. */ - int i; - - /* When requested, locate the corresponding entry in the boot image table - * or panic if not found. - */ - if(ip) { - for (i=0; i < NR_BOOT_PROCS; i++) { - if(image[i].endpoint == endpoint) { - *ip = &image[i]; - break; - } - } - if(i == NR_BOOT_PROCS) { - panic("RS", "boot image table lookup failed", NO_NUM); - } - } - - /* When requested, locate the corresponding entry in the boot image priv table - * or panic if not found. - */ - if(pp) { - for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { - if(boot_image_priv_table[i].endpoint == endpoint) { - *pp = &boot_image_priv_table[i]; - break; - } - } - if(i == NULL_BOOT_NR) { - panic("RS", "boot image priv table lookup failed", NO_NUM); - } - } - - /* When requested, locate the corresponding entry in the boot image sys table - * or resort to the default entry if not found. - */ - if(sp) { - for (i=0; boot_image_sys_table[i].endpoint != DEFAULT_BOOT_NR; i++) { - if(boot_image_sys_table[i].endpoint == endpoint) { - *sp = &boot_image_sys_table[i]; - break; - } - } - if(boot_image_sys_table[i].endpoint == DEFAULT_BOOT_NR) { - *sp = &boot_image_sys_table[i]; /* accept the default entry */ - } - } - - /* When requested, locate the corresponding entry in the boot image dev table - * or resort to the default entry if not found. - */ - if(dp) { - for (i=0; boot_image_dev_table[i].endpoint != DEFAULT_BOOT_NR; i++) { - if(boot_image_dev_table[i].endpoint == endpoint) { - *dp = &boot_image_dev_table[i]; - break; - } - } - if(boot_image_dev_table[i].endpoint == DEFAULT_BOOT_NR) { - *dp = &boot_image_dev_table[i]; /* accept the default entry */ - } - } -} - -/*===========================================================================* - * fill_call_mask * + * sef_cb_init_fresh * *===========================================================================*/ -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 */ -{ -/* 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) +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; + 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; @@ -354,6 +172,13 @@ PRIVATE void init_server(void) /* 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; @@ -371,7 +196,7 @@ PRIVATE void init_server(void) ip = &image[i]; /* System services only. */ - if(!isbootsrvprocn(_ENDPOINT_P(ip->endpoint))) { + if(iskerneln(_ENDPOINT_P(ip->endpoint))) { continue; } nr_image_srvs++; @@ -400,7 +225,7 @@ PRIVATE void init_server(void) boot_image_priv = &boot_image_priv_table[i]; /* System services only. */ - if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) { + if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { continue; } nr_image_priv_srvs++; @@ -418,7 +243,14 @@ PRIVATE void init_server(void) } } - /* Initialize the system process table in 3 steps, each of them following + /* 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. @@ -429,7 +261,7 @@ PRIVATE void init_server(void) boot_image_priv = &boot_image_priv_table[i]; /* System services only. */ - if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) { + if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { continue; } @@ -437,6 +269,7 @@ PRIVATE void init_server(void) 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. @@ -449,30 +282,30 @@ PRIVATE void init_server(void) /* * 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); + 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. */ @@ -483,17 +316,17 @@ PRIVATE void init_server(void) /* * Set sys properties. */ - rp->r_sys_flags = boot_image_sys->flags; /* sys flags */ + rpub->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 */ + 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(rp->r_proc_name, ip->proc_name); + strcpy(rpub->proc_name, ip->proc_name); /* Get command settings. */ rp->r_cmd[0]= '\0'; @@ -502,9 +335,13 @@ PRIVATE void init_server(void) 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; - rp->r_proc_nr_e = ip->endpoint; + rpub->endpoint = ip->endpoint; /* Set some defaults. */ rp->r_uid = 0; /* root */ @@ -516,30 +353,62 @@ PRIVATE void init_server(void) /* Mark as in use. */ rp->r_flags = RS_IN_USE; - rproc_ptr[_ENDPOINT_P(rp->r_proc_nr_e)]= rp; + 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(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) { + if(iskerneln(_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); + /* 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(ip->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) { + 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 3: all the system services in the boot image are now running. + /* - 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. */ @@ -550,17 +419,18 @@ PRIVATE void init_server(void) boot_image_priv = &boot_image_priv_table[i]; /* System services only. */ - if(!isbootsrvprocn(_ENDPOINT_P(boot_image_priv->endpoint))) { + 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 == rp->r_proc_nr_e) { + if (mproc[j].mp_endpoint == rpub->endpoint) { rp->r_pid = mproc[j].mp_pid; break; } @@ -568,15 +438,6 @@ PRIVATE void init_server(void) 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); - } } /* @@ -631,6 +492,163 @@ PRIVATE void init_server(void) */ unmap_ok = 1; _minix_unmapzero(); + + return(OK); +} + +/*===========================================================================* + * exec_image_copy * + *===========================================================================*/ +PRIVATE void exec_image_copy(boot_proc_idx, ip, rp) +int boot_proc_idx; +struct boot_image *ip; +struct rproc *rp; +{ +/* Copy the executable image of the given boot process. */ + int s; + struct exec header; + static char *boot_image_ptr = NULL; + + if(boot_image_ptr == NULL) { + boot_image_ptr = boot_image_buffer; + } + s = NO_NUM; + + /* Get a.out header. */ + if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < sizeof(header) + || (s = sys_getaoutheader(&header, boot_proc_idx)) != OK) { + panic("RS", "unable to get copy of a.out header", s); + } + memcpy(boot_image_ptr, &header, header.a_hdrlen); + boot_image_ptr += header.a_hdrlen; + + /* Get text segment. */ + if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < header.a_text + || (s = rs_startup_segcopy(ip->endpoint, T, D, (vir_bytes) boot_image_ptr, + header.a_text)) != OK) { + panic("RS", "unable to get copy of text segment", s); + } + boot_image_ptr += header.a_text; + + /* Get data segment. */ + if(boot_image_buffer+boot_image_buffer_size - boot_image_ptr < header.a_data + || (s = rs_startup_segcopy(ip->endpoint, D, D, (vir_bytes) boot_image_ptr, + header.a_data)) != OK) { + panic("RS", "unable to get copy of data segment", s); + } + boot_image_ptr += header.a_data; + + /* Set the executable image for the given boot process. */ + rp->r_exec_len = header.a_hdrlen + header.a_text + header.a_data; + rp->r_exec = boot_image_ptr - rp->r_exec_len; +} + +/*===========================================================================* + * boot_image_info_lookup * + *===========================================================================*/ +PRIVATE void boot_image_info_lookup(endpoint, image, ip, pp, sp, dp) +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; +{ +/* Lookup entries in boot image tables. */ + int i; + + /* When requested, locate the corresponding entry in the boot image table + * or panic if not found. + */ + if(ip) { + for (i=0; i < NR_BOOT_PROCS; i++) { + if(image[i].endpoint == endpoint) { + *ip = &image[i]; + break; + } + } + if(i == NR_BOOT_PROCS) { + panic("RS", "boot image table lookup failed", NO_NUM); + } + } + + /* When requested, locate the corresponding entry in the boot image priv table + * or panic if not found. + */ + if(pp) { + for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { + if(boot_image_priv_table[i].endpoint == endpoint) { + *pp = &boot_image_priv_table[i]; + break; + } + } + if(i == NULL_BOOT_NR) { + panic("RS", "boot image priv table lookup failed", NO_NUM); + } + } + + /* When requested, locate the corresponding entry in the boot image sys table + * or resort to the default entry if not found. + */ + if(sp) { + for (i=0; boot_image_sys_table[i].endpoint != DEFAULT_BOOT_NR; i++) { + if(boot_image_sys_table[i].endpoint == endpoint) { + *sp = &boot_image_sys_table[i]; + break; + } + } + if(boot_image_sys_table[i].endpoint == DEFAULT_BOOT_NR) { + *sp = &boot_image_sys_table[i]; /* accept the default entry */ + } + } + + /* When requested, locate the corresponding entry in the boot image dev table + * or resort to the default entry if not found. + */ + if(dp) { + for (i=0; boot_image_dev_table[i].endpoint != DEFAULT_BOOT_NR; i++) { + if(boot_image_dev_table[i].endpoint == endpoint) { + *dp = &boot_image_dev_table[i]; + break; + } + } + if(boot_image_dev_table[i].endpoint == DEFAULT_BOOT_NR) { + *dp = &boot_image_dev_table[i]; /* accept the default entry */ + } + } +} + +/*===========================================================================* + * catch_boot_init_ready * + *===========================================================================*/ +PRIVATE void catch_boot_init_ready(endpoint) +endpoint_t endpoint; +{ +/* Block and catch an init ready message from the given source. */ + int r; + message m; + struct rproc *rp; + int result; + + /* 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)]; + + /* Check result. */ + if(result != OK) { + panic("RS", "unable to complete init for service", m.m_source); + } + + /* 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); - - /* Requests from RS */ - CALLMAP(VM_RS_SET_PRIV, do_rs_set_priv, RS_PROC_NR); - - /* 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); - - /* 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); + /* 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); + + /* 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); + + /* Calls from RS */ + CALLMAP(VM_RS_SET_PRIV, do_rs_set_priv); + + /* 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. -- 2.44.0