diff --git a/servers/ds/Makefile b/servers/ds/Makefile index f78e608d7..ec81a5be6 100644 --- a/servers/ds/Makefile +++ b/servers/ds/Makefile @@ -26,9 +26,8 @@ $(SERVER): $(OBJ) # install -S 256w $@ # install with other servers -install: /sbin/$(SERVER) -/sbin/$(SERVER): $(SERVER) - install -o root -c $? $@ +install: $(SERVER) + install -o root -c $? /sbin/$(SERVER) # install -o root -cs $? $@ # clean up local files diff --git a/servers/ds/main.c b/servers/ds/main.c index 8963ee3c6..a0770aff0 100644 --- a/servers/ds/main.c +++ b/servers/ds/main.c @@ -11,7 +11,7 @@ #include "inc.h" /* include master header file */ /* Allocate space for the global variables. */ -int who; /* caller's proc number */ +int who_e; /* caller's proc number */ int callnr; /* system call number */ int sys_panic; /* flag to indicate system-wide panic */ @@ -72,7 +72,7 @@ PUBLIC int main(int argc, char **argv) /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { m.m_type = result; /* build reply message */ - reply(who, &m); /* send it away */ + reply(who_e, &m); /* send it away */ } } return(OK); /* shouldn't come here */ @@ -116,19 +116,19 @@ message *m_ptr; /* message buffer */ status = receive(ANY, m_ptr); /* this blocks until message arrives */ if (OK != status) panic("DS","failed to receive message!", status); - who = m_ptr->m_source; /* message arrived! set sender */ + who_e = m_ptr->m_source; /* message arrived! set sender */ callnr = m_ptr->m_type; /* set function call number */ } /*===========================================================================* * reply * *===========================================================================*/ -PRIVATE void reply(who, m_ptr) -int who; /* destination */ +PRIVATE void reply(who_e, m_ptr) +int who_e; /* destination */ message *m_ptr; /* message buffer */ { int s; - s = send(who, m_ptr); /* send the message */ + s = send(who_e, m_ptr); /* send the message */ if (OK != s) panic("DS", "unable to send reply!", s); } diff --git a/servers/fs/device.c b/servers/fs/device.c index e65ff9abe..c6a1879b9 100644 --- a/servers/fs/device.c +++ b/servers/fs/device.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "file.h" #include "fproc.h" #include "inode.h" @@ -30,6 +31,7 @@ #define ELEMENTS(a) (sizeof(a)/sizeof((a)[0])) extern int dmap_size; +PRIVATE int dummyproc; /*===========================================================================* * dev_open * @@ -49,9 +51,8 @@ int flags; /* mode bits and flags */ major = (dev >> MAJOR) & BYTE; if (major >= NR_DEVICES) major = 0; dp = &dmap[major]; - if (dp->dmap_driver == NONE) { + if (dp->dmap_driver == NONE) return ENXIO; - } r = (*dp->dmap_opcl)(DEV_OPEN, dev, proc, flags); if (r == SUSPEND) panic(__FILE__,"suspend on open from", dp->dmap_driver); return(r); @@ -99,7 +100,7 @@ PUBLIC void dev_status(message *m) switch(st.m_type) { case DEV_REVIVE: - revive(st.REP_PROC_NR, st.REP_STATUS); + revive(st.REP_ENDPT, st.REP_STATUS); break; case DEV_IO_READY: select_notified(d, st.DEV_MINOR, st.DEV_SEL_OPS); @@ -119,10 +120,10 @@ PUBLIC void dev_status(message *m) /*===========================================================================* * dev_io * *===========================================================================*/ -PUBLIC int dev_io(op, dev, proc, buf, pos, bytes, flags) +PUBLIC int dev_io(op, dev, proc_e, buf, pos, bytes, flags) int op; /* DEV_READ, DEV_WRITE, DEV_IOCTL, etc. */ dev_t dev; /* major-minor device number */ -int proc; /* in whose address space is buf? */ +int proc_e; /* in whose address space is buf? */ void *buf; /* virtual address of the buffer */ off_t pos; /* byte position */ int bytes; /* how many bytes to transfer */ @@ -138,14 +139,20 @@ int flags; /* special flags, like O_NONBLOCK */ /* See if driver is roughly valid. */ if (dp->dmap_driver == NONE) { printf("FS: dev_io: no driver for dev %x\n", dev); - return EIO; + return ENXIO; + } + + if(isokendpt(dp->dmap_driver, &dummyproc) != OK) { + printf("FS: dev_io: old driver for dev %x (%d)\n", + dev, dp->dmap_driver); + return ENXIO; } /* Set up the message passed to task. */ dev_mess.m_type = op; dev_mess.DEVICE = (dev >> MINOR) & BYTE; dev_mess.POSITION = pos; - dev_mess.PROC_NR = proc; + dev_mess.IO_ENDPT = proc_e; dev_mess.ADDRESS = buf; dev_mess.COUNT = bytes; dev_mess.TTY_FLAGS = flags; @@ -153,12 +160,15 @@ int flags; /* special flags, like O_NONBLOCK */ /* Call the task. */ (*dp->dmap_io)(dp->dmap_driver, &dev_mess); + if(dp->dmap_driver == NONE) + panic(__FILE__,"dev_io: driver changed to NONE", NO_NUM); + /* Task has completed. See if call completed. */ if (dev_mess.REP_STATUS == SUSPEND) { if (flags & O_NONBLOCK) { /* Not supposed to block. */ dev_mess.m_type = CANCEL; - dev_mess.PROC_NR = proc; + dev_mess.IO_ENDPT = proc_e; dev_mess.DEVICE = (dev >> MINOR) & BYTE; (*dp->dmap_io)(dp->dmap_driver, &dev_mess); if (dev_mess.REP_STATUS == EINTR) dev_mess.REP_STATUS = EAGAIN; @@ -174,10 +184,10 @@ int flags; /* special flags, like O_NONBLOCK */ /*===========================================================================* * gen_opcl * *===========================================================================*/ -PUBLIC int gen_opcl(op, dev, proc, flags) +PUBLIC int gen_opcl(op, dev, proc_e, flags) int op; /* operation, DEV_OPEN or DEV_CLOSE */ dev_t dev; /* device to open or close */ -int proc; /* process to open/close for */ +int proc_e; /* process to open/close for */ int flags; /* mode bits and flags */ { /* Called from the dmap struct in table.c on opens & closes of special files.*/ @@ -189,9 +199,19 @@ int flags; /* mode bits and flags */ dev_mess.m_type = op; dev_mess.DEVICE = (dev >> MINOR) & BYTE; - dev_mess.PROC_NR = proc; + dev_mess.IO_ENDPT = proc_e; dev_mess.COUNT = flags; + if (dp->dmap_driver == NONE) { + printf("FS: gen_opcl: no driver for dev %x\n", dev); + return ENXIO; + } + if(isokendpt(dp->dmap_driver, &dummyproc) != OK) { + printf("FS: gen_opcl: old driver for dev %x (%d)\n", + dev, dp->dmap_driver); + return ENXIO; + } + /* Call the task. */ (*dp->dmap_io)(dp->dmap_driver, &dev_mess); @@ -201,10 +221,10 @@ int flags; /* mode bits and flags */ /*===========================================================================* * tty_opcl * *===========================================================================*/ -PUBLIC int tty_opcl(op, dev, proc, flags) +PUBLIC int tty_opcl(op, dev, proc_e, flags) int op; /* operation, DEV_OPEN or DEV_CLOSE */ dev_t dev; /* device to open or close */ -int proc; /* process to open/close for */ +int proc_e; /* process to open/close for */ int flags; /* mode bits and flags */ { /* This procedure is called from the dmap struct on tty open/close. */ @@ -224,7 +244,7 @@ int flags; /* mode bits and flags */ } } - r = gen_opcl(op, dev, proc, flags); + r = gen_opcl(op, dev, proc_e, flags); /* Did this call make the tty the controlling tty? */ if (r == 1) { @@ -237,10 +257,10 @@ int flags; /* mode bits and flags */ /*===========================================================================* * ctty_opcl * *===========================================================================*/ -PUBLIC int ctty_opcl(op, dev, proc, flags) +PUBLIC int ctty_opcl(op, dev, proc_e, flags) int op; /* operation, DEV_OPEN or DEV_CLOSE */ dev_t dev; /* device to open or close */ -int proc; /* process to open/close for */ +int proc_e; /* process to open/close for */ int flags; /* mode bits and flags */ { /* This procedure is called from the dmap struct in table.c on opening/closing @@ -259,12 +279,14 @@ PUBLIC int do_setsid() * terminal of a process, and make the process a session leader. */ register struct fproc *rfp; + int slot; /* Only MM may do the SETSID call directly. */ - if (who != PM_PROC_NR) return(ENOSYS); + if (who_e != PM_PROC_NR) return(ENOSYS); /* Make the process a session leader with no controlling tty. */ - rfp = &fproc[m_in.slot1]; + okendpt(m_in.endpt1, &slot); + rfp = &fproc[slot]; rfp->fp_sesldr = TRUE; rfp->fp_tty = 0; return(OK); @@ -297,10 +319,22 @@ PUBLIC int do_ioctl() dev_mess = m; /* Copy full message with all the weird bits. */ dev_mess.m_type = DEV_IOCTL; - dev_mess.PROC_NR = who; + dev_mess.PROC_NR = who_e; dev_mess.TTY_LINE = (dev >> MINOR) & BYTE; /* Call the task. */ + + if (dp->dmap_driver == NONE) { + printf("FS: do_ioctl: no driver for dev %x\n", dev); + return ENXIO; + } + + if(isokendpt(dp->dmap_driver, &dummyproc) != OK) { + printf("FS: do_ioctl: old driver for dev %x (%d)\n", + dev, dp->dmap_driver); + return ENXIO; + } + (*dp->dmap_io)(dp->dmap_driver, &dev_mess); m_out.TTY_SPEK = dev_mess.TTY_SPEK; /* erase and kill */ @@ -309,7 +343,7 @@ PUBLIC int do_ioctl() } #endif - return(dev_io(DEV_IOCTL, dev, who, m_in.ADDRESS, 0L, + return(dev_io(DEV_IOCTL, dev, who_e, m_in.ADDRESS, 0L, m_in.REQUEST, f->filp_flags)); } @@ -324,16 +358,12 @@ message *mess_ptr; /* pointer to message for task */ * pairs. These lead to calls on the following routines via the dmap table. */ - int r, proc_nr; + int r, proc_e, dummy_proc; message local_m; - proc_nr = mess_ptr->PROC_NR; - if (! isokprocnr(proc_nr)) { - printf("FS: warning, got illegal process number (%d) from %d\n", - mess_ptr->PROC_NR, mess_ptr->m_source); - return; - } + proc_e = mess_ptr->IO_ENDPT; +#if DEAD_CODE while ((r = sendrec(task_nr, mess_ptr)) == ELOCKED) { /* sendrec() failed to avoid deadlock. The task 'task_nr' is * trying to send a REVIVE message for an earlier request. @@ -347,7 +377,7 @@ message *mess_ptr; /* pointer to message for task */ * sent a completion reply, ignore the reply and abort the cancel * request. The caller will do the revive for the process. */ - if (mess_ptr->m_type == CANCEL && local_m.REP_PROC_NR == proc_nr) { + if (mess_ptr->m_type == CANCEL && local_m.REP_ENDPT == proc_e) { return; } @@ -356,39 +386,43 @@ message *mess_ptr; /* pointer to message for task */ printf( "fs: strange device reply from %d, type = %d, proc = %d (1)\n", local_m.m_source, - local_m.m_type, local_m.REP_PROC_NR); + local_m.m_type, local_m.REP_ENDPT); continue; } - revive(local_m.REP_PROC_NR, local_m.REP_STATUS); + revive(local_m.REP_ENDPT, local_m.REP_STATUS); } +#endif /* The message received may be a reply to this call, or a REVIVE for some * other process. */ - for (;;) { + r = sendrec(task_nr, mess_ptr); + for(;;) { if (r != OK) { - if (r == EDEADSRCDST) return; /* give up */ - if (r == EDSTDIED) return; - if (r == ESRCDIED) return; - if (r == ELOCKED) return; - else panic(__FILE__,"call_task: can't send/receive", r); + if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) { + printf("fs: dead driver %d\n", task_nr); + return; + } + if (r == ELOCKED) { + printf("fs: ELOCKED talking to %d\n", task_nr); + return; + } + panic(__FILE__,"call_task: can't send/receive", r); } /* Did the process we did the sendrec() for get a result? */ - if (mess_ptr->REP_PROC_NR == proc_nr) { + if (mess_ptr->REP_ENDPT == proc_e) { break; } else if (mess_ptr->m_type == REVIVE) { /* Otherwise it should be a REVIVE. */ - revive(mess_ptr->REP_PROC_NR, mess_ptr->REP_STATUS); + revive(mess_ptr->REP_ENDPT, mess_ptr->REP_STATUS); } else { printf( - "fs: strange device reply from %d, type = %d, proc = %d (2)\n", + "fs: strange device reply from %d, type = %d, proc = %d (2) ignored\n", mess_ptr->m_source, - mess_ptr->m_type, mess_ptr->REP_PROC_NR); - return; + mess_ptr->m_type, mess_ptr->REP_ENDPT); } - r = receive(task_nr, mess_ptr); } } @@ -414,6 +448,18 @@ message *mess_ptr; /* pointer to message for task */ /* Substitute the controlling terminal device. */ dp = &dmap[(fp->fp_tty >> MAJOR) & BYTE]; mess_ptr->DEVICE = (fp->fp_tty >> MINOR) & BYTE; + + if (dp->dmap_driver == NONE) { + printf("FS: ctty_io: no driver for dev\n"); + return; + } + + if(isokendpt(dp->dmap_driver, &dummyproc) != OK) { + printf("FS: ctty_io: old driver %d\n", + dp->dmap_driver); + return; + } + (*dp->dmap_io)(dp->dmap_driver, mess_ptr); } } @@ -444,10 +490,10 @@ PUBLIC void no_dev_io(int proc, message *m) /*===========================================================================* * clone_opcl * *===========================================================================*/ -PUBLIC int clone_opcl(op, dev, proc, flags) +PUBLIC int clone_opcl(op, dev, proc_e, flags) int op; /* operation, DEV_OPEN or DEV_CLOSE */ dev_t dev; /* device to open or close */ -int proc; /* process to open/close for */ +int proc_e; /* process to open/close for */ int flags; /* mode bits and flags */ { /* Some devices need special processing upon open. Such a device is "cloned", @@ -465,9 +511,21 @@ int flags; /* mode bits and flags */ dev_mess.m_type = op; dev_mess.DEVICE = minor; - dev_mess.PROC_NR = proc; + dev_mess.IO_ENDPT = proc_e; dev_mess.COUNT = flags; + + if (dp->dmap_driver == NONE) { + printf("FS: clone_opcl: no driver for dev %x\n", dev); + return ENXIO; + } + + if(isokendpt(dp->dmap_driver, &dummyproc) != OK) { + printf("FS: clone_opcl: old driver for dev %x (%d)\n", + dev, dp->dmap_driver); + return ENXIO; + } + /* Call the task. */ (*dp->dmap_io)(dp->dmap_driver, &dev_mess); @@ -484,7 +542,7 @@ int flags; /* mode bits and flags */ ip = alloc_inode(root_dev, ALL_MODES | I_CHAR_SPECIAL); if (ip == NIL_INODE) { /* Oops, that didn't work. Undo open. */ - (void) clone_opcl(DEV_CLOSE, dev, proc, 0); + (void) clone_opcl(DEV_CLOSE, dev, proc_e, 0); return(err_code); } ip->i_zone[0] = dev; diff --git a/servers/fs/dmap.c b/servers/fs/dmap.c index ecb8866ab..cbafda903 100644 --- a/servers/fs/dmap.c +++ b/servers/fs/dmap.c @@ -79,9 +79,9 @@ PUBLIC int do_devctl() /*===========================================================================* * map_driver * *===========================================================================*/ -PUBLIC int map_driver(major, proc_nr, style) +PUBLIC int map_driver(major, proc_nr_e, style) int major; /* major number of the device */ -int proc_nr; /* process number of the driver */ +int proc_nr_e; /* process number of the driver */ int style; /* style of the device */ { /* Set a new device driver mapping in the dmap table. Given that correct @@ -93,6 +93,7 @@ int style; /* style of the device */ * a system call that tries to dynamically install a new driver. */ struct dmap *dp; + int proc_nr_n; /* Get pointer to device entry in the dmap table. */ if (major < 0 || major >= NR_DEVICES) return(ENODEV); @@ -102,7 +103,7 @@ int style; /* style of the device */ * if busy or unmutable, as unmap is called when driver has * exited. */ - if(proc_nr == NONE) { + if(proc_nr_e == NONE) { dp->dmap_opcl = no_dev; dp->dmap_io = no_dev_io; dp->dmap_driver = NONE; @@ -115,7 +116,8 @@ int style; /* style of the device */ if (dp->dmap_flags & DMAP_BUSY) return(EBUSY); /* Check process number of new driver. */ - if (! isokprocnr(proc_nr)) return(EINVAL); + if (isokendpt(proc_nr_e, &proc_nr_n) != OK) + return(EINVAL); /* Try to update the entry. */ switch (style) { @@ -125,10 +127,10 @@ int style; /* style of the device */ default: return(EINVAL); } dp->dmap_io = gen_io; - dp->dmap_driver = proc_nr; + dp->dmap_driver = proc_nr_e; /* If a driver has completed its exec(), it can be announced to be up. */ - if(fproc[proc_nr].fp_execced) { + if(fproc[proc_nr_n].fp_execced) { dev_up(major); } else { dp->dmap_flags |= DMAP_BABY; @@ -138,15 +140,15 @@ int style; /* style of the device */ } /*===========================================================================* - * dmap_unmap_by_proc * + * dmap_unmap_by_endpt * *===========================================================================*/ -PUBLIC void dmap_unmap_by_proc(int proc_nr) +PUBLIC void dmap_unmap_by_endpt(int proc_nr_e) { int i, r; for (i=0; ifp_task; if (fptr->fp_suspended == SUSPENDED && task == XLOCK) { - revive( (int) (fptr - fproc), 0); + revive(fptr->fp_endpoint, 0); } } } diff --git a/servers/fs/main.c b/servers/fs/main.c index 7e318c602..06e9b9d63 100644 --- a/servers/fs/main.c +++ b/servers/fs/main.c @@ -22,6 +22,7 @@ struct super_block; /* proto.h needs to know this */ #include #include #include +#include #include "buf.h" #include "file.h" #include "fproc.h" @@ -49,11 +50,12 @@ PUBLIC int main() fs_init(); + /* This is the main loop that gets work, processes it, and sends replies. */ while (TRUE) { get_work(); /* sets who and call_nr */ - fp = &fproc[who]; /* pointer to proc table struct */ + fp = &fproc[who_p]; /* pointer to proc table struct */ super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE); /* su? */ /* Check for special control messages first. */ @@ -75,17 +77,17 @@ PUBLIC int main() /* Call the internal function that does the work. */ if (call_nr < 0 || call_nr >= NCALLS) { error = ENOSYS; - printf("FS, warning illegal %d system call by %d\n", call_nr, who); + printf("FS, warning illegal %d system call by %d\n", call_nr, who_e); } else if (fp->fp_pid == PID_FREE) { error = ENOSYS; - printf("FS, bad process, who = %d, call_nr = %d, slot1 = %d\n", - who, call_nr, m_in.slot1); + printf("FS, bad process, who = %d, call_nr = %d, endpt1 = %d\n", + who_e, call_nr, m_in.endpt1); } else { error = (*call_vec[call_nr])(); } /* Copy the results back to the user and send reply. */ - if (error != SUSPEND) { reply(who, error); } + if (error != SUSPEND) { reply(who_e, error); } if (rdahed_inode != NIL_INODE) { read_ahead(); /* do block read ahead */ } @@ -103,12 +105,14 @@ PRIVATE void get_work() * nonzero, a suspended process must be awakened. */ register struct fproc *rp; + int l = 0; if (reviving != 0) { /* Revive a suspended process. */ for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++) if (rp->fp_revived == REVIVING) { - who = (int)(rp - fproc); + who_p = (int)(rp - fproc); + who_e = rp->fp_endpoint; call_nr = rp->fp_fd & BYTE; m_in.fd = (rp->fp_fd >>8) & BYTE; m_in.buffer = rp->fp_buffer; @@ -121,10 +125,27 @@ PRIVATE void get_work() panic(__FILE__,"get_work couldn't revive anyone", NO_NUM); } - /* Normal case. No one to revive. */ - if (receive(ANY, &m_in) != OK) panic(__FILE__,"fs receive error", NO_NUM); - who = m_in.m_source; - call_nr = m_in.m_type; + for(;;) { + /* Normal case. No one to revive. */ + if (receive(ANY, &m_in) != OK) + panic(__FILE__,"fs receive error", NO_NUM); + who_e = m_in.m_source; + who_p = _ENDPOINT_P(who_e); + if(who_p < -NR_TASKS || who_p >= NR_PROCS) + panic(__FILE__,"receive process out of range", who_p); + if(who_p >= 0 && fproc[who_p].fp_endpoint == NONE) { + printf("FS: ignoring request from %d, endpointless slot %d (%d)", + m_in.m_source, who_p, m_in.m_type); + continue; + } + if(who_p >= 0 && fproc[who_p].fp_endpoint != who_e) { + printf("FS: receive endpoint inconsistent (%d, %d), ignoring %d", + fproc[who_p].fp_endpoint, who_e, m_in.m_type); + continue; + } + call_nr = m_in.m_type; + return; + } } /*===========================================================================* @@ -168,7 +189,8 @@ int result; /* result of the call (usually OK or error #) */ int s; m_out.reply_type = result; s = send(whom, &m_out); - if (s != OK) printf("FS: couldn't send reply %d: %d\n", result, s); + if (s != OK) printf("FS: couldn't send reply %d to %d: %d\n", + result, whom, s); } /*===========================================================================* @@ -188,12 +210,14 @@ PRIVATE void fs_init() * Then, stop and synchronize with the PM. */ do { + int slot; if (OK != (s=receive(PM_PROC_NR, &mess))) panic(__FILE__,"FS couldn't receive from PM", s); - if (NONE == mess.PR_PROC_NR) break; + if (NONE == mess.PR_ENDPT) break; - rfp = &fproc[mess.PR_PROC_NR]; + rfp = &fproc[mess.PR_SLOT]; rfp->fp_pid = mess.PR_PID; + rfp->fp_endpoint = mess.PR_ENDPT; rfp->fp_realuid = (uid_t) SYS_UID; rfp->fp_effuid = (uid_t) SYS_UID; rfp->fp_realgid = (gid_t) SYS_GID; @@ -217,7 +241,7 @@ PRIVATE void fs_init() /* The following initializations are needed to let dev_opcl succeed .*/ fp = (struct fproc *) NULL; - who = FS_PROC_NR; + who_e = who_p = FS_PROC_NR; buf_pool(); /* initialize buffer pool */ build_dmap(); /* build device table and map boot driver */ @@ -232,7 +256,7 @@ PRIVATE void fs_init() dup_inode(rip); rfp->fp_rootdir = rip; rfp->fp_workdir = rip; - } + } else rfp->fp_endpoint = NONE; } } @@ -335,7 +359,7 @@ PRIVATE void load_ram(void) /* Tell RAM driver how big the RAM disk must be. */ m_out.m_type = DEV_IOCTL; - m_out.PROC_NR = FS_PROC_NR; + m_out.PR_ENDPT = FS_PROC_NR; m_out.DEVICE = RAM_DEV; m_out.REQUEST = MIOCRAMSIZE; /* I/O control to use */ m_out.POSITION = (ram_size_kb * 1024); /* request in bytes */ diff --git a/servers/fs/misc.c b/servers/fs/misc.c index 4fd694784..cd30e12a9 100644 --- a/servers/fs/misc.c +++ b/servers/fs/misc.c @@ -21,6 +21,7 @@ #include #include /* cc runs out of memory with unistd.h :-( */ #include +#include #include #include #include "buf.h" @@ -59,7 +60,7 @@ PUBLIC int do_getsysinfo() } dst_addr = (vir_bytes) m_in.info_where; - if (OK != (s=sys_datacopy(SELF, src_addr, who, dst_addr, len))) + if (OK != (s=sys_datacopy(SELF, src_addr, who_e, dst_addr, len))) return(s); return(OK); @@ -172,7 +173,7 @@ PUBLIC int do_fcntl() } /* Copy flock data from userspace. */ - if((r = sys_datacopy(who, (vir_bytes) m_in.name1, + if((r = sys_datacopy(who_e, (vir_bytes) m_in.name1, SELF, (vir_bytes) &flock_arg, (phys_bytes) sizeof(flock_arg))) != OK) return r; @@ -256,10 +257,13 @@ PUBLIC int do_reboot() struct inode dummy; /* Only PM may make this call directly. */ - if (who != PM_PROC_NR) return(EGENERIC); + if (who_e != PM_PROC_NR) return(EGENERIC); /* Do exit processing for all leftover processes and servers. */ - for (i = 0; i < NR_PROCS; i++) { m_in.slot1 = i; do_exit(); } + for (i = 0; i < NR_PROCS; i++) { + if((m_in.endpt1 = fproc[i].fp_endpoint) != NONE) + do_exit(); + } /* The root file system is mounted onto itself, which keeps it from being * unmounted. Pull an inode out of thin air and put the root on it. @@ -293,21 +297,35 @@ PUBLIC int do_fork() */ register struct fproc *cp; - int i; + int i, parentno, childno; /* Only PM may make this call directly. */ - if (who != PM_PROC_NR) return(EGENERIC); + if (who_e != PM_PROC_NR) return(EGENERIC); + + /* Check up-to-dateness of fproc. */ + okendpt(m_in.parent_endpt, &parentno); + + /* PM gives child endpoint, which implies process slot information. + * Don't call isokendpt, because that will verify if the endpoint + * number is correct in fproc, which it won't be. + */ + childno = _ENDPOINT_P(m_in.child_endpt); + if(childno < 0 || childno >= NR_PROCS) + panic(__FILE__, "FS: bogus child for forking", m_in.child_endpt); + if(fproc[childno].fp_pid != PID_FREE) + panic(__FILE__, "FS: forking on top of in-use child", childno); /* Copy the parent's fproc struct to the child. */ - fproc[m_in.child] = fproc[m_in.parent]; + fproc[childno] = fproc[parentno]; /* Increase the counters in the 'filp' table. */ - cp = &fproc[m_in.child]; + cp = &fproc[childno]; for (i = 0; i < OPEN_MAX; i++) if (cp->fp_filp[i] != NIL_FILP) cp->fp_filp[i]->filp_count++; - /* Fill in new process id. */ + /* Fill in new process and endpoint id. */ cp->fp_pid = m_in.pid; + cp->fp_endpoint = m_in.child_endpt; /* A child is not a process leader. */ cp->fp_sesldr = 0; @@ -330,14 +348,15 @@ PUBLIC int do_exec() * MM does an EXEC, it calls FS to allow FS to find these files and close them. */ - register int i; + int i, proc; long bitmap; /* Only PM may make this call directly. */ - if (who != PM_PROC_NR) return(EGENERIC); + if (who_e != PM_PROC_NR) return(EGENERIC); /* The array of FD_CLOEXEC bits is in the fp_cloexec bit map. */ - fp = &fproc[m_in.slot1]; /* get_filp() needs 'fp' */ + okendpt(m_in.endpt1, &proc); + fp = &fproc[proc]; /* get_filp() needs 'fp' */ bitmap = fp->fp_cloexec; if (bitmap) { /* Check the file desriptors one by one for presence of FD_CLOEXEC. */ @@ -351,10 +370,10 @@ PUBLIC int do_exec() fp->fp_execced = 1; /* Reply to caller (PM) directly. */ - reply(who, OK); + reply(who_e, OK); /* Check if this is a driver that can now be useful. */ - dmap_proc_up(fp - fproc); + dmap_endpt_up(fp->fp_endpoint); /* Suppress reply to caller (caller already replied to). */ return SUSPEND; @@ -367,23 +386,24 @@ PUBLIC int do_exit() { /* Perform the file system portion of the exit(status) system call. */ - register int i, exitee, task; + int i, exitee_p, exitee_e, task; register struct fproc *rfp; register struct filp *rfilp; register struct inode *rip; dev_t dev; /* Only PM may do the EXIT call directly. */ - if (who != PM_PROC_NR) return(EGENERIC); + if (who_e != PM_PROC_NR) return(EGENERIC); /* Nevertheless, pretend that the call came from the user. */ - fp = &fproc[m_in.slot1]; /* get_filp() needs 'fp' */ - exitee = m_in.slot1; + exitee_e = m_in.endpt1; + okendpt(exitee_e, &exitee_p); + fp = &fproc[exitee_p]; /* get_filp() needs 'fp' */ if (fp->fp_suspended == SUSPENDED) { task = -fp->fp_task; if (task == XPIPE || task == XPOPEN) susp_count--; - m_in.pro = exitee; + m_in.ENDPT = exitee_e; (void) do_unpause(); /* this always succeeds for MM */ fp->fp_suspended = NOT_SUSPENDED; } @@ -405,8 +425,11 @@ PUBLIC int do_exit() * (unmapping has to be done after the first step, because the * dmap table is used in the first step.) */ - unsuspend_by_proc(exitee); - dmap_unmap_by_proc(exitee); + unsuspend_by_endpt(exitee_e); + dmap_unmap_by_endpt(exitee_e); + + /* Invalidate endpoint number for error and sanity checks. */ + fp->fp_endpoint = NONE; /* If a session leader exits then revoke access to its controlling tty from * all other processes using it. @@ -450,11 +473,13 @@ PUBLIC int do_set() /* Set uid_t or gid_t field. */ register struct fproc *tfp; + int proc; /* Only PM may make this call directly. */ - if (who != PM_PROC_NR) return(EGENERIC); + if (who_e != PM_PROC_NR) return(EGENERIC); - tfp = &fproc[m_in.slot1]; + okendpt(m_in.endpt1, &proc); + tfp = &fproc[proc]; if (call_nr == SETUID) { tfp->fp_realuid = (uid_t) m_in.real_user_id; tfp->fp_effuid = (uid_t) m_in.eff_user_id; @@ -480,8 +505,7 @@ PUBLIC int do_revive() * 'SUSPEND' pseudo error, and the reply to the blocked process is done * explicitly in revive(). */ - - revive(m_in.REP_PROC_NR, m_in.REP_STATUS); + revive(m_in.REP_ENDPT, m_in.REP_STATUS); return(SUSPEND); /* don't reply to the TTY task */ } @@ -500,21 +524,21 @@ PUBLIC int do_svrctl() return(EPERM); /* Try to copy request structure to FS. */ - if ((r = sys_datacopy(who, (vir_bytes) m_in.svrctl_argp, + if ((r = sys_datacopy(who_e, (vir_bytes) m_in.svrctl_argp, FS_PROC_NR, (vir_bytes) &device, (phys_bytes) sizeof(device))) != OK) return(r); /* Try to update device mapping. */ major = (device.dev >> MAJOR) & BYTE; - r=map_driver(major, who, device.style); + r=map_driver(major, who_e, device.style); return(r); } case FSDEVUNMAP: { struct fsdevunmap fdu; int r, major; /* Try to copy request structure to FS. */ - if ((r = sys_datacopy(who, (vir_bytes) m_in.svrctl_argp, + if ((r = sys_datacopy(who_e, (vir_bytes) m_in.svrctl_argp, FS_PROC_NR, (vir_bytes) &fdu, (phys_bytes) sizeof(fdu))) != OK) return(r); diff --git a/servers/fs/mount.c b/servers/fs/mount.c index 8609a35f6..d6a8d7173 100644 --- a/servers/fs/mount.c +++ b/servers/fs/mount.c @@ -132,7 +132,7 @@ PUBLIC int do_mount() if (sp == NIL_SUPER) return(ENFILE); /* no super block available */ /* Open the device the file system lives on. */ - if (dev_open(dev, who, m_in.rd_only ? R_BIT : (R_BIT|W_BIT)) != OK) + if (dev_open(dev, who_e, m_in.rd_only ? R_BIT : (R_BIT|W_BIT)) != OK) return(EINVAL); /* Make the cache forget about blocks it has open on the filesystem */ diff --git a/servers/fs/open.c b/servers/fs/open.c index 0d94a39b9..1462efca4 100644 --- a/servers/fs/open.c +++ b/servers/fs/open.c @@ -141,7 +141,7 @@ PRIVATE int common_open(register int oflags, mode_t omode) case I_BLOCK_SPECIAL: /* Invoke the driver for special processing. */ dev = (dev_t) rip->i_zone[0]; - r = dev_open(dev, who, bits | (oflags & ~O_ACCMODE)); + r = dev_open(dev, who_e, bits | (oflags & ~O_ACCMODE)); break; case I_NAMED_PIPE: @@ -516,7 +516,7 @@ PUBLIC int do_slink() if ((r = err_code) == OK) { r = (bp = new_block(sip, (off_t) 0)) == NIL_BUF ? err_code - : sys_vircopy(who, D, (vir_bytes) m_in.name1, + : sys_vircopy(who_e, D, (vir_bytes) m_in.name1, SELF, D, (vir_bytes) bp->b_data, (vir_bytes) m_in.name1_length-1); diff --git a/servers/fs/param.h b/servers/fs/param.h index 0a3255f8b..883f2bab3 100644 --- a/servers/fs/param.h +++ b/servers/fs/param.h @@ -2,7 +2,7 @@ #define acc_time m2_l1 #define addr m1_i3 #define buffer m1_p1 -#define child m1_i2 +#define child_endpt m1_i2 #define co_mode m1_i1 #define eff_grp_id m1_i3 #define eff_user_id m1_i3 @@ -26,10 +26,10 @@ #define name2_length m1_i2 #define nbytes m1_i2 #define owner m1_i2 -#define parent m1_i1 +#define parent_endpt m1_i1 #define pathname m3_ca1 #define pid m1_i3 -#define pro m1_i1 +#define ENDPT m1_i1 #define ctl_req m4_l1 #define driver_nr m4_l2 #define dev_nr m4_l3 @@ -38,7 +38,7 @@ #define real_user_id m1_i2 #define request m1_i2 #define sig m1_i2 -#define slot1 m1_i1 +#define endpt1 m1_i1 #define tp m2_l1 #define utime_actime m2_l1 #define utime_modtime m2_l2 diff --git a/servers/fs/pipe.c b/servers/fs/pipe.c index a1c870ad1..eee19a646 100644 --- a/servers/fs/pipe.c +++ b/servers/fs/pipe.c @@ -11,7 +11,7 @@ * release: check to see if a suspended process can be released and do * it * revive: mark a suspended process as able to run again - * unsuspend_by_proc: revive all processes blocking on a given process + * unsuspend_by_endpt: revive all processes blocking on a given process * do_unpause: a signal has been sent to a process; see if it suspended */ @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -124,8 +125,9 @@ int notouch; /* check only */ /* Process is writing to a pipe. */ if (find_filp(rip, R_BIT) == NIL_FILP) { /* Tell kernel to generate a SIGPIPE signal. */ - if (!notouch) - sys_kill((int)(fp - fproc), SIGPIPE); + if (!notouch) { + sys_kill(fp->fp_endpoint, SIGPIPE); + } return(EPIPE); } @@ -185,6 +187,8 @@ int task; /* who is proc waiting for? (PIPE = pipe) */ if (task == XPIPE || task == XPOPEN) susp_count++;/* #procs susp'ed on pipe*/ fp->fp_suspended = SUSPENDED; fp->fp_fd = m_in.fd << 8 | call_nr; + if(task == NONE) + panic(__FILE__,"suspend on NONE",NO_NUM); fp->fp_task = -task; if (task == XLOCK) { fp->fp_buffer = (char *) m_in.name1; /* third arg to fcntl() */ @@ -196,9 +200,9 @@ int task; /* who is proc waiting for? (PIPE = pipe) */ } /*===========================================================================* - * unsuspend_by_proc * + * unsuspend_by_endpt * *===========================================================================*/ -PUBLIC void unsuspend_by_proc(int proc) +PUBLIC void unsuspend_by_endpt(int proc_e) { struct fproc *rp; int client = 0; @@ -207,13 +211,14 @@ PUBLIC void unsuspend_by_proc(int proc) * disappeared with return code EAGAIN. */ for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++, client++) - if(rp->fp_suspended == SUSPENDED && rp->fp_task == -proc) - revive(client, EAGAIN); + if(rp->fp_suspended == SUSPENDED && rp->fp_task == -proc_e) { + revive(rp->fp_endpoint, EAGAIN); + } /* Revive processes waiting in drivers on select()s * with EAGAIN too. */ - select_unsuspend_by_proc(proc); + select_unsuspend_by_endpt(proc_e); return; } @@ -259,7 +264,7 @@ int count; /* max number of processes to release */ rp->fp_revived == NOT_REVIVING && (rp->fp_fd & BYTE) == call_nr && rp->fp_filp[rp->fp_fd>>8]->filp_ino == ip) { - revive((int)(rp - fproc), 0); + revive(rp->fp_endpoint, 0); susp_count--; /* keep track of who is suspended */ if (--count == 0) return; } @@ -269,8 +274,8 @@ int count; /* max number of processes to release */ /*===========================================================================* * revive * *===========================================================================*/ -PUBLIC void revive(proc_nr, returned) -int proc_nr; /* process to revive */ +PUBLIC void revive(proc_nr_e, returned) +int proc_nr_e; /* process to revive */ int returned; /* if hanging on task, how many bytes read */ { /* Revive a previously blocked process. When a process hangs on tty, this @@ -279,9 +284,11 @@ int returned; /* if hanging on task, how many bytes read */ register struct fproc *rfp; register int task; + int proc_nr; + + if(isokendpt(proc_nr_e, &proc_nr) != OK) + return; - if (proc_nr < 0 || proc_nr >= NR_PROCS) - panic(__FILE__,"revive err", proc_nr); rfp = &fproc[proc_nr]; if (rfp->fp_suspended == NOT_SUSPENDED || rfp->fp_revived == REVIVING)return; @@ -298,13 +305,13 @@ int returned; /* if hanging on task, how many bytes read */ } else { rfp->fp_suspended = NOT_SUSPENDED; if (task == XPOPEN) /* process blocked in open or create */ - reply(proc_nr, rfp->fp_fd>>8); + reply(proc_nr_e, rfp->fp_fd>>8); else if (task == XSELECT) { - reply(proc_nr, returned); + reply(proc_nr_e, returned); } else { /* Revive a process suspended on TTY or other device. */ rfp->fp_nbytes = returned; /*pretend it wants only what there is*/ - reply(proc_nr, returned); /* unblock the process */ + reply(proc_nr_e, returned); /* unblock the process */ } } } @@ -319,16 +326,15 @@ PUBLIC int do_unpause() */ register struct fproc *rfp; - int proc_nr, task, fild; + int proc_nr_e, proc_nr_p, task, fild; struct filp *f; dev_t dev; message mess; - if (who > PM_PROC_NR) return(EPERM); - proc_nr = m_in.pro; - if (proc_nr < 0 || proc_nr >= NR_PROCS) - panic(__FILE__,"unpause err 1", proc_nr); - rfp = &fproc[proc_nr]; + if (who_e != PM_PROC_NR) return(EPERM); + proc_nr_e = m_in.ENDPT; + okendpt(proc_nr_e, &proc_nr_p); + rfp = &fproc[proc_nr_p]; if (rfp->fp_suspended == NOT_SUSPENDED) return(OK); task = -rfp->fp_task; @@ -340,7 +346,7 @@ PUBLIC int do_unpause() break; case XSELECT: /* process blocking on select() */ - select_forget(proc_nr); + select_forget(proc_nr_e); break; case XPOPEN: /* process trying to open a fifo */ @@ -353,7 +359,7 @@ PUBLIC int do_unpause() f = rfp->fp_filp[fild]; dev = (dev_t) f->filp_ino->i_zone[0]; /* device hung on */ mess.TTY_LINE = (dev >> MINOR) & BYTE; - mess.PROC_NR = proc_nr; + mess.IO_ENDPT = proc_nr_e; /* Tell kernel R or W. Mode is from current call, not open. */ mess.COUNT = (rfp->fp_fd & BYTE) == READ ? R_BIT : W_BIT; @@ -363,7 +369,7 @@ PUBLIC int do_unpause() } rfp->fp_suspended = NOT_SUSPENDED; - reply(proc_nr, EINTR); /* signal interrupted call */ + reply(proc_nr_e, EINTR); /* signal interrupted call */ return(OK); } diff --git a/servers/fs/proto.h b/servers/fs/proto.h index d4e17b139..cb49b200f 100644 --- a/servers/fs/proto.h +++ b/servers/fs/proto.h @@ -52,8 +52,8 @@ _PROTOTYPE( int do_devctl, (void) ); _PROTOTYPE( void build_dmap, (void) ); _PROTOTYPE( int map_driver, (int major, int proc_nr, int dev_style) ); _PROTOTYPE( int dmap_driver_match, (int proc, int major) ); -_PROTOTYPE( void dmap_unmap_by_proc, (int proc_nr) ); -_PROTOTYPE( void dmap_proc_up, (int proc_nr) ); +_PROTOTYPE( void dmap_unmap_by_endpt, (int proc_nr) ); +_PROTOTYPE( void dmap_endpt_up, (int proc_nr) ); /* filedes.c */ _PROTOTYPE( struct filp *find_filp, (struct inode *rip, mode_t bits) ); @@ -135,7 +135,7 @@ _PROTOTYPE( void suspend, (int task) ); _PROTOTYPE( int select_request_pipe, (struct filp *f, int *ops, int bl) ); _PROTOTYPE( int select_cancel_pipe, (struct filp *f) ); _PROTOTYPE( int select_match_pipe, (struct filp *f) ); -_PROTOTYPE( void unsuspend_by_proc, (int) ); +_PROTOTYPE( void unsuspend_by_endpt, (int) ); /* protect.c */ _PROTOTYPE( int do_access, (void) ); @@ -183,8 +183,12 @@ _PROTOTYPE( unsigned conv2, (int norm, int w) ); _PROTOTYPE( long conv4, (int norm, long x) ); _PROTOTYPE( int fetch_name, (char *path, int len, int flag) ); _PROTOTYPE( int no_sys, (void) ); +_PROTOTYPE( int isokendpt_f, (char *f, int l, int e, int *p, int ft)); _PROTOTYPE( void panic, (char *who, char *mess, int num) ); +#define okendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 1) +#define isokendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 0) + /* write.c */ _PROTOTYPE( void clear_zone, (struct inode *rip, off_t pos, int flag) ); _PROTOTYPE( int do_write, (void) ); @@ -198,7 +202,7 @@ _PROTOTYPE( int select_callback, (struct filp *, int ops) ); _PROTOTYPE( void select_forget, (int fproc) ); _PROTOTYPE( void select_timeout_check, (timer_t *) ); _PROTOTYPE( void init_select, (void) ); -_PROTOTYPE( void select_unsuspend_by_proc, (int proc) ); +_PROTOTYPE( void select_unsuspend_by_endpt, (int proc) ); _PROTOTYPE( int select_notified, (int major, int minor, int ops) ); /* timers.c */ diff --git a/servers/fs/read.c b/servers/fs/read.c index 9e446528b..1f73c8449 100644 --- a/servers/fs/read.c +++ b/servers/fs/read.c @@ -13,6 +13,7 @@ #include "fs.h" #include +#include #include #include "buf.h" #include "file.h" @@ -53,20 +54,15 @@ int rw_flag; /* READING or WRITING */ int completed, r2 = OK; phys_bytes p; - /* left unfinished rw_chunk()s from previous call! this can't happen. - * it means something has gone wrong we can't repair now. + /* PM loads segments by putting funny things in other bits of the + * message, indicated by a high bit in fd. */ - if (bufs_in_use < 0) { - panic(__FILE__,"start - bufs_in_use negative", bufs_in_use); - } - - /* MM loads segments by putting funny things in upper 10 bits of 'fd'. */ - if (who == PM_PROC_NR && (m_in.fd & (~BYTE)) ) { - usr = m_in.fd >> 7; - seg = (m_in.fd >> 5) & 03; - m_in.fd &= 037; /* get rid of user and segment bits */ + if (who_e == PM_PROC_NR && (m_in.fd & _PM_SEG_FLAG)) { + seg = (int) m_in.m1_p2; + usr = (int) m_in.m1_p3; + m_in.fd &= ~(_PM_SEG_FLAG); /* get rid of flag bit */ } else { - usr = who; /* normal case */ + usr = who_e; /* normal case */ seg = D; } @@ -83,8 +79,10 @@ int rw_flag; /* READING or WRITING */ * if not, copying will fail later. * do this after 0-check above because umap doesn't want to map 0 bytes. */ - if ((r = sys_umap(usr, seg, (vir_bytes) m_in.buffer, m_in.nbytes, &p)) != OK) + if ((r = sys_umap(usr, seg, (vir_bytes) m_in.buffer, m_in.nbytes, &p)) != OK) { + printf("FS: read_write: umap failed for process %d\n", usr); return r; + } position = f->filp_pos; oflags = f->filp_flags; rip = f->filp_ino; @@ -240,9 +238,6 @@ int rw_flag; /* READING or WRITING */ fp->fp_cum_io_partial = 0; return(cum_io); } - if (bufs_in_use < 0) { - panic(__FILE__,"end - bufs_in_use negative", bufs_in_use); - } return(r); } diff --git a/servers/fs/select.c b/servers/fs/select.c index 34e86335b..ac8f81482 100644 --- a/servers/fs/select.c +++ b/servers/fs/select.c @@ -4,7 +4,7 @@ * do_select: perform the SELECT system call * select_callback: notify select system of possible fd operation * select_notified: low-level entry for device notifying select - * select_unsuspend_by_proc: cancel a blocking select on exiting driver + * select_unsuspend_by_endpt: cancel a blocking select on exiting driver * * Changes: * 6 june 2005 Created (Ben Gras) @@ -27,7 +27,7 @@ PRIVATE struct selectentry { struct fproc *requestor; /* slot is free iff this is NULL */ - int req_procnr; + int req_endpt; fd_set readfds, writefds, errorfds; fd_set ready_readfds, ready_writefds, ready_errorfds; fd_set *vir_readfds, *vir_writefds, *vir_errorfds; @@ -176,13 +176,13 @@ PRIVATE void copy_fdsets(struct selectentry *e) { if (e->vir_readfds) sys_vircopy(SELF, D, (vir_bytes) &e->ready_readfds, - e->req_procnr, D, (vir_bytes) e->vir_readfds, sizeof(fd_set)); + e->req_endpt, D, (vir_bytes) e->vir_readfds, sizeof(fd_set)); if (e->vir_writefds) sys_vircopy(SELF, D, (vir_bytes) &e->ready_writefds, - e->req_procnr, D, (vir_bytes) e->vir_writefds, sizeof(fd_set)); + e->req_endpt, D, (vir_bytes) e->vir_writefds, sizeof(fd_set)); if (e->vir_errorfds) sys_vircopy(SELF, D, (vir_bytes) &e->ready_errorfds, - e->req_procnr, D, (vir_bytes) e->vir_errorfds, sizeof(fd_set)); + e->req_endpt, D, (vir_bytes) e->vir_errorfds, sizeof(fd_set)); return; } @@ -207,7 +207,7 @@ PUBLIC int do_select(void) if (s >= MAXSELECTS) return ENOSPC; - selecttab[s].req_procnr = who; + selecttab[s].req_endpt = who_e; selecttab[s].nfds = 0; selecttab[s].nreadyfds = 0; memset(selecttab[s].filps, 0, sizeof(selecttab[s].filps)); @@ -226,24 +226,24 @@ PUBLIC int do_select(void) /* copy args */ if (selecttab[s].vir_readfds - && (r=sys_vircopy(who, D, (vir_bytes) m_in.SEL_READFDS, + && (r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_READFDS, SELF, D, (vir_bytes) &selecttab[s].readfds, sizeof(fd_set))) != OK) return r; if (selecttab[s].vir_writefds - && (r=sys_vircopy(who, D, (vir_bytes) m_in.SEL_WRITEFDS, + && (r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_WRITEFDS, SELF, D, (vir_bytes) &selecttab[s].writefds, sizeof(fd_set))) != OK) return r; if (selecttab[s].vir_errorfds - && (r=sys_vircopy(who, D, (vir_bytes) m_in.SEL_ERRORFDS, + && (r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_ERRORFDS, SELF, D, (vir_bytes) &selecttab[s].errorfds, sizeof(fd_set))) != OK) return r; if (!m_in.SEL_TIMEOUT) is_timeout = nonzero_timeout = 0; else - if ((r=sys_vircopy(who, D, (vir_bytes) m_in.SEL_TIMEOUT, + if ((r=sys_vircopy(who_e, D, (vir_bytes) m_in.SEL_TIMEOUT, SELF, D, (vir_bytes) &timeout, sizeof(timeout))) != OK) return r; @@ -462,7 +462,7 @@ PRIVATE void select_cancel_all(struct selectentry *e) *===========================================================================*/ PRIVATE void select_wakeup(struct selectentry *e, int r) { - revive(e->req_procnr, r); + revive(e->req_endpt, r); } /*===========================================================================* @@ -612,7 +612,7 @@ PUBLIC void init_select(void) /*===========================================================================* * select_forget * *===========================================================================*/ -PUBLIC void select_forget(int proc) +PUBLIC void select_forget(int proc_e) { /* something has happened (e.g. signal delivered that interrupts * select()). totally forget about the select(). @@ -621,7 +621,7 @@ PUBLIC void select_forget(int proc) for(s = 0; s < MAXSELECTS; s++) { if (selecttab[s].requestor && - selecttab[s].req_procnr == proc) { + selecttab[s].req_endpt == proc_e) { break; } @@ -677,9 +677,9 @@ PUBLIC void select_timeout_check(timer_t *timer) } /*===========================================================================* - * select_unsuspend_by_proc * + * select_unsuspend_by_endpt * *===========================================================================*/ -PUBLIC void select_unsuspend_by_proc(int proc) +PUBLIC void select_unsuspend_by_endpt(int proc_e) { int fd, s; @@ -691,7 +691,7 @@ PUBLIC void select_unsuspend_by_proc(int proc) if (!selecttab[s].filps[fd] || !selecttab[s].filps[fd]->filp_ino) continue; maj = (selecttab[s].filps[fd]->filp_ino->i_zone[0] >> MAJOR)&BYTE; - if(dmap_driver_match(proc, maj)) { + if(dmap_driver_match(proc_e, maj)) { select_return(&selecttab[s], EAGAIN); } } diff --git a/servers/fs/stadir.c b/servers/fs/stadir.c index 0602a9d1f..6fa0bcbb9 100644 --- a/servers/fs/stadir.c +++ b/servers/fs/stadir.c @@ -55,8 +55,11 @@ PUBLIC int do_chdir() int r; register struct fproc *rfp; - if (who == PM_PROC_NR) { - rfp = &fproc[m_in.slot1]; + if (who_e == PM_PROC_NR) { + int slot; + if(isokendpt(m_in.endpt1, &slot) != OK) + return EINVAL; + rfp = &fproc[slot]; put_inode(fp->fp_rootdir); dup_inode(fp->fp_rootdir = rfp->fp_rootdir); put_inode(fp->fp_workdir); @@ -217,7 +220,7 @@ char *user_addr; /* user space address where stat buf goes */ /* Copy the struct to user space. */ r = sys_datacopy(FS_PROC_NR, (vir_bytes) &statbuf, - who, (vir_bytes) user_addr, (phys_bytes) sizeof(statbuf)); + who_e, (vir_bytes) user_addr, (phys_bytes) sizeof(statbuf)); return(r); } @@ -237,7 +240,7 @@ PUBLIC int do_fstatfs() st.f_bsize = rfilp->filp_ino->i_sp->s_block_size; r = sys_datacopy(FS_PROC_NR, (vir_bytes) &st, - who, (vir_bytes) m_in.buffer, (phys_bytes) sizeof(st)); + who_e, (vir_bytes) m_in.buffer, (phys_bytes) sizeof(st)); return(r); } @@ -283,7 +286,7 @@ PUBLIC int do_rdlink() else { bp = get_block(rip->i_dev, b, NORMAL); r = sys_vircopy(SELF, D, (vir_bytes) bp->b_data, - who, D, (vir_bytes) m_in.name2, (vir_bytes) rip->i_size); + who_e, D, (vir_bytes) m_in.name2, (vir_bytes) rip->i_size); if (r == OK) r = rip->i_size; put_block(bp, DIRECTORY_BLOCK); diff --git a/servers/fs/utility.c b/servers/fs/utility.c index bcf189f59..44c0279d9 100644 --- a/servers/fs/utility.c +++ b/servers/fs/utility.c @@ -12,6 +12,7 @@ #include "fs.h" #include +#include #include #include "buf.h" #include "file.h" @@ -72,7 +73,7 @@ int flag; /* M3 means path may be in message */ r = OK; } else { /* String is not contained in the message. Get it from user space. */ - r = sys_datacopy(who, (vir_bytes) path, + r = sys_datacopy(who_e, (vir_bytes) path, FS_PROC_NR, (vir_bytes) user_path, (phys_bytes) len); } return(r); @@ -138,3 +139,27 @@ long x; /* 32-bit long to be byte swapped */ return(l); } +/*===========================================================================* + * isokendpt_f * + *===========================================================================*/ +PUBLIC int isokendpt_f(char *file, int line, int endpoint, int *proc, int fatal) +{ + int failed = 0; + *proc = _ENDPOINT_P(endpoint); + if(*proc < 0 || *proc >= NR_PROCS) { + printf("FS:%s:%d: proc (%d) from endpoint (%d) out of range\n", + file, line, *proc, endpoint); + failed = 1; + } else if(fproc[*proc].fp_endpoint != endpoint) { + printf("FS:%s:%d: proc (%d) from endpoint (%d) doesn't match " + "known endpoint (%d)\n", + file, line, *proc, endpoint, fproc[*proc].fp_endpoint); + failed = 1; + } + + if(failed && fatal) + panic(__FILE__, "isokendpt_f failed", NO_NUM); + + return failed ? EDEADSRCDST : OK; +} + diff --git a/servers/inet/Makefile b/servers/inet/Makefile index a2cc1d5ee..25d80b13e 100644 --- a/servers/inet/Makefile +++ b/servers/inet/Makefile @@ -28,10 +28,8 @@ all: inet inet: $(OBJ) $(CC) -o $@ $(LDFLAGS) $(OBJ) version.c $(LIBS) -install: /usr/sbin/inet - -/usr/sbin/inet: inet - install -c $? $@ +install: inet + install -c $? /usr/sbin/inet clean: rm -f $(OBJ) inet *.bak diff --git a/servers/inet/sr.c b/servers/inet/sr.c index ed26b7433..e2c72ca51 100644 --- a/servers/inet/sr.c +++ b/servers/inet/sr.c @@ -66,7 +66,7 @@ #define NDEV_COUNT COUNT #define NDEV_IOCTL REQUEST #define NDEV_MINOR DEVICE -#define NDEV_PROC PROC_NR +#define NDEV_PROC IO_ENDPT #endif THIS_FILE @@ -141,7 +141,7 @@ mq_t *m; m->mq_mess.NDEV_REF, m->mq_mess.NDEV_OPERATION); #else /* Minix 3 */ - result= sr_repl_queue(m->mq_mess.PROC_NR, 0, 0); + result= sr_repl_queue(m->mq_mess.IO_ENDPT, 0, 0); #endif if (result) { @@ -567,7 +567,7 @@ message *m; sr_fd->srf_select_proc= m->m_source; - m_ops= m->PROC_NR; + m_ops= m->IO_ENDPT; i_ops= 0; if (m_ops & SEL_RD) i_ops |= SR_SELECT_READ; if (m_ops & SEL_WR) i_ops |= SR_SELECT_WRITE; @@ -733,7 +733,7 @@ int is_revive; mp= &reply; mp->m_type= DEVICE_REPLY; - mp->REP_PROC_NR= proc; + mp->REP_ENDPT= proc; mp->REP_STATUS= status; #ifdef __minix_vmd mp->REP_REF= ref; @@ -994,10 +994,10 @@ int size; cpvec[i].cpv_size= size; #else /* Minix 3 */ vir_cp_req[i].count= size; - vir_cp_req[i].src.proc_nr = proc; + vir_cp_req[i].src.proc_nr_e = proc; vir_cp_req[i].src.segment = D; vir_cp_req[i].src.offset = (vir_bytes) src; - vir_cp_req[i].dst.proc_nr = this_proc; + vir_cp_req[i].dst.proc_nr_e = this_proc; vir_cp_req[i].dst.segment = D; vir_cp_req[i].dst.offset = (vir_bytes) ptr2acc_data(acc); #endif @@ -1056,10 +1056,10 @@ char *dest; cpvec[i].cpv_dst= (vir_bytes)dest; cpvec[i].cpv_size= size; #else /* Minix 3 */ - vir_cp_req[i].src.proc_nr = this_proc; + vir_cp_req[i].src.proc_nr_e = this_proc; vir_cp_req[i].src.segment = D; vir_cp_req[i].src.offset= (vir_bytes)ptr2acc_data(acc); - vir_cp_req[i].dst.proc_nr = proc; + vir_cp_req[i].dst.proc_nr_e = proc; vir_cp_req[i].dst.segment = D; vir_cp_req[i].dst.offset= (vir_bytes)dest; vir_cp_req[i].count= size; @@ -1110,12 +1110,12 @@ int operation; for (m= repl_queue; m;) { #ifdef __minix_vmd - if (m->mq_mess.REP_PROC_NR == proc && + if (m->mq_mess.REP_ENDPT == proc && m->mq_mess.REP_REF ==ref && (m->mq_mess.REP_OPERATION == operation || operation == CANCEL_ANY)) #else /* Minix 3 */ - if (m->mq_mess.REP_PROC_NR == proc) + if (m->mq_mess.REP_ENDPT == proc) #endif { assert(!m_cancel); diff --git a/servers/is/Makefile b/servers/is/Makefile index 56f81bfb9..25d90001d 100644 --- a/servers/is/Makefile +++ b/servers/is/Makefile @@ -26,10 +26,8 @@ $(SERVER): $(OBJ) # install -S 256w $@ # install with other servers -install: /sbin/$(SERVER) -/sbin/$(SERVER): $(SERVER) - install -o root -c $? $@ -# install -o root -cs $? $@ +install: $(SERVER) + install -o root -c $? /sbin/$(SERVER) # clean up local files clean: diff --git a/servers/is/dmp_fs.c b/servers/is/dmp_fs.c index d4452ac2e..1d75ddb94 100644 --- a/servers/is/dmp_fs.c +++ b/servers/is/dmp_fs.c @@ -71,11 +71,11 @@ PUBLIC void dtab_dmp() getsysinfo(FS_PROC_NR, SI_DMAP_TAB, dmap); printf("File System (FS) device <-> driver mappings\n"); - printf("Major Proc Flags\n"); - printf("----- ---- -----\n"); + printf("Major Driver ept Flags\n"); + printf("----- ---------- -----\n"); for (i=0; i #include +#include #include "../../kernel/const.h" #include "../../kernel/config.h" #include "../../kernel/debug.h" @@ -175,11 +176,11 @@ PUBLIC void irqtab_dmp() for (i=0; iproc_nr==NONE) { + if (e->proc_nr_e==NONE) { printf(" \n"); continue; } - printf("%10d ", e->proc_nr); + printf("%10d ", e->proc_nr_e); printf(" %9.9s (%02d) ", irq[e->irq], e->irq); printf(" %s", (e->policy & IRQ_REENABLE) ? "reenable" : " - "); printf(" %d", e->notify_id); @@ -478,7 +479,7 @@ PUBLIC void proctab_dmp() return; } - printf("\n--nr-name---- -prior-quant- -user---sys- -text---data---size- -rts flags-\n"); + printf("\n-nr-----endpoint--name--- -prior-quant- -user---sys----size-rts flags-\n"); for (rp = oldrp; rp < END_PROC_ADDR; rp++) { if (isemptyp(rp)) continue; @@ -490,16 +491,16 @@ PUBLIC void proctab_dmp() if (proc_nr(rp) == IDLE) printf("(%2d) ", proc_nr(rp)); else if (proc_nr(rp) < 0) printf("[%2d] ", proc_nr(rp)); else printf(" %2d ", proc_nr(rp)); - printf(" %-8.8s %02u/%02u %02d/%02u %6lu%6lu %6uK%6uK%6uK %s", + printf(" %10d ", rp->p_endpoint); + printf(" %-8.8s %02u/%02u %02d/%02u %6lu%6lu %6uK %s", rp->p_name, rp->p_priority, rp->p_max_priority, rp->p_ticks_left, rp->p_quantum_size, rp->p_user_time, rp->p_sys_time, - click_to_round_k(text), click_to_round_k(data), click_to_round_k(size), p_rts_flags_str(rp->p_rts_flags)); if (rp->p_rts_flags & (SENDING|RECEIVING)) { - printf(" %-7.7s", proc_name(rp->p_getfrom)); + printf(" %-7.7s", proc_name(_ENDPOINT_P(rp->p_getfrom_e))); } printf("\n"); } diff --git a/servers/is/dmp_rs.c b/servers/is/dmp_rs.c index 4fd82ef08..03f82f1e4 100644 --- a/servers/is/dmp_rs.c +++ b/servers/is/dmp_rs.c @@ -31,8 +31,8 @@ PUBLIC void rproc_dmp() rp = &rproc[i]; if (! rp->r_flags & RS_IN_USE) continue; if (++n > 22) break; - printf("%3d %5d %s %3d/%2d %3u %8u %8u %3dx %3d %s (%d)", - rp->r_proc_nr, rp->r_pid, + printf("%9d %5d %s %3d/%2d %3u %8u %8u %3dx %3d %s (%d)", + 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, diff --git a/servers/is/glo.h b/servers/is/glo.h index 35277f248..718e0e3d0 100644 --- a/servers/is/glo.h +++ b/servers/is/glo.h @@ -12,7 +12,7 @@ extern int sys_panic; /* if set, shutdown can be done */ /* The parameters of the call are kept here. */ extern message m_in; /* the input message itself */ extern message m_out; /* the output message used for reply */ -extern int who; /* caller's proc number */ +extern int who_e; /* caller's proc number */ extern int callnr; /* system call number */ extern int dont_reply; /* normally 0; set to 1 to inhibit reply */ diff --git a/servers/is/main.c b/servers/is/main.c index 813355532..07ccea270 100644 --- a/servers/is/main.c +++ b/servers/is/main.c @@ -16,7 +16,7 @@ /* Allocate space for the global variables. */ message m_in; /* the input message itself */ message m_out; /* the output message used for reply */ -int who; /* caller's proc number */ +int who_e; /* caller's proc number */ int callnr; /* system call number */ int sys_panic; /* flag to indicate system-wide panic */ @@ -57,7 +57,7 @@ PUBLIC int main(int argc, char **argv) } continue; case PANIC_DUMPS: - printf("Oops ... panic in %d. ", who); + printf("Oops ... panic in %d. ", who_e); printf("Hit F-keys for debug dumps or F12 to shut down.\n"); sys_panic = TRUE; /* set flag to allow exit */ continue; @@ -74,7 +74,7 @@ PUBLIC int main(int argc, char **argv) /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { - reply(who, result); + reply(who_e, result); } } return(OK); /* shouldn't come here */ @@ -136,7 +136,7 @@ PRIVATE void get_work() status = receive(ANY, &m_in); /* this blocks until message arrives */ if (OK != status) panic("IS","failed to receive message!", status); - who = m_in.m_source; /* message arrived! set sender */ + who_e = m_in.m_source; /* message arrived! set sender */ callnr = m_in.m_type; /* set function call number */ } diff --git a/servers/pm/alloc.c b/servers/pm/alloc.c index 7f0bdbf1a..f81c2167e 100644 --- a/servers/pm/alloc.c +++ b/servers/pm/alloc.c @@ -277,7 +277,7 @@ u32_t offset, size; /* area on swap file to use */ if (swap_fd != -1) return(EBUSY); /* already have swap? */ - tell_fs(CHDIR, who, FALSE, 0); /* be like the caller for open() */ + tell_fs(CHDIR, who_e, FALSE, 0); /* be like the caller for open() */ if ((swap_fd = open(file, O_RDWR)) < 0) return(-errno); swap_offset = offset; size >>= CLICK_SHIFT; @@ -374,10 +374,10 @@ PUBLIC void swap_in() rmp->mp_seg[D].mem_phys = new_base; rmp->mp_seg[S].mem_phys = rmp->mp_seg[D].mem_phys + (rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir); - sys_newmap(proc_nr, rmp->mp_seg); + sys_newmap(rmp->mp_endpoint, rmp->mp_seg); off = swap_offset + ((off_t) (old_base-swap_base)<mp_endpoint, D, (phys_bytes)size << CLICK_SHIFT); free_mem(old_base, size); rmp->mp_flags &= ~(ONSWAP|SWAPIN); *pmp = rmp->mp_swapq; @@ -427,12 +427,12 @@ PRIVATE int swap_out() off = swap_offset + ((off_t) (new_base - swap_base) << CLICK_SHIFT); lseek(swap_fd, off, SEEK_SET); - rw_seg(1, swap_fd, proc_nr, D, (phys_bytes)size << CLICK_SHIFT); + rw_seg(1, swap_fd, rmp->mp_endpoint, D, (phys_bytes)size << CLICK_SHIFT); old_base = rmp->mp_seg[D].mem_phys; rmp->mp_seg[D].mem_phys = new_base; rmp->mp_seg[S].mem_phys = rmp->mp_seg[D].mem_phys + (rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir); - sys_newmap(proc_nr, rmp->mp_seg); + sys_newmap(rmp->mp_endpoint, rmp->mp_seg); free_mem(old_base, size); rmp->mp_flags |= ONSWAP; diff --git a/servers/pm/break.c b/servers/pm/break.c index a628fd281..b57aaa464 100644 --- a/servers/pm/break.c +++ b/servers/pm/break.c @@ -49,7 +49,7 @@ PUBLIC int do_brk() return(ENOMEM); } new_clicks -= rmp->mp_seg[D].mem_vir; - if ((r=get_stack_ptr(who, &new_sp)) != OK) /* ask kernel for sp value */ + if ((r=get_stack_ptr(who_e, &new_sp)) != OK) /* ask kernel for sp value */ panic(__FILE__,"couldn't get stack pointer", r); r = adjust(rmp, new_clicks, new_sp); rmp->mp_reply.reply_ptr = (r == OK ? m_in.addr : (char *) -1); @@ -121,7 +121,9 @@ vir_bytes sp; /* new value of sp */ rmp->mp_seg[S].mem_vir) ? ENOMEM : OK; #endif if (r == OK) { - if (changed) sys_newmap((int)(rmp - mproc), rmp->mp_seg); + int r2; + if (changed && (r2=sys_newmap(rmp->mp_endpoint, rmp->mp_seg)) != OK) + panic(__FILE__,"couldn't sys_newmap in adjust", r2); return(OK); } diff --git a/servers/pm/exec.c b/servers/pm/exec.c index b6d8dd10e..504d147c7 100644 --- a/servers/pm/exec.c +++ b/servers/pm/exec.c @@ -19,6 +19,7 @@ #include "pm.h" #include #include +#include #include #include #include @@ -53,7 +54,7 @@ PUBLIC int do_exec() */ register struct mproc *rmp; struct mproc *sh_mp; - int m, r, fd, ft, sn; + int m, r, r2, fd, ft, sn; static char mbuf[ARG_MAX]; /* buffer for stack and zeroes */ static char name_buf[PATH_MAX]; /* the name of the file to exec */ char *new_sp, *name, *basename; @@ -73,14 +74,14 @@ PUBLIC int do_exec() /* Get the exec file name and see if the file is executable. */ src = (vir_bytes) m_in.exec_name; dst = (vir_bytes) name_buf; - r = sys_datacopy(who, (vir_bytes) src, + r = sys_datacopy(who_e, (vir_bytes) src, PM_PROC_NR, (vir_bytes) dst, (phys_bytes) m_in.exec_len); if (r != OK) return(r); /* file name not in user data segment */ /* Fetch the stack from the user before destroying the old core image. */ src = (vir_bytes) m_in.stack_ptr; dst = (vir_bytes) mbuf; - r = sys_datacopy(who, (vir_bytes) src, + r = sys_datacopy(who_e, (vir_bytes) src, PM_PROC_NR, (vir_bytes) dst, (phys_bytes)stk_bytes); /* can't fetch stack (e.g. bad virtual addr) */ if (r != OK) return(EACCES); @@ -89,7 +90,7 @@ PUBLIC int do_exec() name = name_buf; /* name of file to exec. */ do { s_p = &s_buf[r]; - tell_fs(CHDIR, who, FALSE, 0); /* switch to the user's FS environ */ + tell_fs(CHDIR, who_e, FALSE, 0); /* switch to the user's FS environ */ fd = allowed(name, s_p, X_BIT); /* is file executable? */ if (fd < 0) return(fd); /* file was not executable */ @@ -128,16 +129,16 @@ PUBLIC int do_exec() patch_ptr(mbuf, vsp); src = (vir_bytes) mbuf; r = sys_datacopy(PM_PROC_NR, (vir_bytes) src, - who, (vir_bytes) vsp, (phys_bytes)stk_bytes); - if (r != OK) panic(__FILE__,"do_exec stack copy err on", who); + who_e, (vir_bytes) vsp, (phys_bytes)stk_bytes); + if (r != OK) panic(__FILE__,"do_exec stack copy err on", who_e); /* Read in text and data segments. */ if (sh_mp != NULL) { lseek(fd, (off_t) text_bytes, SEEK_CUR); /* shared: skip text */ } else { - rw_seg(0, fd, who, T, text_bytes); + rw_seg(0, fd, who_e, T, text_bytes); } - rw_seg(0, fd, who, D, data_bytes); + rw_seg(0, fd, who_e, D, data_bytes); close(fd); /* don't need exec file any more */ @@ -145,11 +146,11 @@ PUBLIC int do_exec() if ((rmp->mp_flags & TRACED) == 0) { /* suppress if tracing */ if (s_buf[0].st_mode & I_SET_UID_BIT) { rmp->mp_effuid = s_buf[0].st_uid; - tell_fs(SETUID,who, (int)rmp->mp_realuid, (int)rmp->mp_effuid); + tell_fs(SETUID, who_e, (int)rmp->mp_realuid, (int)rmp->mp_effuid); } if (s_buf[0].st_mode & I_SET_GID_BIT) { rmp->mp_effgid = s_buf[0].st_gid; - tell_fs(SETGID,who, (int)rmp->mp_realgid, (int)rmp->mp_effgid); + tell_fs(SETGID,who_e, (int)rmp->mp_realgid, (int)rmp->mp_effgid); } } @@ -169,14 +170,16 @@ PUBLIC int do_exec() rmp->mp_flags |= ft; /* turn it on for separate I & D files */ new_sp = (char *) vsp; - tell_fs(EXEC, who, 0, 0); /* allow FS to handle FD_CLOEXEC files */ + tell_fs(EXEC, who_e, 0, 0); /* allow FS to handle FD_CLOEXEC files */ /* System will save command line for debugging, ps(1) output, etc. */ basename = strrchr(name, '/'); if (basename == NULL) basename = name; else basename++; strncpy(rmp->mp_name, basename, PROC_NAME_LEN-1); rmp->mp_name[PROC_NAME_LEN] = '\0'; - sys_exec(who, new_sp, basename, pc); + if((r2=sys_exec(who_e, new_sp, basename, pc)) != OK) { + panic(__FILE__,"sys_exec failed", r2); + } /* Cause a signal if this process is traced. */ if (rmp->mp_flags & TRACED) check_sig(rmp->mp_pid, SIGTRAP); @@ -304,7 +307,7 @@ phys_bytes tot_bytes; /* total memory to allocate, including gap */ vir_clicks text_clicks, data_clicks, gap_clicks, stack_clicks, tot_clicks; phys_clicks new_base; phys_bytes bytes, base, bss_offset; - int s; + int s, r2; /* No need to allocate text if it can be shared. */ if (sh_mp != NULL) text_bytes = 0; @@ -366,7 +369,10 @@ phys_bytes tot_bytes; /* total memory to allocate, including gap */ + rmp->mp_seg[D].mem_len + gap_clicks; #endif - sys_newmap(who, rmp->mp_seg); /* report new map to the kernel */ + if((r2=sys_newmap(who_e, rmp->mp_seg)) != OK) { + /* report new map to the kernel */ + panic(__FILE__,"sys_newmap failed", r2); + } /* The old memory may have been swapped out, but the new memory is real. */ rmp->mp_flags &= ~(WAITING|ONSWAP|SWAPIN); @@ -522,10 +528,10 @@ char *script; /* name of script to interpret */ /*===========================================================================* * rw_seg * *===========================================================================*/ -PUBLIC void rw_seg(rw, fd, proc, seg, seg_bytes0) +PUBLIC void rw_seg(rw, fd, proc_e, seg, seg_bytes0) int rw; /* 0 = read, 1 = write */ int fd; /* file descriptor to read from / write to */ -int proc; /* process number */ +int proc_e; /* process number (endpoint) */ int seg; /* T, D, or S */ phys_bytes seg_bytes0; /* how much is to be transferred? */ { @@ -545,21 +551,25 @@ phys_bytes seg_bytes0; /* how much is to be transferred? */ * partially initialized. */ - int new_fd, bytes, r; + int bytes, r, proc_n; char *ubuf_ptr; - struct mem_map *sp = &mproc[proc].mp_seg[seg]; + struct mem_map *sp; phys_bytes seg_bytes = seg_bytes0; - new_fd = (proc << 7) | (seg << 5) | fd; + if(pm_isokendpt(proc_e, &proc_n) != OK || proc_n < 0) + return; + + sp = &mproc[proc_n].mp_seg[seg]; + ubuf_ptr = (char *) ((vir_bytes) sp->mem_vir << CLICK_SHIFT); while (seg_bytes != 0) { #define PM_CHUNK_SIZE 8192 bytes = MIN((INT_MAX / PM_CHUNK_SIZE) * PM_CHUNK_SIZE, seg_bytes); - if (rw == 0) { - r = read(new_fd, ubuf_ptr, bytes); + if(!rw) { + r = _read_pm(fd, ubuf_ptr, bytes, seg, proc_e); } else { - r = write(new_fd, ubuf_ptr, bytes); + r = _write_pm(fd, ubuf_ptr, bytes, seg, proc_e); } if (r != bytes) break; ubuf_ptr += bytes; diff --git a/servers/pm/forkexit.c b/servers/pm/forkexit.c index 2e4cff377..796e2f925 100644 --- a/servers/pm/forkexit.c +++ b/servers/pm/forkexit.c @@ -37,6 +37,8 @@ PUBLIC int do_fork() phys_clicks prog_clicks, child_base; phys_bytes prog_bytes, parent_abs, child_abs; /* Intel only */ pid_t new_pid; + static int next_child; + int n = 0, r; /* If tables might fill up during FORK, don't even start since recovery half * way through is such a nuisance. @@ -64,14 +66,22 @@ PUBLIC int do_fork() if (s < 0) panic(__FILE__,"do_fork can't copy", s); /* Find a slot in 'mproc' for the child process. A slot must exist. */ - for (rmc = &mproc[0]; rmc < &mproc[NR_PROCS]; rmc++) - if ( (rmc->mp_flags & IN_USE) == 0) break; + do { + next_child = (next_child+1) % NR_PROCS; + n++; + } while((mproc[next_child].mp_flags & IN_USE) && n <= NR_PROCS); + if(n > NR_PROCS) + panic(__FILE__,"do_fork can't find child slot", NO_NUM); + if(next_child < 0 || next_child >= NR_PROCS + || (mproc[next_child].mp_flags & IN_USE)) + panic(__FILE__,"do_fork finds wrong child slot", next_child); + rmc = &mproc[next_child]; /* Set up the child and its memory map; copy its 'mproc' slot from parent. */ child_nr = (int)(rmc - mproc); /* slot number of the child */ procs_in_use++; *rmc = *rmp; /* copy parent's process slot to child's */ - rmc->mp_parent = who; /* record child's parent */ + rmc->mp_parent = who_p; /* record child's parent */ /* inherit only these flags */ rmc->mp_flags &= (IN_USE|SEPARATE|PRIV_PROC|DONT_SWAP); rmc->mp_child_utime = 0; /* reset administration */ @@ -92,15 +102,20 @@ PUBLIC int do_fork() rmc->mp_pid = new_pid; /* assign pid to child */ /* Tell kernel and file system about the (now successful) FORK. */ - sys_fork(who, child_nr); - tell_fs(FORK, who, child_nr, rmc->mp_pid); + if((r=sys_fork(who_e, child_nr, &rmc->mp_endpoint)) != OK) { + panic(__FILE__,"do_fork can't sys_fork", r); + } + tell_fs(FORK, who_e, rmc->mp_endpoint, rmc->mp_pid); /* Report child's memory map to kernel. */ - sys_newmap(child_nr, rmc->mp_seg); + if((r=sys_newmap(rmc->mp_endpoint, rmc->mp_seg)) != OK) { + panic(__FILE__,"do_fork can't sys_newmap", r); + } /* Reply to child to wake it up. */ setreply(child_nr, 0); /* only parent gets details */ - rmp->mp_reply.procnr = child_nr; /* child's process number */ + rmp->mp_reply.endpt = rmc->mp_endpoint; /* child's process number */ + return(new_pid); /* child's pid */ } @@ -127,29 +142,33 @@ int exit_status; /* the process' exit status (for parent) */ * parent is waiting, release the rest, else keep the process slot and * become a zombie. */ - register int proc_nr; - int parent_waiting, right_child; + register int proc_nr, proc_nr_e; + int parent_waiting, right_child, r; pid_t pidarg, procgrp; struct mproc *p_mp; clock_t t[5]; proc_nr = (int) (rmp - mproc); /* get process slot number */ + proc_nr_e = rmp->mp_endpoint; /* Remember a session leader's process group. */ procgrp = (rmp->mp_pid == mp->mp_procgrp) ? mp->mp_procgrp : 0; /* If the exited process has a timer pending, kill it. */ - if (rmp->mp_flags & ALARM_ON) set_alarm(proc_nr, (unsigned) 0); + if (rmp->mp_flags & ALARM_ON) set_alarm(proc_nr_e, (unsigned) 0); /* Do accounting: fetch usage times and accumulate at parent. */ - sys_times(proc_nr, t); + if((r=sys_times(proc_nr_e, t)) != OK) + panic(__FILE__,"pm_exit: sys_times failed", r); + p_mp = &mproc[rmp->mp_parent]; /* process' parent */ p_mp->mp_child_utime += t[0] + rmp->mp_child_utime; /* add user time */ p_mp->mp_child_stime += t[1] + rmp->mp_child_stime; /* add system time */ /* Tell the kernel and FS that the process is no longer runnable. */ - tell_fs(EXIT, proc_nr, 0, 0); /* file system can free the proc slot */ - sys_exit(proc_nr); + tell_fs(EXIT, proc_nr_e, 0, 0); /* file system can free the proc slot */ + if((r=sys_exit(proc_nr_e)) != OK) + panic(__FILE__,"pm_exit: sys_exit failed", r); /* Pending reply messages for the dead process cannot be delivered. */ rmp->mp_flags &= ~REPLY; @@ -222,7 +241,7 @@ PUBLIC int do_waitpid() */ children = 0; for (rp = &mproc[0]; rp < &mproc[NR_PROCS]; rp++) { - if ( (rp->mp_flags & IN_USE) && rp->mp_parent == who) { + if ( (rp->mp_flags & IN_USE) && rp->mp_parent == who_p) { /* The value of pidarg determines which children qualify. */ if (pidarg > 0 && pidarg != rp->mp_pid) continue; if (pidarg < -1 && -pidarg != rp->mp_procgrp) continue; diff --git a/servers/pm/getset.c b/servers/pm/getset.c index d59bdb78d..5b0376ce6 100644 --- a/servers/pm/getset.c +++ b/servers/pm/getset.c @@ -6,6 +6,7 @@ #include "pm.h" #include +#include #include #include "mproc.h" #include "param.h" @@ -22,7 +23,7 @@ PUBLIC int do_getset() */ register struct mproc *rmp = mp; - register int r; + int r, proc; switch(call_nr) { case GETUID: @@ -36,10 +37,10 @@ PUBLIC int do_getset() break; case GETPID: - r = mproc[who].mp_pid; + r = mproc[who_p].mp_pid; rmp->mp_reply.reply_res2 = mproc[rmp->mp_parent].mp_pid; - if (m_in.procnr >= 0 && m_in.procnr < NR_PROCS) - rmp->mp_reply.reply_res3 = mproc[m_in.procnr].mp_pid; + if(pm_isokendpt(m_in.endpt, &proc) == OK && proc >= 0) + rmp->mp_reply.reply_res3 = mproc[proc].mp_pid; break; case SETEUID: @@ -49,7 +50,7 @@ PUBLIC int do_getset() return(EPERM); if(call_nr == SETUID) rmp->mp_realuid = (uid_t) m_in.usr_id; rmp->mp_effuid = (uid_t) m_in.usr_id; - tell_fs(SETUID, who, rmp->mp_realuid, rmp->mp_effuid); + tell_fs(SETUID, who_e, rmp->mp_realuid, rmp->mp_effuid); r = OK; break; @@ -60,14 +61,14 @@ PUBLIC int do_getset() return(EPERM); if(call_nr == SETGID) rmp->mp_realgid = (gid_t) m_in.grp_id; rmp->mp_effgid = (gid_t) m_in.grp_id; - tell_fs(SETGID, who, rmp->mp_realgid, rmp->mp_effgid); + tell_fs(SETGID, who_e, rmp->mp_realgid, rmp->mp_effgid); r = OK; break; case SETSID: if (rmp->mp_procgrp == rmp->mp_pid) return(EPERM); rmp->mp_procgrp = rmp->mp_pid; - tell_fs(SETSID, who, 0, 0); + tell_fs(SETSID, who_e, 0, 0); /* fall through */ case GETPGRP: diff --git a/servers/pm/glo.h b/servers/pm/glo.h index 716b26741..6947b12b6 100644 --- a/servers/pm/glo.h +++ b/servers/pm/glo.h @@ -12,7 +12,7 @@ EXTERN struct kinfo kinfo; /* kernel information */ /* The parameters of the call are kept here. */ EXTERN message m_in; /* the incoming message itself is kept here. */ -EXTERN int who; /* caller's proc number */ +EXTERN int who_p, who_e; /* caller's proc number, endpoint */ EXTERN int call_nr; /* system call number */ extern _PROTOTYPE (int (*call_vec[]), (void) ); /* system call handlers */ diff --git a/servers/pm/main.c b/servers/pm/main.c index 471be3867..77a0040d7 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -59,18 +60,27 @@ PUBLIC int main() result = SUSPEND; /* don't reply */ } else if (call_nr == SYS_SIG) { /* signals pending */ sigset = m_in.NOTIFY_ARG; - if (sigismember(&sigset, SIGKSIG)) (void) ksig_pending(); + if (sigismember(&sigset, SIGKSIG)) { + (void) ksig_pending(); + } result = SUSPEND; /* don't reply */ } /* Else, if the system call number is valid, perform the call. */ else if ((unsigned) call_nr >= NCALLS) { result = ENOSYS; } else { +#if 0 + printf("[pm: %s %d %d %d ", + who_p >= 0 ? mproc[who_p].mp_name : "?", who_e, who_p, call_nr); +#endif result = (*call_vec[call_nr])(); +#if 0 + printf(" %d] ", result); +#endif } /* Send the results back to the user to indicate completion. */ - if (result != SUSPEND) setreply(who, result); + if (result != SUSPEND) setreply(who_p, result); swap_in(); /* maybe a process can be swapped in? */ @@ -85,8 +95,9 @@ PUBLIC int main() */ if ((rmp->mp_flags & (REPLY | ONSWAP | IN_USE | ZOMBIE)) == (REPLY | IN_USE)) { - if ((s=send(proc_nr, &rmp->mp_reply)) != OK) { - panic(__FILE__,"PM can't reply to", proc_nr); + if ((s=send(rmp->mp_endpoint, &rmp->mp_reply)) != OK) { + panic(__FILE__,"PM can't reply to", + rmp->mp_endpoint); } rmp->mp_flags &= ~REPLY; } @@ -101,15 +112,22 @@ PUBLIC int main() PRIVATE void get_work() { /* Wait for the next message and extract useful information from it. */ - if (receive(ANY, &m_in) != OK) panic(__FILE__,"PM receive error", NO_NUM); - who = m_in.m_source; /* who sent the message */ + if (receive(ANY, &m_in) != OK) + panic(__FILE__,"PM 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 < 0 ? PM_PROC_NR : who]; + 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); + } } /*===========================================================================* @@ -125,6 +143,9 @@ int result; /* result of call (usually OK or error #) */ */ 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 */ @@ -230,6 +251,9 @@ PRIVATE void pm_init() #endif } + /* Get kernel endpoint identifier. */ + rmp->mp_endpoint = ip->endpoint; + /* Get memory map for this process from the kernel. */ if ((s=get_mem_map(ip->proc_nr, rmp->mp_seg)) != OK) panic(__FILE__,"couldn't get process entry",s); @@ -239,8 +263,9 @@ PRIVATE void pm_init() patch_mem_chunks(mem_chunks, rmp->mp_seg); /* Tell FS about this system process. */ - mess.PR_PROC_NR = ip->proc_nr; + mess.PR_SLOT = ip->proc_nr; mess.PR_PID = rmp->mp_pid; + mess.PR_ENDPT = rmp->mp_endpoint; if (OK != (s=send(FS_PROC_NR, &mess))) panic(__FILE__,"can't sync up with FS", s); printf(" %s", ip->proc_name); /* display process name */ @@ -256,7 +281,7 @@ PRIVATE void pm_init() sigfillset(&mproc[TTY_PROC_NR].mp_sig2mess); /* forward signals */ /* Tell FS that no more system processes follow and synchronize. */ - mess.PR_PROC_NR = NONE; + mess.PR_ENDPT = NONE; if (sendrec(FS_PROC_NR, &mess) != OK || mess.m_type != OK) panic(__FILE__,"can't sync up with FS", NO_NUM); diff --git a/servers/pm/misc.c b/servers/pm/misc.c index a9fbbe78a..a79e1ad43 100644 --- a/servers/pm/misc.c +++ b/servers/pm/misc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "mproc.h" #include "param.h" @@ -98,7 +99,7 @@ PUBLIC int do_getsysinfo() } dst_addr = (vir_bytes) m_in.info_where; - if (OK != (s=sys_datacopy(SELF, src_addr, who, dst_addr, len))) + if (OK != (s=sys_datacopy(SELF, src_addr, who_e, dst_addr, len))) return(s); return(OK); } @@ -116,29 +117,30 @@ PUBLIC int do_getprocnr() if (m_in.pid >= 0) { /* lookup process by pid */ for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) { if ((rmp->mp_flags & IN_USE) && (rmp->mp_pid==m_in.pid)) { - mp->mp_reply.procnr = (int) (rmp - mproc); + mp->mp_reply.endpt = rmp->mp_endpoint; return(OK); } } return(ESRCH); } else if (m_in.namelen > 0) { /* lookup process by name */ key_len = MIN(m_in.namelen, PROC_NAME_LEN); - if (OK != (s=sys_datacopy(who, (vir_bytes) m_in.addr, + if (OK != (s=sys_datacopy(who_e, (vir_bytes) m_in.addr, SELF, (vir_bytes) search_key, key_len))) return(s); search_key[key_len] = '\0'; /* terminate for safety */ for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) { if (((rmp->mp_flags & (IN_USE | ZOMBIE)) == IN_USE) && strncmp(rmp->mp_name, search_key, key_len)==0) { - mp->mp_reply.procnr = (int) (rmp - mproc); + mp->mp_reply.endpt = rmp->mp_endpoint; return(OK); } } return(ESRCH); - } else { /* return own/parent process number */ - mp->mp_reply.procnr = who; - mp->mp_reply.pprocnr = mp->mp_parent; + } else { /* return own/parent process number */ + mp->mp_reply.endpt = who_e; + mp->mp_reply.pendpt = mproc[mp->mp_parent].mp_endpoint; } + return(OK); } @@ -168,7 +170,7 @@ PUBLIC int do_reboot() case RBT_MONITOR: code_len = m_in.reboot_strlen + 1; if (code_len > sizeof(monitor_code)) return(EINVAL); - if (sys_datacopy(who, (vir_bytes) m_in.reboot_code, + if (sys_datacopy(who_e, (vir_bytes) m_in.reboot_code, PM_PROC_NR, (vir_bytes) monitor_code, (phys_bytes) (code_len)) != OK) return(EFAULT); if (monitor_code[code_len-1] != 0) return(EINVAL); @@ -213,7 +215,7 @@ PUBLIC int do_getsetpriority() return(EINVAL); if (arg_who == 0) - rmp_nr = who; + rmp_nr = who_p; else if ((rmp_nr = proc_from_pid(arg_who)) < 0) return(ESRCH); @@ -269,7 +271,7 @@ PUBLIC int do_svrctl() size_t copy_len; /* Copy sysgetenv structure to PM. */ - if (sys_datacopy(who, ptr, SELF, (vir_bytes) &sysgetenv, + if (sys_datacopy(who_e, ptr, SELF, (vir_bytes) &sysgetenv, sizeof(sysgetenv)) != OK) return(EFAULT); /* Set a param override? */ @@ -283,11 +285,11 @@ PUBLIC int do_svrctl() sizeof(local_param_overrides[local_params].value)) return EINVAL; - if ((s = sys_datacopy(who, (vir_bytes) sysgetenv.key, + if ((s = sys_datacopy(who_e, (vir_bytes) sysgetenv.key, SELF, (vir_bytes) local_param_overrides[local_params].name, sysgetenv.keylen)) != OK) return s; - if ((s = sys_datacopy(who, (vir_bytes) sysgetenv.val, + if ((s = sys_datacopy(who_e, (vir_bytes) sysgetenv.val, SELF, (vir_bytes) local_param_overrides[local_params].value, sysgetenv.keylen)) != OK) return s; @@ -307,7 +309,7 @@ PUBLIC int do_svrctl() int p; /* Try to get a copy of the requested key. */ if (sysgetenv.keylen > sizeof(search_key)) return(EINVAL); - if ((s = sys_datacopy(who, (vir_bytes) sysgetenv.key, + if ((s = sys_datacopy(who_e, (vir_bytes) sysgetenv.key, SELF, (vir_bytes) search_key, sysgetenv.keylen)) != OK) return(s); @@ -333,7 +335,7 @@ PUBLIC int do_svrctl() /* Value found, make the actual copy (as far as possible). */ copy_len = MIN(val_len, sysgetenv.vallen); if ((s=sys_datacopy(SELF, (vir_bytes) val_start, - who, (vir_bytes) sysgetenv.val, copy_len)) != OK) + who_e, (vir_bytes) sysgetenv.val, copy_len)) != OK) return(s); return OK; @@ -345,7 +347,7 @@ PUBLIC int do_svrctl() if (mp->mp_effuid != SUPER_USER) return(EPERM); - if (sys_datacopy(who, (phys_bytes) ptr, + if (sys_datacopy(who_e, (phys_bytes) ptr, PM_PROC_NR, (phys_bytes) &swapon, (phys_bytes) sizeof(swapon)) != OK) return(EFAULT); @@ -362,3 +364,43 @@ PUBLIC int do_svrctl() } } +/*===========================================================================* + * _read_pm * + *===========================================================================*/ +PUBLIC ssize_t _read_pm(fd, buffer, nbytes, seg, ep) +int fd; +void *buffer; +size_t nbytes; +int seg; +int ep; +{ + message m; + + m.m1_i1 = _PM_SEG_FLAG | fd; + m.m1_i2 = nbytes; + m.m1_p1 = (char *) buffer; + m.m1_p2 = (char *) seg; + m.m1_p3 = (char *) ep; + return(_syscall(FS_PROC_NR, READ, &m)); +} + +/*===========================================================================* + * _write_pm * + *===========================================================================*/ +PUBLIC ssize_t _write_pm(fd, buffer, nbytes, seg, ep) +int fd; +void *buffer; +size_t nbytes; +int seg; +int ep; +{ + message m; + + m.m1_i1 = _PM_SEG_FLAG | fd; + m.m1_i2 = nbytes; + m.m1_p1 = (char *) buffer; + m.m1_p2 = (char *) seg; + m.m1_p3 = (char *) ep; + return(_syscall(FS_PROC_NR, WRITE, &m)); +} + diff --git a/servers/pm/mproc.h b/servers/pm/mproc.h index 127547d37..eba3fef8a 100644 --- a/servers/pm/mproc.h +++ b/servers/pm/mproc.h @@ -11,6 +11,7 @@ EXTERN struct mproc { char mp_exitstatus; /* storage for status when process exits */ char mp_sigstatus; /* storage for signal # for killed procs */ pid_t mp_pid; /* process id */ + int mp_endpoint; /* kernel endpoint id */ pid_t mp_procgrp; /* pid of process group (used for signals) */ pid_t mp_wpid; /* pid this process is waiting for */ int mp_parent; /* index of parent process */ diff --git a/servers/pm/param.h b/servers/pm/param.h index dbcd9d36f..68a9b940b 100644 --- a/servers/pm/param.h +++ b/servers/pm/param.h @@ -6,8 +6,8 @@ #define grp_id m1_i1 #define namelen m1_i2 #define pid m1_i1 -#define procnr m1_i1 -#define pprocnr m1_i2 +#define endpt m1_i1 +#define pendpt m1_i2 #define seconds m1_i1 #define sig m6_i1 #define stack_bytes m1_i2 diff --git a/servers/pm/proto.h b/servers/pm/proto.h index 937bac846..6913e9d89 100644 --- a/servers/pm/proto.h +++ b/servers/pm/proto.h @@ -63,6 +63,9 @@ _PROTOTYPE( int do_svrctl, (void) ); _PROTOTYPE( int do_allocmem, (void) ); _PROTOTYPE( int do_freemem, (void) ); _PROTOTYPE( int do_getsetpriority, (void) ); +_PROTOTYPE( ssize_t _read_pm, (int _fd, void *_buf, size_t _n, int s, int e)); +_PROTOTYPE( ssize_t _write_pm, (int _fd, void *_buf, size_t _n, int s, int e)); + #if (MACHINE == MACINTOSH) _PROTOTYPE( phys_clicks start_click, (void) ); @@ -111,4 +114,5 @@ _PROTOTYPE( int get_stack_ptr, (int proc_nr, vir_bytes *sp) ); _PROTOTYPE( int get_mem_map, (int proc_nr, struct mem_map *mem_map) ); _PROTOTYPE( char *find_param, (const char *key)); _PROTOTYPE( int proc_from_pid, (pid_t p)); +_PROTOTYPE( int pm_isokendpt, (int ep, int *proc)); diff --git a/servers/pm/signal.c b/servers/pm/signal.c index 25534d8c4..5a51e5965 100644 --- a/servers/pm/signal.c +++ b/servers/pm/signal.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,7 @@ PUBLIC int do_sigaction() svp = &mp->mp_sigact[m_in.sig_nr]; if ((struct sigaction *) m_in.sig_osa != (struct sigaction *) NULL) { r = sys_datacopy(PM_PROC_NR,(vir_bytes) svp, - who, (vir_bytes) m_in.sig_osa, (phys_bytes) sizeof(svec)); + who_e, (vir_bytes) m_in.sig_osa, (phys_bytes) sizeof(svec)); if (r != OK) return(r); } @@ -61,7 +62,7 @@ PUBLIC int do_sigaction() return(OK); /* Read in the sigaction structure. */ - r = sys_datacopy(who, (vir_bytes) m_in.sig_nsa, + r = sys_datacopy(who_e, (vir_bytes) m_in.sig_nsa, PM_PROC_NR, (vir_bytes) &svec, (phys_bytes) sizeof(svec)); if (r != OK) return(r); @@ -183,7 +184,7 @@ PUBLIC int do_sigreturn() mp->mp_sigmask = (sigset_t) m_in.sig_set; sigdelset(&mp->mp_sigmask, SIGKILL); - r = sys_sigreturn(who, (struct sigmsg *) m_in.sig_context); + r = sys_sigreturn(who_e, (struct sigmsg *) m_in.sig_context); check_pending(mp); return(r); } @@ -213,16 +214,27 @@ PUBLIC int ksig_pending() * signals until all signals are handled. If there are no more signals, * NONE is returned in the process number field. */ - int proc_nr; + int proc_nr_e; sigset_t sig_map; while (TRUE) { - sys_getksig(&proc_nr, &sig_map); /* get an arbitrary pending signal */ - if (NONE == proc_nr) { /* stop if no more pending signals */ + int r; + /* get an arbitrary pending signal */ + if((r=sys_getksig(&proc_nr_e, &sig_map)) != OK) + panic(__FILE__,"sys_getksig failed", r); + if (NONE == proc_nr_e) { /* stop if no more pending signals */ break; } else { - handle_sig(proc_nr, sig_map); /* handle the received signal */ - sys_endksig(proc_nr); /* tell kernel it's done */ + int proc_nr_p; + if(pm_isokendpt(proc_nr_e, &proc_nr_p) != OK) + panic(__FILE__,"sys_getksig strange process", proc_nr_e); + handle_sig(proc_nr_e, sig_map); /* handle the received signal */ + /* If the process still exists to the kernel after the signal + * has been handled ... + */ + if ((mproc[proc_nr_p].mp_flags & (IN_USE | ZOMBIE)) == IN_USE) + if((r=sys_endksig(proc_nr_e)) != OK) /* ... tell kernel it's done */ + panic(__FILE__,"sys_endksig failed", r); } } return(SUSPEND); /* prevents sending reply */ @@ -231,16 +243,19 @@ PUBLIC int ksig_pending() /*===========================================================================* * handle_sig * *===========================================================================*/ -PRIVATE void handle_sig(proc_nr, sig_map) -int proc_nr; +PRIVATE void handle_sig(proc_nr_e, sig_map) +int proc_nr_e; sigset_t sig_map; { register struct mproc *rmp; - int i; + int i, proc_nr; pid_t proc_id, id; + if(pm_isokendpt(proc_nr_e, &proc_nr) != OK || proc_nr < 0) + return; rmp = &mproc[proc_nr]; - if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) return; + if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) + return; proc_id = rmp->mp_pid; mp = &mproc[0]; /* pretend signals are from PM */ mp->mp_procgrp = rmp->mp_procgrp; /* get process group right */ @@ -275,14 +290,14 @@ sigset_t sig_map; PUBLIC int do_alarm() { /* Perform the alarm(seconds) system call. */ - return(set_alarm(who, m_in.seconds)); + return(set_alarm(who_e, m_in.seconds)); } /*===========================================================================* * set_alarm * *===========================================================================*/ -PUBLIC int set_alarm(proc_nr, sec) -int proc_nr; /* process that wants the alarm */ +PUBLIC int set_alarm(proc_nr_e, sec) +int proc_nr_e; /* process that wants the alarm */ int sec; /* how many seconds delay before the signal */ { /* This routine is used by do_alarm() to set the alarm timer. It is also used @@ -293,12 +308,16 @@ int sec; /* how many seconds delay before the signal */ clock_t uptime; /* current system time */ int remaining; /* previous time left in seconds */ int s; + int proc_nr_n; + + if(pm_isokendpt(proc_nr_e, &proc_nr_n) != OK) + return EINVAL; /* First determine remaining time of previous alarm, if set. */ - if (mproc[proc_nr].mp_flags & ALARM_ON) { + if (mproc[proc_nr_n].mp_flags & ALARM_ON) { if ( (s=getuptime(&uptime)) != OK) panic(__FILE__,"set_alarm couldn't get uptime", s); - exptime = *tmr_exp_time(&mproc[proc_nr].mp_timer); + exptime = *tmr_exp_time(&mproc[proc_nr_n].mp_timer); remaining = (int) ((exptime - uptime + (HZ-1))/HZ); if (remaining < 0) remaining = 0; } else { @@ -326,11 +345,12 @@ int sec; /* how many seconds delay before the signal */ ticks = LONG_MAX; /* eternity (really TMR_NEVER) */ if (ticks != 0) { - pm_set_timer(&mproc[proc_nr].mp_timer, ticks, cause_sigalrm, proc_nr); - mproc[proc_nr].mp_flags |= ALARM_ON; - } else if (mproc[proc_nr].mp_flags & ALARM_ON) { - pm_cancel_timer(&mproc[proc_nr].mp_timer); - mproc[proc_nr].mp_flags &= ~ALARM_ON; + pm_set_timer(&mproc[proc_nr_n].mp_timer, ticks, + cause_sigalrm, proc_nr_e); + mproc[proc_nr_n].mp_flags |= ALARM_ON; + } else if (mproc[proc_nr_n].mp_flags & ALARM_ON) { + pm_cancel_timer(&mproc[proc_nr_n].mp_timer); + mproc[proc_nr_n].mp_flags &= ~ALARM_ON; } return(remaining); } @@ -341,11 +361,17 @@ int sec; /* how many seconds delay before the signal */ PRIVATE void cause_sigalrm(tp) struct timer *tp; { - int proc_nr; + int proc_nr_e, proc_nr_n; register struct mproc *rmp; - proc_nr = tmr_arg(tp)->ta_int; /* get process from timer */ - rmp = &mproc[proc_nr]; + /* get process from timer */ + if(pm_isokendpt(tmr_arg(tp)->ta_int, &proc_nr_n) != OK) { + printf("PM: ignoring timer for invalid enpoint %d\n", + tmr_arg(tp)->ta_int); + return; + } + + rmp = &mproc[proc_nr_n]; if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) return; if ((rmp->mp_flags & ALARM_ON) == 0) return; @@ -429,8 +455,8 @@ int signo; /* signal to send to process (1 to _NSIG) */ sm.sm_signo = signo; sm.sm_sighandler = (vir_bytes) rmp->mp_sigact[signo].sa_handler; sm.sm_sigreturn = rmp->mp_sigreturn; - if ((s=get_stack_ptr(slot, &new_sp)) != OK) - panic(__FILE__,"couldn't get new stack pointer",s); + if ((s=get_stack_ptr(rmp->mp_endpoint, &new_sp)) != OK) + panic(__FILE__,"couldn't get new stack pointer (for sig)",s); sm.sm_stkptr = new_sp; /* Make room for the sigcontext and sigframe struct. */ @@ -451,7 +477,7 @@ int signo; /* signal to send to process (1 to _NSIG) */ rmp->mp_sigact[signo].sa_handler = SIG_DFL; } - if (OK == (s=sys_sigsend(slot, &sm))) { + if (OK == (s=sys_sigsend(rmp->mp_endpoint, &sm))) { sigdelset(&rmp->mp_sigpending, signo); /* If process is hanging on PAUSE, WAIT, SIGSUSPEND, tty, @@ -460,10 +486,10 @@ int signo; /* signal to send to process (1 to _NSIG) */ unpause(slot); return; } - panic(__FILE__, "warning, sys_sigsend failed", s); + panic(__FILE__, "sys_sigsend failed", s); } else if (sigismember(&rmp->mp_sig2mess, signo)) { - if (OK != (s=sys_kill(slot,signo))) + if (OK != (s=sys_kill(rmp->mp_endpoint,signo))) panic(__FILE__, "warning, sys_kill failed", s); return; } @@ -483,7 +509,7 @@ doterminate: } #endif /* Switch to the user's FS environment and dump core. */ - tell_fs(CHDIR, slot, FALSE, 0); + tell_fs(CHDIR, rmp->mp_endpoint, FALSE, 0); dump_core(rmp); } pm_exit(rmp, 0); /* terminate process */ @@ -607,7 +633,7 @@ int pro; /* which process number */ } /* Process is not hanging on an PM call. Ask FS to take a look. */ - tell_fs(UNPAUSE, pro, 0, 0); + tell_fs(UNPAUSE, rmp->mp_endpoint, 0, 0); } /*===========================================================================* @@ -638,8 +664,8 @@ register struct mproc *rmp; /* whose core is to be dumped */ * the adjust() for sending a signal to fail due to safety checking. * Maybe make SAFETY_BYTES a parameter. */ - if ((s=get_stack_ptr(slot, ¤t_sp)) != OK) - panic(__FILE__,"couldn't get new stack pointer",s); + if ((s=get_stack_ptr(rmp->mp_endpoint, ¤t_sp)) != OK) + panic(__FILE__,"couldn't get new stack pointer (for core)",s); adjust(rmp, rmp->mp_seg[D].mem_len, current_sp); /* Write the memory map of all segments to begin the core file. */ @@ -651,7 +677,7 @@ register struct mproc *rmp; /* whose core is to be dumped */ /* Write out the whole kernel process table entry to get the regs. */ trace_off = 0; - while (sys_trace(T_GETUSER, slot, trace_off, &trace_data) == OK) { + while (sys_trace(T_GETUSER, rmp->mp_endpoint, trace_off, &trace_data) == OK) { if (write(fd, (char *) &trace_data, (unsigned) sizeof (long)) != (unsigned) sizeof (long)) { close(fd); @@ -662,7 +688,7 @@ register struct mproc *rmp; /* whose core is to be dumped */ /* Loop through segments and write the segments themselves out. */ for (seg = 0; seg < NR_LOCAL_SEGS; seg++) { - rw_seg(1, fd, slot, seg, + rw_seg(1, fd, rmp->mp_endpoint, seg, (phys_bytes) rmp->mp_seg[seg].mem_len << CLICK_SHIFT); } close(fd); diff --git a/servers/pm/time.c b/servers/pm/time.c index 58aa79a09..f05f1819f 100644 --- a/servers/pm/time.c +++ b/servers/pm/time.c @@ -71,7 +71,7 @@ PUBLIC int do_times() clock_t t[5]; int s; - if (OK != (s=sys_times(who, t))) + if (OK != (s=sys_times(who_e, t))) panic(__FILE__,"do_times couldn't get times", s); rmp->mp_reply.reply_t1 = t[0]; /* user time */ rmp->mp_reply.reply_t2 = t[1]; /* system time */ diff --git a/servers/pm/utility.c b/servers/pm/utility.c index 866db003b..c12425128 100644 --- a/servers/pm/utility.c +++ b/servers/pm/utility.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include /* needed only because mproc.h needs it */ #include "mproc.h" @@ -122,6 +123,7 @@ int num; /* number to go with it */ if (num != NO_NUM) printf(": %d",num); printf("\n"); +#if 0 /* Allow for debug dumps if the IS server is available. */ m.m_type = PANIC_DUMPS; if (OK == (s= nb_send(11, &m))) { @@ -129,6 +131,8 @@ int num; /* number to go with it */ } printf("Shutting down: IS is not answering: %d\n", s); sys_abort(RBT_PANIC); +#endif + sys_exit(SELF); } /*===========================================================================* @@ -199,14 +203,14 @@ struct mem_map *mem_map; /* put memory map here */ /*===========================================================================* * get_stack_ptr * *===========================================================================*/ -PUBLIC int get_stack_ptr(proc_nr, sp) -int proc_nr; /* process to get sp of */ +PUBLIC int get_stack_ptr(proc_nr_e, sp) +int proc_nr_e; /* process to get sp of */ vir_bytes *sp; /* put stack pointer here */ { struct proc p; int s; - if ((s=sys_getproc(&p, proc_nr)) != OK) + if ((s=sys_getproc(&p, proc_nr_e)) != OK) return(s); *sp = p.p_reg.sp; return(OK); @@ -227,3 +231,18 @@ pid_t mp_pid; return -1; } +/*===========================================================================* + * pm_isokendpt * + *===========================================================================*/ +PUBLIC int pm_isokendpt(int endpoint, int *proc) +{ + *proc = _ENDPOINT_P(endpoint); + if(*proc < -NR_TASKS || *proc >= NR_PROCS) + return EINVAL; + if(*proc >= 0 && endpoint != mproc[*proc].mp_endpoint) + return EDEADSRCDST; + if(*proc >= 0 && !(mproc[*proc].mp_flags & IN_USE)) + return EDEADSRCDST; + return OK; +} + diff --git a/servers/rs/main.c b/servers/rs/main.c index 93da27b34..fd1822652 100644 --- a/servers/rs/main.c +++ b/servers/rs/main.c @@ -9,6 +9,7 @@ */ #include "inc.h" #include +#include #include "../../kernel/const.h" #include "../../kernel/type.h" @@ -31,7 +32,7 @@ PUBLIC int main(void) * sending the reply. The loop never terminates, unless a panic occurs. */ message m; /* request message */ - int call_nr, who; /* call number and caller */ + int call_nr, who_e,who_p; /* call number and caller */ int result; /* result to return */ sigset_t sigset; /* system signal set */ int s; @@ -44,7 +45,11 @@ PUBLIC int main(void) /* Wait for request message. */ get_work(&m); - who = m.m_source; + who_e = m.m_source; + who_p = _ENDPOINT_P(who_e); + if(who_p < -NR_TASKS || who_p >= NR_PROCS) + panic("RS","message from bogus source", who_e); + call_nr = m.m_type; /* Now determine what to do. Three types of requests are expected: @@ -68,8 +73,8 @@ PUBLIC int main(void) if (sigismember(&sigset, SIGKSTOP)) do_shutdown(NULL); continue; default: /* heartbeat notification */ - if (rproc_ptr[who] != NULL) /* mark heartbeat time */ - rproc_ptr[who]->r_alive_tm = m.NOTIFY_TIMESTAMP; + if (rproc_ptr[who_p] != NULL) /* mark heartbeat time */ + rproc_ptr[who_p]->r_alive_tm = m.NOTIFY_TIMESTAMP; } } @@ -92,7 +97,7 @@ PUBLIC int main(void) /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { - reply(who, result); + reply(who_e, result); } } } @@ -134,7 +139,7 @@ PRIVATE void init_server(void) if (ip->proc_nr >= 0) { nr_in_use ++; rproc[s].r_flags = RS_IN_USE; - rproc[s].r_proc_nr = ip->proc_nr; + rproc[s].r_proc_nr_e = ip->endpoint; rproc[s].r_pid = getnpid(ip->proc_nr); for(t=0; t< NR_DEVICES; t++) if (dmap[t].dmap_driver == ip->proc_nr) diff --git a/servers/rs/manager.c b/servers/rs/manager.c index 0a6349c52..c5e0d5cf5 100644 --- a/servers/rs/manager.c +++ b/servers/rs/manager.c @@ -8,6 +8,7 @@ #include #include #include +#include /* Allocate variables. */ struct rproc rproc[NR_SYS_PROCS]; /* system process table */ @@ -191,7 +192,7 @@ PUBLIC void do_exit(message *m_ptr) while ( (exit_pid = waitpid(-1, &exit_status, WNOHANG)) != 0 ) { #if VERBOSE - printf("RS: proc %d, pid %d, ", rp->r_proc_nr, exit_pid); + printf("RS: proc %d, pid %d, ", rp->r_proc_nr_e, exit_pid); if (WIFSIGNALED(exit_status)) { printf("killed, signal number %d\n", WTERMSIG(exit_status)); } @@ -206,11 +207,11 @@ PUBLIC void do_exit(message *m_ptr) for (rp=BEG_RPROC_ADDR; rpr_flags & RS_IN_USE) && rp->r_pid == exit_pid) { - rproc_ptr[rp->r_proc_nr] = NULL; /* invalidate */ + rproc_ptr[rp->r_proc_nr_e] = NULL; /* invalidate */ if ((rp->r_flags & RS_EXITING) || shutting_down) { rp->r_flags = 0; /* release slot */ - rproc_ptr[rp->r_proc_nr] = NULL; + rproc_ptr[rp->r_proc_nr_e] = NULL; } else if(rp->r_flags & RS_REFRESHING) { rp->r_restarts = -1; /* reset counter */ @@ -289,7 +290,7 @@ message *m_ptr; if (now - rp->r_alive_tm > 2*rp->r_period && rp->r_pid > 0) { #if VERBOSE - printf("RS: service %d reported late\n", rp->r_proc_nr); + printf("RS: service %d reported late\n", rp->r_proc_nr_e); #endif kill(rp->r_pid, SIGKILL); /* simulate crash */ } @@ -300,9 +301,9 @@ message *m_ptr; */ else if (now - rp->r_check_tm > rp->r_period) { #if VERBOSE - printf("RS: status request sent to %d\n", rp->r_proc_nr); + printf("RS: status request sent to %d\n", rp->r_proc_nr_e); #endif - notify(rp->r_proc_nr); /* request status */ + notify(rp->r_proc_nr_e); /* request status */ rp->r_check_tm = now; /* mark time */ } } @@ -325,7 +326,7 @@ struct rproc *rp; * process will be inhibited from running by the NO_PRIV flag. Only let the * child run once its privileges have been set by the parent. */ - int child_proc_nr; /* child process slot */ + 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; @@ -350,7 +351,7 @@ struct rproc *rp; exit(EXEC_FAILED); /* terminate child */ default: /* parent process */ - child_proc_nr = getnprocnr(child_pid); /* get child slot */ + child_proc_nr_e = getnprocnr(child_pid); /* get child slot */ break; /* continue below */ } @@ -359,11 +360,11 @@ struct rproc *rp; * not yet set. First try to set the device driver mapping at the FS. */ if (rp->r_dev_nr > 0) { /* set driver map */ - if ((s=mapdriver(child_proc_nr, rp->r_dev_nr, rp->r_dev_style)) < 0) { + if ((s=mapdriver(child_proc_nr_e, rp->r_dev_nr, rp->r_dev_style)) < 0) { report("RS", "couldn't map driver", errno); + rp->r_flags |= RS_EXITING; /* expect exit */ if(child_pid > 0) kill(child_pid, SIGKILL); /* kill driver */ else report("RS", "didn't kill pid", child_pid); - rp->r_flags |= RS_EXITING; /* expect exit */ return(s); /* return error */ } } @@ -372,17 +373,18 @@ struct rproc *rp; * Now, set the privilege structure for the child process to let is run. * This should succeed: we tested number in use above. */ - if ((s = sys_privctl(child_proc_nr, SYS_PRIV_INIT, 0, NULL)) < 0) { + if ((s = sys_privctl(child_proc_nr_e, SYS_PRIV_INIT, 0, NULL)) < 0) { report("RS","call to SYSTEM failed", s); /* to let child run */ + rp->r_flags |= RS_EXITING; /* expect exit */ if(child_pid > 0) kill(child_pid, SIGKILL); /* kill driver */ else report("RS", "didn't kill pid", child_pid); - rp->r_flags |= RS_EXITING; /* expect exit */ return(s); /* return error */ } #if VERBOSE - printf("RS: started '%s', major %d, pid %d, proc_nr %d\n", - rp->r_cmd, rp->r_dev_nr, child_pid, child_proc_nr); + printf("RS: started '%s', major %d, pid %d, endpoint %d, proc %d\n", + rp->r_cmd, rp->r_dev_nr, child_pid, + child_proc_nr_e, child_proc_nr_n); #endif /* The system service now has been successfully started. Update the rest @@ -390,14 +392,15 @@ struct rproc *rp; * thing that can go wrong now, is that execution fails at the child. If * that's the case, the child will exit. */ + child_proc_nr_n = _ENDPOINT_P(child_proc_nr_e); rp->r_flags = RS_IN_USE; /* mark slot in use */ rp->r_restarts += 1; /* raise nr of restarts */ - rp->r_proc_nr = child_proc_nr; /* set child details */ + rp->r_proc_nr_e = child_proc_nr_e; /* set child details */ rp->r_pid = child_pid; rp->r_check_tm = 0; /* not check yet */ getuptime(&rp->r_alive_tm); /* currently alive */ rp->r_stop_tm = 0; /* not exiting yet */ - rproc_ptr[child_proc_nr] = rp; /* mapping for fast access */ + rproc_ptr[child_proc_nr_n] = rp; /* mapping for fast access */ return(OK); } diff --git a/servers/rs/manager.h b/servers/rs/manager.h index cf1bf74d5..520db4222 100644 --- a/servers/rs/manager.h +++ b/servers/rs/manager.h @@ -12,7 +12,7 @@ * the servers and drivers, and thus is not directly indexed by slot number. */ extern struct rproc { - int r_proc_nr; /* process slot number */ + int r_proc_nr_e; /* process endpoint number */ pid_t r_pid; /* process id */ dev_t r_dev_nr; /* major device number */ int r_dev_style; /* device style */