/*===========================================================================* * chardriver_announce * *===========================================================================*/ void chardriver_announce(void) { /* Announce we are up after a fresh start or restart. */ int r; char key[DS_MAX_KEYLEN]; char label[DS_MAX_KEYLEN]; char *driver_prefix = "drv.chr."; /* Callers are allowed to use sendrec to communicate with drivers. * For this reason, there may blocked callers when a driver restarts. * Ask the kernel to unblock them (if any). */ #if USE_STATECTL if ((r = sys_statectl(SYS_STATE_CLEAR_IPC_REFS)) != OK) panic("chardriver_init: sys_statectl failed: %d", r); #endif /* Publish a driver up event. */ if ((r = ds_retrieve_label_name(label, getprocnr())) != OK) panic("chardriver_init: unable to get own label: %d", r); snprintf(key, DS_MAX_KEYLEN, "%s%s", driver_prefix, label); if ((r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE)) != OK) panic("chardriver_init: unable to publish driver up event: %d", r); /* Expect a DEV_OPEN for any device before serving regular driver requests. */ clear_open_devs(); }
/*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the Minix file server. */ int i; /* Defaults */ opt.use_orlov = TRUE; opt.mfsalloc = FALSE; opt.use_reserved_blocks = FALSE; opt.block_with_super = 0; opt.use_prealloc = FALSE; /* If we have been given an options string, parse options from there. */ for (i = 1; i < env_argc - 1; i++) if (!strcmp(env_argv[i], "-o")) optset_parse(optset_table, env_argv[++i]); may_use_vmcache = 1; /* Init inode table */ for (i = 0; i < NR_INODES; ++i) { inode[i].i_count = 0; cch[i] = 0; } init_inode_cache(); SELF_E = getprocnr(); /* just a small number before we find out the block size at mount time */ buf_pool(10); fs_block_size = _MIN_BLOCK_SIZE; return(OK); }
/*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ static int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the pipe file server. */ int i; struct passwd *pw; /* Initialize main loop parameters. */ exitsignaled = 0; /* No exit request seen yet. */ busy = 0; /* Server is not 'busy' (i.e., inodes in use). */ /* Init inode table */ for (i = 0; i < PFS_NR_INODES; ++i) { inode[i].i_count = 0; } init_inode_cache(); uds_init(); buf_pool(); /* Drop root privileges */ if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) { printf("PFS: unable to retrieve uid of SERVICE_LOGIN, " "still running as root"); } else if (setuid(pw->pw_uid) != 0) { panic("unable to drop privileges"); } SELF_E = getprocnr(); return(OK); }
/*===========================================================================* * blockdriver_announce * *===========================================================================*/ void blockdriver_announce(int type) { /* Announce we are up after a fresh start or a restart. */ int r; char key[DS_MAX_KEYLEN]; char label[DS_MAX_KEYLEN]; char *driver_prefix = "drv.blk."; /* Callers are allowed to use sendrec to communicate with drivers. * For this reason, there may blocked callers when a driver restarts. * Ask the kernel to unblock them (if any). Note that most block drivers * will not restart statefully, and thus will skip this code. */ if (type == SEF_INIT_RESTART) { #if USE_STATECTL if ((r = sys_statectl(SYS_STATE_CLEAR_IPC_REFS)) != OK) panic("blockdriver_init: sys_statectl failed: %d", r); #endif } /* Publish a driver up event. */ if ((r = ds_retrieve_label_name(label, getprocnr())) != OK) panic("blockdriver_init: unable to get own label: %d", r); snprintf(key, DS_MAX_KEYLEN, "%s%s", driver_prefix, label); if ((r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE)) != OK) panic("blockdriver_init: unable to publish driver up event: %d", r); /* Expect an open for any device before serving regular driver requests. */ clear_open_devs(); /* Initialize or reset the message queue. */ mq_init(); }
/***************************************************************************** * hermes_struct_init * * * * Initialize the hermes structure fields * *****************************************************************************/ void hermes_struct_init (hermes_t * hw, u32_t address, int io_space, int reg_spacing) { hw->iobase = address; hw->io_space = io_space; hw->reg_spacing = reg_spacing; hw->inten = 0x0; this_proc = getprocnr(); }
PUBLIC int sys_p2_get_stat(vm_p2_stats *out){ message m; CHECKEUID; m.VM_P2_ENDPT = getprocnr(); m.VM_P2_OP = VM_P2_GET_STAT; m.VM_P2_BUF = (char*)out; /*fprintf(stdout,"sys_p2_get_stat() %d\n",m.VM_P2_ENDPT);*/ return(_syscall(VM_PROC_NR, VM_P2, &m)); }
/*===========================================================================* * 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); }
/*===========================================================================* * test_label * *===========================================================================*/ void test_label(void) { int r; char label[DS_MAX_KEYLEN]; endpoint_t endpoint; /* Retrieve own label and endpoint. */ r = ds_retrieve_label_name(label, getprocnr()); assert(r == OK); r = ds_retrieve_label_endpt(label, &endpoint); assert(r == OK && endpoint == getprocnr()); /* Publish and delete. */ r = ds_publish_label(label, endpoint, 0); assert(r == EPERM); r = ds_delete_label(label); assert(r == EPERM); printf("DSTEST: LABEL test successful!\n"); }
/*===========================================================================* * init_server * *===========================================================================*/ PRIVATE void init_server(void) { int i; /* Init driver mapping */ for (i = 0; i < NR_DEVICES; ++i) driver_endpoints[i].driver_e = NONE; /* SELF_E will contain the id of this process */ SELF_E = getprocnr(); /* hash_init(); */ /* Init the table with the ids */ setenv("TZ","",1); /* Used to calculate the time */ }
/*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the iso9660fs server. */ int i; /* Init driver mapping */ for (i = 0; i < NR_DEVICES; ++i) driver_endpoints[i].driver_e = NONE; /* SELF_E will contain the id of this process */ SELF_E = getprocnr(); /* hash_init(); */ /* Init the table with the ids */ setenv("TZ","",1); /* Used to calculate the time */ return(OK); }
/*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the Minix file server. */ int i, r; /* Defaults */ opt.use_orlov = TRUE; opt.mfsalloc = FALSE; opt.use_reserved_blocks = FALSE; opt.block_with_super = 0; opt.use_prealloc = FALSE; /* If we have been given an options string, parse options from there. */ for (i = 1; i < env_argc - 1; i++) if (!strcmp(env_argv[i], "-o")) optset_parse(optset_table, env_argv[++i]); may_use_vmcache = 1; /* Init inode table */ for (i = 0; i < NR_INODES; ++i) { inode[i].i_count = 0; cch[i] = 0; } init_inode_cache(); /* Init driver mapping */ for (i = 0; i < NR_DEVICES; ++i) driver_endpoints[i].driver_e = NONE; SELF_E = getprocnr(); buf_pool(DEFAULT_NR_BUFS); fs_block_size = _MIN_BLOCK_SIZE; fs_m_in.m_type = FS_READY; if ((r = send(VFS_PROC_NR, &fs_m_in)) != OK) { panic("Error sending login to VFS: %d", r); } return(OK); }
/*===========================================================================* * init_server * *===========================================================================*/ PRIVATE void init_server(void) { int i; /* Init inode table */ for (i = 0; i < NR_INODES; ++i) { inode[i].i_count = 0; cch[i] = 0; } init_inode_cache(); /* Init driver mapping */ for (i = 0; i < NR_DEVICES; ++i) driver_endpoints[i].driver_e = NONE; SELF_E = getprocnr(); buf_pool(); fs_block_size = _MIN_BLOCK_SIZE; }
/*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the iso9660fs server. */ int i, r; /* Init driver mapping */ for (i = 0; i < NR_DEVICES; ++i) driver_endpoints[i].driver_e = NONE; /* SELF_E will contain the id of this process */ 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); }
/*===========================================================================* * netdriver_announce * *===========================================================================*/ PUBLIC void netdriver_announce() { /* Announce we are up after a fresh start or restart. */ int r; char key[DS_MAX_KEYLEN]; char label[DS_MAX_KEYLEN]; char *driver_prefix = "drv.net."; /* Publish a driver up event. */ r = ds_retrieve_label_name(label, getprocnr()); if (r != OK) { panic("driver_announce: unable to get own label: %d\n", r); } snprintf(key, DS_MAX_KEYLEN, "%s%s", driver_prefix, label); r = ds_publish_u32(key, DS_DRIVER_UP, DSF_OVERWRITE); if (r != OK) { panic("driver_announce: unable to publish driver up event: %d\n", r); } conf_expected = TRUE; }
/*===========================================================================* * main * *===========================================================================*/ int main(int argc, char **argv) { endpoint_t ep_self, ep_requestor, ep_child; cp_grant_id_t gid; int i, r, pid; char *buf; int status; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); /* Prepare work. */ buf = (char*) CLICK_CEIL(buf_buf); fid_send = open(FIFO_GRANTOR, O_WRONLY); fid_get = open(FIFO_REQUESTOR, O_RDONLY); if(fid_get < 0 || fid_send < 0) { printf("GRANTOR: can't open fifo files.\n"); return 1; } /* Get the requestor's endpoint. */ read(fid_get, &ep_requestor, sizeof(ep_requestor)); dprint("GRANTOR: getting requestor's endpoint: %d\n", ep_requestor); /* Grant. */ gid = cpf_grant_direct(ep_requestor, (long)buf, BUF_SIZE, CPF_READ | CPF_WRITE | CPF_MAP); ep_self = getprocnr(); dprint("GRANTOR: sending my endpoint %d and gid %d\n", ep_self, gid); write(fid_send, &ep_self, sizeof(ep_self)); write(fid_send, &gid, sizeof(gid)); /* Test safemap. */ buf[0] = 0; FIFO_NOTIFY(fid_send); FIFO_WAIT(fid_get); return 0; }
/*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the pipe file server. */ int i; /* Initialize main loop parameters. */ exitsignaled = 0; /* No exit request seen yet. */ busy = 0; /* Server is not 'busy' (i.e., inodes in use). */ /* Init inode table */ for (i = 0; i < NR_INODES; ++i) { inode[i].i_count = 0; } init_inode_cache(); uds_init(); SELF_E = getprocnr(); buf_pool(); driver_announce(); return(OK); }
/*===========================================================================* * main * *===========================================================================*/ int main(int argc, char **argv) { endpoint_t ep_self, ep_child; size_t size = BUF_SIZE; int i, r, pid; int status; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); /* Prepare work. */ buf = (char*) CLICK_CEIL(buf_buf); fid_get = open(FIFO_GRANTOR, O_RDONLY); fid_send = open(FIFO_REQUESTOR, O_WRONLY); if(fid_get < 0 || fid_send < 0) { printf("REQUESTOR: can't open fifo files.\n"); return 1; } /* Send the endpoint to the granter, in order to let him to * create the grant. */ ep_self = getprocnr(); write(fid_send, &ep_self, sizeof(ep_self)); dprint("REQUESTOR: sending my endpoint: %d\n", ep_self); /* Get the granter's endpoint and gid. */ read(fid_get, &ep_granter, sizeof(ep_granter)); read(fid_get, &gid, sizeof(gid)); dprint("REQUESTOR: getting granter's endpoint %d and gid %d\n", ep_granter, gid); /* Test MAP. */ FIFO_WAIT(fid_get); r = sys_safemap(ep_granter, gid, 0, (long)buf, size, 1); if(r != OK) { printf("REQUESTOR: error in sys_safemap: %d\n", r); return 1; } CHECK_TEST("REQUESTOR", buf[0], BUF_START_GRANTOR, "MAP"); buf[0] = BUF_START_REQUESTOR; r = sys_safeunmap((long)buf); if(r != OK) { printf("REQUESTOR: error in sys_safeunmap: %d\n", r); return 1; } FIFO_NOTIFY(fid_send); /* Test UNMAP. */ FIFO_WAIT(fid_get); CHECK_TEST("REQUESTOR", buf[0], BUF_START_REQUESTOR, "UNMAP"); r = sys_safemap(ep_granter, gid, 0, (long)buf, size, 1); if(r != 0) { printf("REQUESTOR: error in sys_safemap: %d\n", r); return 1; } FIFO_NOTIFY(fid_send); /* Test REVOKE. */ FIFO_WAIT(fid_get); CHECK_TEST("REQUESTOR", buf[0], BUF_START_GRANTOR, "REVOKE"); buf[0] = BUF_START_REQUESTOR; FIFO_NOTIFY(fid_send); /* Test SMAP_COW. */ FIFO_WAIT(fid_get); r = sys_safemap(ep_granter, gid, 0, (long)buf, size, 1); if(r != OK) { printf("REQUESTOR: error in sys_safemap: %d\n", r); return 1; } buf[0] = BUF_START_REQUESTOR; pid = fork(); if(pid < 0) { printf("REQUESTOR: error in fork\n"); return 1; } if(pid == 0) { exit(buf[0] != BUF_START_REQUESTOR); } FIFO_NOTIFY(fid_send); FIFO_WAIT(fid_get); ep_child = getnprocnr(pid); if ((r = sys_privctl(ep_child, SYS_PRIV_SET_USER, NULL)) != OK) { printf("REQUESTOR: unable to set privileges: %d\n", r); return 1; } if ((r = sys_privctl(ep_child, SYS_PRIV_ALLOW, NULL)) != OK) { printf("REQUESTOR: child process can't run: %d\n", r); return 1; } wait(&status); FIFO_NOTIFY(fid_send); CHECK_TEST("REQUESTOR", buf[0], BUF_START_GRANTOR, "SMAP_COW"); CHECK_TEST("REQUESTOR", 1, WIFEXITED(status) && (WEXITSTATUS(status) == 0), "SMAP_COW child"); /* Test COW_SMAP. */ FIFO_WAIT(fid_get); buf[0] = BUF_START_REQUESTOR; r = sys_safemap(ep_granter, gid, 0, (long)buf, size, 1); if(r != OK) { printf("REQUESTOR: error in sys_safemap: %d\n", r); return 1; } FIFO_NOTIFY(fid_send); FIFO_WAIT(fid_get); CHECK_TEST("REQUESTOR", buf[0], BUF_START_GRANTOR+1, "COW_SMAP"); /* Test COW_SMAP2 (with COW safecopy). */ FIFO_WAIT(fid_get); buf[0] = BUF_START_REQUESTOR; r = sys_safecopyto(ep_granter, gid, 0, (long)buf, size); if(r != OK) { printf("REQUESTOR: error in sys_safecopyto: %d\n", r); return 1; } r = sys_safemap(ep_granter, gid, 0, (long)buf, size, 1); if(r != OK) { printf("REQUESTOR: error in sys_safemap: %d\n", r); return 1; } FIFO_NOTIFY(fid_send); CHECK_TEST("REQUESTOR", buf[0], BUF_START_REQUESTOR, "COW_SMAP2"); return 0; }
/*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) { /* Initialize the reincarnation server. */ struct boot_image *ip; int s,i; int nr_image_srvs, nr_image_priv_srvs, nr_uncaught_init_srvs; struct rproc *rp; struct rproc *replica_rp; struct rprocpub *rpub; struct boot_image image[NR_BOOT_PROCS]; struct boot_image_priv *boot_image_priv; struct boot_image_sys *boot_image_sys; struct boot_image_dev *boot_image_dev; int pid, replica_pid; endpoint_t replica_endpoint; int ipc_to; int *calls; int all_c[] = { ALL_C, NULL_C }; int no_c[] = { NULL_C }; /* See if we run in verbose mode. */ env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1); if ((s = sys_getinfo(GET_HZ, &system_hz, sizeof(system_hz), 0, 0)) != OK) panic("Cannot get system timer frequency\n"); /* 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("unable to create rprocpub table grant: %d", rinit.rproctab_gid); } /* Initialize some global variables. */ RUPDATE_INIT(); shutting_down = FALSE; /* Get a copy of the boot image table. */ if ((s = sys_getimage(image)) != OK) { panic("unable to get copy of boot image table: %d", s); } /* Determine the number of system services in the boot image table. */ nr_image_srvs = 0; for(i=0;i<NR_BOOT_PROCS;i++) { ip = &image[i]; /* System services only. */ if(iskerneln(_ENDPOINT_P(ip->endpoint))) { continue; } nr_image_srvs++; } /* Determine the number of entries in the boot image priv table and make sure * it matches the number of system services in the boot image table. */ nr_image_priv_srvs = 0; for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { boot_image_priv = &boot_image_priv_table[i]; /* System services only. */ if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { continue; } nr_image_priv_srvs++; } if(nr_image_srvs != nr_image_priv_srvs) { panic("boot image table and boot image priv table mismatch"); } /* Reset the system process table. */ for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) { rp->r_flags = 0; rp->r_init_err = ERESTART; rp->r_pub = &rprocpub[rp - rproc]; rp->r_pub->in_use = FALSE; rp->r_pub->old_endpoint = NONE; rp->r_pub->new_endpoint = NONE; } /* 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: set priviliges, sys properties, and dev properties (if any) * for every system service. */ for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { boot_image_priv = &boot_image_priv_table[i]; /* System services only. */ if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { continue; } /* Lookup the corresponding entries in other tables. */ boot_image_info_lookup(boot_image_priv->endpoint, image, &ip, NULL, &boot_image_sys, &boot_image_dev); rp = &rproc[boot_image_priv - boot_image_priv_table]; rpub = rp->r_pub; /* * Set privileges. */ /* Get label. */ strcpy(rpub->label, boot_image_priv->label); /* 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 and signal manager. */ rp->r_priv.s_flags = boot_image_priv->flags; /* priv flags */ rp->r_priv.s_init_flags = SRV_OR_USR(rp, SRV_I, USR_I); /* init flags */ rp->r_priv.s_trap_mask= SRV_OR_USR(rp, SRV_T, USR_T); /* traps */ ipc_to = SRV_OR_USR(rp, SRV_M, USR_M); /* targets */ fill_send_mask(&rp->r_priv.s_ipc_to, ipc_to == ALL_M); rp->r_priv.s_sig_mgr= SRV_OR_USR(rp, SRV_SM, USR_SM); /* sig mgr */ rp->r_priv.s_bak_sig_mgr = NONE; /* backup sig mgr */ /* Initialize kernel call mask bitmap. */ calls = SRV_OR_USR(rp, SRV_KC, USR_KC) == ALL_C ? all_c : no_c; fill_call_mask(calls, NR_SYS_CALLS, rp->r_priv.s_k_call_mask, KERNEL_CALL, TRUE); /* Set the privilege structure. RS and VM are exceptions and are already * running. */ if(boot_image_priv->endpoint != RS_PROC_NR && boot_image_priv->endpoint != VM_PROC_NR) { if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv))) != OK) { panic("unable to set privilege structure: %d", s); } } /* Synch the privilege structure with the kernel. */ if ((s = sys_getpriv(&(rp->r_priv), ip->endpoint)) != OK) { panic("unable to synch privilege structure: %d", s); } /* * Set sys properties. */ rpub->sys_flags = boot_image_sys->flags; /* sys flags */ /* * Set dev properties. */ rpub->dev_nr = boot_image_dev->dev_nr; /* major device number */ /* Build command settings. Also set the process name. */ strlcpy(rp->r_cmd, ip->proc_name, sizeof(rp->r_cmd)); rp->r_script[0]= '\0'; build_cmd_dep(rp); strlcpy(rpub->proc_name, ip->proc_name, sizeof(rpub->proc_name)); /* Initialize vm call mask bitmap. */ calls = SRV_OR_USR(rp, SRV_VC, USR_VC) == ALL_C ? all_c : no_c; fill_call_mask(calls, NR_VM_CALLS, rpub->vm_call_mask, VM_RQ_BASE, TRUE); /* Scheduling parameters. */ rp->r_scheduler = SRV_OR_USR(rp, SRV_SCH, USR_SCH); rp->r_priority = SRV_OR_USR(rp, SRV_Q, USR_Q); rp->r_quantum = SRV_OR_USR(rp, SRV_QT, USR_QT); /* Get some settings from the boot image table. */ rpub->endpoint = ip->endpoint; /* Set some defaults. */ rp->r_old_rp = NULL; /* no old version yet */ rp->r_new_rp = NULL; /* no new version yet */ rp->r_prev_rp = NULL; /* no prev replica yet */ rp->r_next_rp = NULL; /* no next replica yet */ rp->r_uid = 0; /* root */ rp->r_check_tm = 0; /* not checked yet */ rp->r_alive_tm = getticks(); /* currently alive */ rp->r_stop_tm = 0; /* not exiting yet */ rp->r_asr_count = 0; /* no ASR updates yet */ rp->r_restarts = 0; /* no restarts so far */ rp->r_period = 0; /* no period yet */ rp->r_exec = NULL; /* no in-memory copy yet */ rp->r_exec_len = 0; /* Mark as in use and active. */ rp->r_flags = RS_IN_USE | RS_ACTIVE; rproc_ptr[_ENDPOINT_P(rpub->endpoint)]= rp; rpub->in_use = TRUE; } /* - Step 2: allow every system service in the boot image to run. */ nr_uncaught_init_srvs = 0; for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { boot_image_priv = &boot_image_priv_table[i]; /* System services only. */ if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { continue; } /* Lookup the corresponding slot in the system process table. */ rp = &rproc[boot_image_priv - boot_image_priv_table]; rpub = rp->r_pub; /* RS/VM are already running as we speak. */ if(boot_image_priv->endpoint == RS_PROC_NR || boot_image_priv->endpoint == VM_PROC_NR) { if ((s = init_service(rp, SEF_INIT_FRESH, rp->r_priv.s_init_flags)) != OK) { panic("unable to initialize %d: %d", boot_image_priv->endpoint, s); } /* VM will still send an RS_INIT message, though. */ if (boot_image_priv->endpoint != RS_PROC_NR) { nr_uncaught_init_srvs++; } continue; } /* Allow the service to run. */ if ((s = sched_init_proc(rp)) != OK) { panic("unable to initialize scheduling: %d", s); } if ((s = sys_privctl(rpub->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) { panic("unable to initialize privileges: %d", 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, rp->r_priv.s_init_flags)) != OK) { panic("unable to initialize service: %d", s); } if(rpub->sys_flags & SF_SYNCH_BOOT) { /* Catch init ready message now to synchronize. */ catch_boot_init_ready(rpub->endpoint); } else { /* Catch init ready message later. */ nr_uncaught_init_srvs++; } } } /* - Step 3: let every system service complete initialization by * catching all the init ready messages left. */ while(nr_uncaught_init_srvs) { catch_boot_init_ready(ANY); nr_uncaught_init_srvs--; } /* - Step 4: all the system services in the boot image are now running. * Complete the initialization of the system process table in collaboration * with other system services. */ for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { boot_image_priv = &boot_image_priv_table[i]; /* System services only. */ if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { continue; } /* Lookup the corresponding slot in the system process table. */ rp = &rproc[boot_image_priv - boot_image_priv_table]; rpub = rp->r_pub; /* Get pid from PM. */ rp->r_pid = getnpid(rpub->endpoint); if(rp->r_pid < 0) { panic("unable to get pid: %d", rp->r_pid); } } /* Set alarm to periodically check service status. */ if (OK != (s=sys_setalarm(RS_DELTA_T, 0))) panic("couldn't set alarm: %d", s); #if USE_LIVEUPDATE /* Now create a new RS instance and let the current * instance live update into the replica. Clone RS' own slot first. */ rp = rproc_ptr[_ENDPOINT_P(RS_PROC_NR)]; if((s = clone_slot(rp, &replica_rp)) != OK) { panic("unable to clone current RS instance: %d", s); } /* Fork a new RS instance with root:wheel. */ pid = srv_fork(0, 0); if(pid < 0) { panic("unable to fork a new RS instance: %d", pid); } replica_pid = pid ? pid : getpid(); if ((s = getprocnr(replica_pid, &replica_endpoint)) != 0) panic("unable to get replica endpoint: %d", s); replica_rp->r_pid = replica_pid; replica_rp->r_pub->endpoint = replica_endpoint; if(pid == 0) { /* New RS instance running. */ /* Live update the old instance into the new one. */ s = update_service(&rp, &replica_rp, RS_SWAP, 0); if(s != OK) { panic("unable to live update RS: %d", s); } cpf_reload(); /* Clean up the old RS instance, the new instance will take over. */ cleanup_service(rp); /* Ask VM to pin memory for the new RS instance. */ if((s = vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN, 0, 0)) != OK) { panic("unable to pin memory for the new RS instance: %d", s); } } else { /* Old RS instance running. */ /* Set up privileges for the new instance and let it run. */ s = sys_privctl(replica_endpoint, SYS_PRIV_SET_SYS, &(replica_rp->r_priv)); if(s != OK) { panic("unable to set privileges for the new RS instance: %d", s); } if ((s = sched_init_proc(replica_rp)) != OK) { panic("unable to initialize RS replica scheduling: %d", s); } s = sys_privctl(replica_endpoint, SYS_PRIV_YIELD, NULL); if(s != OK) { panic("unable to yield control to the new RS instance: %d", s); } NOT_REACHABLE; } #endif /* USE_LIVEUPDATE */ return(OK); }
PUBLIC void main() { mq_t *mq; int r; int source, timerand, fd; struct fssignon device; #ifdef __minix_vmd struct systaskinfo info; #endif u8_t randbits[32]; struct timeval tv; #if DEBUG printf("Starting inet...\n"); printf("%s\n", version); #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("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("unable to open random device %s: %s\n", RANDOM_DEV_NAME, strerror(errno)); } if (timerand) { printf("using current time for random-number seed\n"); #ifdef __minix_vmd r= sysutime(UTIME_TIMEOFDAY, &tv); #else /* Minix 3 */ r= gettimeofday(&tv, NULL); #endif if (r == -1) { printf("sysutime failed: %s\n", strerror(errno)); exit(1); } memcpy(randbits, &tv, sizeof(tv)); } init_rand256(randbits); #ifdef __minix_vmd if (svrctl(SYSSIGNON, (void *) &info) == -1) pause(); /* Our new identity as a server. */ this_proc = info.proc_nr; #else /* Minix 3 */ /* Our new identity as a server. */ if ((this_proc = getprocnr()) < 0) ip_panic(( "unable to get own process nr\n")); #endif /* 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; } #ifdef __minix_vmd r= sys_findproc(SYN_AL_NAME, &synal_tasknr, 0); if (r != OK) ip_panic(( "unable to find synchronous alarm task: %d\n", r )); #endif nw_init(); while (TRUE) { #ifdef BUF_CONSISTENCY_CHECK if (inet_buf_debug) { static int buf_debug_count= 0; if (++buf_debug_count >= inet_buf_debug) { buf_debug_count= 0; if (!bf_consistency_check()) break; } } #endif if (ev_head) { ev_process(); continue; } if (clck_call_expire) { clck_expire_timers(); continue; } mq= mq_get(); if (!mq) ip_panic(("out of messages")); r= receive (ANY, &mq->mq_mess); if (r<0) { ip_panic(("unable to receive: %d", r)); } reset_time(); source= mq->mq_mess.m_source; if (source == FS_PROC_NR) { sr_rec(mq); } #ifdef __minix_vmd else if (source == synal_tasknr) { clck_tick (&mq->mq_mess); mq_free(mq); } #else /* Minix 3 */ else if (mq->mq_mess.m_type == SYN_ALARM) { clck_tick(&mq->mq_mess); mq_free(mq); } else if (mq->mq_mess.m_type == SYS_SIG) { /* signaled */ /* probably SIGTERM */ mq_free(mq); } else if (mq->mq_mess.m_type & NOTIFY_MESSAGE) { /* A driver is (re)started. */ eth_check_drivers(&mq->mq_mess); mq_free(mq); } #endif else { compare(mq->mq_mess.m_type, ==, DL_TASK_REPLY); eth_rec(&mq->mq_mess); mq_free(mq); } } ip_panic(("task is not allowed to terminate")); }
/*===========================================================================* * main * *===========================================================================*/ int main(int argc, char **argv) { endpoint_t ep_self, ep_child; size_t size = BUF_SIZE; int i, r, pid; int status; u64_t start, end, diff; double micros; char nr_pages_str[10], is_map_str[2], is_write_str[2]; int nr_pages, is_map, is_write; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); /* Parse the command line. */ r = env_get_param("pages", nr_pages_str, sizeof(nr_pages_str)); errno = 0; nr_pages = atoi(nr_pages_str); if (r != OK || errno || nr_pages <=0) { exit_usage(); } if(nr_pages > TEST_PAGE_NUM) { printf("REQUESTOR: too many pages. Max allowed: %d\n", TEST_PAGE_NUM); exit_usage(); } r = env_get_param("map", is_map_str, sizeof(is_map_str)); errno = 0; is_map = atoi(is_map_str); if (r != OK || errno || (is_map!=0 && is_map!=1)) { exit_usage(); } r = env_get_param("write", is_write_str, sizeof(is_write_str)); errno = 0; is_write = atoi(is_write_str); if (r != OK || errno || (is_write!=0 && is_write!=1)) { exit_usage(); } printf("REQUESTOR: Running tests with pages=%d map=%d write=%d...\n", nr_pages, is_map, is_write); /* Prepare work. */ buf = (char*) CLICK_CEIL(buf_buf); fid_get = open(FIFO_GRANTOR, O_RDONLY); fid_send = open(FIFO_REQUESTOR, O_WRONLY); if(fid_get < 0 || fid_send < 0) { printf("REQUESTOR: can't open fifo files.\n"); return 1; } /* Send the endpoint to the granter, in order to let him to * create the grant. */ ep_self = getprocnr(); write(fid_send, &ep_self, sizeof(ep_self)); dprint("REQUESTOR: sending my endpoint: %d\n", ep_self); /* Get the granter's endpoint and gid. */ read(fid_get, &ep_granter, sizeof(ep_granter)); read(fid_get, &gid, sizeof(gid)); dprint("REQUESTOR: getting granter's endpoint %d and gid %d\n", ep_granter, gid); FIFO_WAIT(fid_get); diff = make64(0, 0); if(is_map) { /* Test safemap. */ for(i=0;i<NR_TEST_ITERATIONS;i++) { read_tsc_64(&start); r = sys_safemap(ep_granter, gid, 0, (long)buf, nr_pages*CLICK_SIZE, D, 1); if(r != OK) { printf("REQUESTOR: safemap error: %d\n", r); return 1; } read_write_buff(buf, nr_pages*CLICK_SIZE, is_write); read_tsc_64(&end); diff = add64(diff, (sub64(end, start))); r = sys_safeunmap(D, (long)buf); if(r != OK) { printf("REQUESTOR: safeunmap error: %d\n", r); return 1; } } micros = ((double)tsc_64_to_micros(diff)) / (NR_TEST_ITERATIONS*nr_pages); REPORT_TEST("REQUESTOR", "SAFEMAP", micros); } else { /* Test safecopy. */ for(i=0;i<NR_TEST_ITERATIONS;i++) { read_tsc_64(&start); r = sys_safecopyfrom(ep_granter, gid, 0, (long)buf, nr_pages*CLICK_SIZE, D); if(r != OK) { printf("REQUESTOR: safecopy error: %d\n", r); return 1; } read_write_buff(buf, nr_pages*CLICK_SIZE, is_write); read_tsc_64(&end); diff = add64(diff, (sub64(end, start))); } micros = ((double)tsc_64_to_micros(diff)) / (NR_TEST_ITERATIONS*nr_pages); REPORT_TEST("REQUESTOR", "SAFECOPY", micros); } FIFO_NOTIFY(fid_send); return 0; }