From 7967177710b79820b5c29dea31ba3d1b95ef3ded Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Fri, 3 Mar 2006 10:20:58 +0000 Subject: [PATCH] endpoint-aware conversion of servers. 'who', indicating caller number in pm and fs and some other servers, has been removed in favour of 'who_e' (endpoint) and 'who_p' (proc nr.). In both PM and FS, isokendpt() convert endpoints to process slot numbers, returning OK if it was a valid and consistent endpoint number. okendpt() does the same but panic()s if it doesn't succeed. (In PM, this is pm_isok..) pm and fs keep their own records of process endpoints in their proc tables, which are needed to make kernel calls about those processes. message field names have changed. fs drivers are endpoints. fs now doesn't try to get out of driver deadlock, as the protocol isn't supposed to let that happen any more. (A warning is printed if ELOCKED is detected though.) fproc[].fp_task (indicating which driver the process is suspended on) became an int. PM and FS now get endpoint numbers of initial boot processes from the kernel. These happen to be the same as the old proc numbers, to let user processes reach them with the old numbers, but FS and PM don't know that. All new processes after INIT, even after the generation number wraps around, get endpoint numbers with generation 1 and higher, so the first instances of the boot processes are the only processes ever to have endpoint numbers in the old proc number range. More return code checks of sys_* functions have been added. IS has become endpoint-aware. Ditched the 'text' and 'data' fields in the kernel dump (which show locations, not sizes, so aren't terribly useful) in favour of the endpoint number. Proc number is still visible. Some other dumps (e.g. dmap, rs) show endpoint numbers now too which got the formatting changed. PM reading segments using rw_seg() has changed - it uses other fields in the message now instead of encoding the segment and process number and fd in the fd field. For that it uses _read_pm() and _write_pm() which to _taskcall()s directly in pm/misc.c. PM now sys_exit()s itself on panic(), instead of sys_abort(). RS also talks in endpoints instead of process numbers. --- servers/ds/Makefile | 5 +- servers/ds/main.c | 12 ++-- servers/fs/device.c | 150 ++++++++++++++++++++++++++++------------ servers/fs/dmap.c | 28 ++++---- servers/fs/fproc.h | 3 +- servers/fs/glo.h | 2 +- servers/fs/lock.c | 6 +- servers/fs/main.c | 56 ++++++++++----- servers/fs/misc.c | 80 +++++++++++++-------- servers/fs/mount.c | 2 +- servers/fs/open.c | 4 +- servers/fs/param.h | 8 +-- servers/fs/pipe.c | 56 ++++++++------- servers/fs/proto.h | 12 ++-- servers/fs/read.c | 27 +++----- servers/fs/select.c | 32 ++++----- servers/fs/stadir.c | 13 ++-- servers/fs/utility.c | 27 +++++++- servers/inet/Makefile | 6 +- servers/inet/sr.c | 20 +++--- servers/is/Makefile | 6 +- servers/is/dmp_fs.c | 6 +- servers/is/dmp_kernel.c | 13 ++-- servers/is/dmp_rs.c | 4 +- servers/is/glo.h | 2 +- servers/is/main.c | 8 +-- servers/pm/alloc.c | 10 +-- servers/pm/break.c | 6 +- servers/pm/exec.c | 54 +++++++++------ servers/pm/forkexit.c | 49 +++++++++---- servers/pm/getset.c | 15 ++-- servers/pm/glo.h | 2 +- servers/pm/main.c | 43 +++++++++--- servers/pm/misc.c | 72 +++++++++++++++---- servers/pm/mproc.h | 1 + servers/pm/param.h | 4 +- servers/pm/proto.h | 4 ++ servers/pm/signal.c | 98 ++++++++++++++++---------- servers/pm/time.c | 2 +- servers/pm/utility.c | 25 ++++++- servers/rs/main.c | 17 +++-- servers/rs/manager.c | 35 +++++----- servers/rs/manager.h | 2 +- 43 files changed, 661 insertions(+), 366 deletions(-) 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 */ -- 2.44.0