Removed 'system process' magic from PM and FS.
This commit is contained in:
+9
-8
@@ -13,7 +13,7 @@ CC = exec cc
|
||||
CFLAGS = -I$i
|
||||
LDFLAGS = -i
|
||||
|
||||
OBJ = main.o forkexit.o break.o exec.o procutils.o \
|
||||
OBJ = main.o forkexit.o break.o exec.o dmp.o \
|
||||
signal.o alloc.o utility.o table.o trace.o getset.o misc.o
|
||||
|
||||
# build local binary
|
||||
@@ -32,7 +32,7 @@ clean:
|
||||
rm -f $(SERVER) *.o *.bak
|
||||
|
||||
# dependencies
|
||||
a = mm.h $h/config.h $s/types.h $h/const.h $h/type.h \
|
||||
a = pm.h $h/config.h $s/types.h $h/const.h $h/type.h \
|
||||
$i/ansi.h $i/fcntl.h $i/unistd.h $h/syslib.h \
|
||||
$i/limits.h $i/errno.h const.h type.h proto.h glo.h
|
||||
|
||||
@@ -94,12 +94,7 @@ misc.o: $s/svrctl.h
|
||||
misc.o: mproc.h
|
||||
misc.o: param.h
|
||||
|
||||
procutils.o: $a
|
||||
procutils.o: $i/timers.h
|
||||
procutils.o: $i/string.h
|
||||
procutils.o: $k/const.h
|
||||
procutils.o: $k/type.h
|
||||
procutils.o: $k/proc.h
|
||||
dmp.o: $a
|
||||
|
||||
signal.o: $a
|
||||
signal.o: $s/stat.h
|
||||
@@ -132,3 +127,9 @@ utility.o: $h/com.h
|
||||
utility.o: $i/fcntl.h
|
||||
utility.o: $i/signal.h
|
||||
utility.o: mproc.h
|
||||
utility.o: $i/timers.h
|
||||
utility.o: $i/string.h
|
||||
utility.o: $k/const.h
|
||||
utility.o: $k/type.h
|
||||
utility.o: $k/proc.h
|
||||
|
||||
|
||||
+11
-11
@@ -3,19 +3,19 @@
|
||||
* structure used is the hole table, which maintains a list of holes in memory.
|
||||
* It is kept sorted in order of increasing memory address. The addresses
|
||||
* it contains refers to physical memory, starting at absolute address 0
|
||||
* (i.e., they are not relative to the start of MM). During system
|
||||
* (i.e., they are not relative to the start of PM). During system
|
||||
* initialization, that part of memory containing the interrupt vectors,
|
||||
* kernel, and MM are "allocated" to mark them as not available and to
|
||||
* kernel, and PM are "allocated" to mark them as not available and to
|
||||
* remove them from the hole list.
|
||||
*
|
||||
* The entry points into this file are:
|
||||
* alloc_mem: allocate a given sized chunk of memory
|
||||
* free_mem: release a previously allocated chunk of memory
|
||||
* mem_init: initialize the tables when MM start up
|
||||
* mem_init: initialize the tables when PM start up
|
||||
* max_hole: returns the largest hole currently available
|
||||
*/
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <minix/com.h>
|
||||
#include <minix/callnr.h>
|
||||
#include <signal.h>
|
||||
@@ -40,7 +40,7 @@ PRIVATE u32_t swap_offset; /* offset to start of swap area on swap file */
|
||||
PRIVATE phys_clicks swap_base; /* memory offset chosen as swap base */
|
||||
PRIVATE phys_clicks swap_maxsize;/* maximum amount of swap "memory" possible */
|
||||
PRIVATE struct mproc *in_queue; /* queue of processes wanting to swap in */
|
||||
PRIVATE struct mproc *outswap = &mproc[LOW_USER]; /* outswap candidate? */
|
||||
PRIVATE struct mproc *outswap = &mproc[0]; /* outswap candidate? */
|
||||
#else /* !SWAP */
|
||||
#define swap_base ((phys_clicks) -1)
|
||||
#endif /* !SWAP */
|
||||
@@ -219,7 +219,7 @@ phys_clicks *free; /* memory size summaries */
|
||||
|
||||
/* Get a copy of the physical memory chunks found at the kernel. */
|
||||
if ((i=sys_getmemchunks(mem)) != OK)
|
||||
panic("MM couldn't get mem chunks",i);
|
||||
panic("PM couldn't get mem chunks",i);
|
||||
|
||||
/* Put all holes on the free list. */
|
||||
for (hp = &hole[0]; hp < &hole[NR_HOLES]; hp++) hp->h_next = hp + 1;
|
||||
@@ -281,13 +281,13 @@ PUBLIC int swap_off()
|
||||
if (swap_fd == -1) return(OK); /* can't turn off what isn't on */
|
||||
|
||||
/* Put all swapped out processes on the inswap queue and swap in. */
|
||||
for (rmp = &mproc[LOW_USER]; rmp < &mproc[NR_PROCS]; rmp++) {
|
||||
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
|
||||
if (rmp->mp_flags & ONSWAP) swap_inqueue(rmp);
|
||||
}
|
||||
swap_in();
|
||||
|
||||
/* All in memory? */
|
||||
for (rmp = &mproc[LOW_USER]; rmp < &mproc[NR_PROCS]; rmp++) {
|
||||
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
|
||||
if (rmp->mp_flags & ONSWAP) return(ENOMEM);
|
||||
}
|
||||
|
||||
@@ -375,7 +375,7 @@ PUBLIC void swap_in()
|
||||
PRIVATE int swap_out()
|
||||
{
|
||||
/* Try to find a process that can be swapped out. Candidates are those blocked
|
||||
* on a system call that MM handles, like wait(), pause() or sigsuspend().
|
||||
* on a system call that PM handles, like wait(), pause() or sigsuspend().
|
||||
*/
|
||||
struct mproc *rmp;
|
||||
struct hole *hp, *prev_ptr;
|
||||
@@ -385,13 +385,13 @@ PRIVATE int swap_out()
|
||||
|
||||
rmp = outswap;
|
||||
do {
|
||||
if (++rmp == &mproc[NR_PROCS]) rmp = &mproc[LOW_USER];
|
||||
if (++rmp == &mproc[NR_PROCS]) rmp = &mproc[0];
|
||||
|
||||
/* A candidate? */
|
||||
if (!(rmp->mp_flags & (PAUSED | WAITING | SIGSUSPENDED))) continue;
|
||||
|
||||
/* Already on swap or otherwise to be avoided? */
|
||||
if (rmp->mp_flags & (TRACED | REPLY | ONSWAP)) continue;
|
||||
if (rmp->mp_flags & (DONT_SWAP | TRACED | REPLY | ONSWAP)) continue;
|
||||
|
||||
/* Got one, find a swap hole and swap it out. */
|
||||
proc_nr = (rmp - mproc);
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@
|
||||
* size_ok: see if the segment sizes are feasible
|
||||
*/
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <signal.h>
|
||||
#include "mproc.h"
|
||||
#include "param.h"
|
||||
@@ -49,8 +49,8 @@ PUBLIC int do_brk()
|
||||
return(ENOMEM);
|
||||
}
|
||||
new_clicks -= rmp->mp_seg[D].mem_vir;
|
||||
if ((r=p_getsp(who, &new_sp)) != OK) /* ask kernel for current sp value */
|
||||
panic("MM couldn't get stack pointer", r);
|
||||
if ((r=get_stack_ptr(who, &new_sp)) != OK) /* ask kernel for sp value */
|
||||
panic("PM 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);
|
||||
return(r); /* return new address or -1 */
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* Constants used by the Memory Manager. */
|
||||
/* Constants used by the Process Manager. */
|
||||
|
||||
#define NO_MEM ((phys_clicks) 0) /* returned by alloc_mem() with mem is up */
|
||||
|
||||
|
||||
+14
-15
@@ -3,7 +3,7 @@
|
||||
* - read the header and extract the sizes
|
||||
* - fetch the initial args and environment from the user space
|
||||
* - allocate the memory for the new process
|
||||
* - copy the initial stack from MM to the process
|
||||
* - copy the initial stack from PM to the process
|
||||
* - read in the text and data segments and copy to the process
|
||||
* - take care of setuid and setgid bits
|
||||
* - fix up 'mproc' table
|
||||
@@ -16,7 +16,7 @@
|
||||
* find_share: find a process whose text segment can be shared
|
||||
*/
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <sys/stat.h>
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/com.h>
|
||||
@@ -49,9 +49,8 @@ PUBLIC int do_exec()
|
||||
{
|
||||
/* Perform the execve(name, argv, envp) call. The user library builds a
|
||||
* complete stack image, including pointers, args, environ, etc. The stack
|
||||
* is copied to a buffer inside MM, and then to the new core image.
|
||||
* is copied to a buffer inside PM, and then to the new core image.
|
||||
*/
|
||||
|
||||
register struct mproc *rmp;
|
||||
struct mproc *sh_mp;
|
||||
int m, r, fd, ft, sn;
|
||||
@@ -122,7 +121,7 @@ PUBLIC int do_exec()
|
||||
rmp->mp_dev = s_p->st_dev;
|
||||
rmp->mp_ctime = s_p->st_ctime;
|
||||
|
||||
/* Patch up stack and copy it from MM to new core image. */
|
||||
/* Patch up stack and copy it from PM to new core image. */
|
||||
vsp = (vir_bytes) rmp->mp_seg[S].mem_vir << CLICK_SHIFT;
|
||||
vsp += (vir_bytes) rmp->mp_seg[S].mem_len << CLICK_SHIFT;
|
||||
vsp -= stk_bytes;
|
||||
@@ -389,7 +388,7 @@ phys_bytes tot_bytes; /* total memory to allocate, including gap */
|
||||
* patch_ptr *
|
||||
*===========================================================================*/
|
||||
PRIVATE void patch_ptr(stack, base)
|
||||
char stack[ARG_MAX]; /* pointer to stack image within MM */
|
||||
char stack[ARG_MAX]; /* pointer to stack image within PM */
|
||||
vir_bytes base; /* virtual address of stack base inside user */
|
||||
{
|
||||
/* When doing an exec(name, argv, envp) call, the user builds up a stack
|
||||
@@ -422,7 +421,7 @@ vir_bytes base; /* virtual address of stack base inside user */
|
||||
* insert_arg *
|
||||
*===========================================================================*/
|
||||
PRIVATE int insert_arg(stack, stk_bytes, arg, replace)
|
||||
char stack[ARG_MAX]; /* pointer to stack image within MM */
|
||||
char stack[ARG_MAX]; /* pointer to stack image within PM */
|
||||
vir_bytes *stk_bytes; /* size of initial stack */
|
||||
char *arg; /* argument to prepend/replace as new argv[0] */
|
||||
int replace;
|
||||
@@ -480,7 +479,7 @@ int replace;
|
||||
*===========================================================================*/
|
||||
PRIVATE char *patch_stack(fd, stack, stk_bytes, script)
|
||||
int fd; /* file descriptor to open script file */
|
||||
char stack[ARG_MAX]; /* pointer to stack image within MM */
|
||||
char stack[ARG_MAX]; /* pointer to stack image within PM */
|
||||
vir_bytes *stk_bytes; /* size of initial stack */
|
||||
char *script; /* name of script to interpret */
|
||||
{
|
||||
@@ -538,10 +537,10 @@ phys_bytes seg_bytes0; /* how much is to be transferred? */
|
||||
* space one at a time. This is too slow, so we do something dirty here,
|
||||
* namely send the user space and virtual address to the file system in the
|
||||
* upper 10 bits of the file descriptor, and pass it the user virtual address
|
||||
* instead of a MM address. The file system extracts these parameters when
|
||||
* gets a read or write call from the memory manager, which is the only process
|
||||
* that is permitted to use this trick. The file system then copies the whole
|
||||
* segment directly to/from user space, bypassing MM completely.
|
||||
* instead of a PM address. The file system extracts these parameters when
|
||||
* gets a read or write call from the process manager, which is the only
|
||||
* process that is permitted to use this trick. The file system then copies
|
||||
* the whole segment directly to/from user space, bypassing PM completely.
|
||||
*
|
||||
* The byte count on read is usually smaller than the segment count, because
|
||||
* a segment is padded out to a click multiple, and the data segment is only
|
||||
@@ -557,8 +556,8 @@ phys_bytes seg_bytes0; /* how much is to be transferred? */
|
||||
ubuf_ptr = (char *) ((vir_bytes) sp->mem_vir << CLICK_SHIFT);
|
||||
|
||||
while (seg_bytes != 0) {
|
||||
#define MM_CHUNK_SIZE 8192
|
||||
bytes = MIN((INT_MAX / MM_CHUNK_SIZE) * MM_CHUNK_SIZE, seg_bytes);
|
||||
#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);
|
||||
} else {
|
||||
@@ -585,8 +584,8 @@ time_t ctime;
|
||||
* call is made.
|
||||
*/
|
||||
struct mproc *sh_mp;
|
||||
for (sh_mp = &mproc[0]; sh_mp < &mproc[NR_PROCS]; sh_mp++) {
|
||||
|
||||
for (sh_mp = &mproc[INIT_PROC_NR]; sh_mp < &mproc[NR_PROCS]; sh_mp++) {
|
||||
if (!(sh_mp->mp_flags & SEPARATE)) continue;
|
||||
if (sh_mp == mp_ign) continue;
|
||||
if (sh_mp->mp_ino != ino) continue;
|
||||
|
||||
+15
-28
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <sys/wait.h>
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/com.h>
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#define LAST_FEW 2 /* last few slots reserved for superuser */
|
||||
|
||||
PRIVATE pid_t next_pid = INIT_PID+1; /* next pid to be assigned */
|
||||
|
||||
FORWARD _PROTOTYPE (void cleanup, (register struct mproc *child) );
|
||||
|
||||
@@ -35,12 +34,12 @@ FORWARD _PROTOTYPE (void cleanup, (register struct mproc *child) );
|
||||
PUBLIC int do_fork()
|
||||
{
|
||||
/* The process pointed to by 'mp' has forked. Create a child process. */
|
||||
|
||||
register struct mproc *rmp; /* pointer to parent */
|
||||
register struct mproc *rmc; /* pointer to child */
|
||||
int i, child_nr, t;
|
||||
phys_clicks prog_clicks, child_base;
|
||||
phys_bytes prog_bytes, parent_abs, child_abs; /* Intel only */
|
||||
pid_t new_pid;
|
||||
|
||||
/* If tables might fill up during FORK, don't even start since recovery half
|
||||
* way through is such a nuisance.
|
||||
@@ -49,7 +48,7 @@ PUBLIC int do_fork()
|
||||
if ((procs_in_use == NR_PROCS) ||
|
||||
(procs_in_use >= NR_PROCS-LAST_FEW && rmp->mp_effuid != 0))
|
||||
{
|
||||
printf("MM: proc table full!\n");
|
||||
printf("PM: proc table full!\n");
|
||||
return(EAGAIN);
|
||||
}
|
||||
|
||||
@@ -90,16 +89,8 @@ PUBLIC int do_fork()
|
||||
rmc->mp_sigstatus = 0;
|
||||
|
||||
/* Find a free pid for the child and put it in the table. */
|
||||
do {
|
||||
t = 0; /* 't' = 0 means pid still free */
|
||||
next_pid = (next_pid < 30000 ? next_pid + 1 : INIT_PID + 1);
|
||||
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
|
||||
if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) {
|
||||
t = 1;
|
||||
break;
|
||||
}
|
||||
rmc->mp_pid = next_pid; /* assign pid to child */
|
||||
} while (t);
|
||||
new_pid = get_free_pid();
|
||||
rmc->mp_pid = new_pid; /* assign pid to child */
|
||||
|
||||
/* Tell kernel and file system about the (now successful) FORK. */
|
||||
sys_fork(who, child_nr, rmc->mp_pid);
|
||||
@@ -110,7 +101,7 @@ PUBLIC int do_fork()
|
||||
|
||||
/* Reply to child to wake it up. */
|
||||
setreply(child_nr, 0);
|
||||
return(next_pid); /* child's pid */
|
||||
return(new_pid); /* child's pid */
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +113,6 @@ PUBLIC int do_mm_exit()
|
||||
/* Perform the exit(status) system call. The real work is done by mm_exit(),
|
||||
* which is also called when a process is killed by a signal.
|
||||
*/
|
||||
|
||||
mm_exit(mp, m_in.status);
|
||||
return(SUSPEND); /* can't communicate from beyond the grave */
|
||||
}
|
||||
@@ -139,7 +129,6 @@ 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;
|
||||
pid_t pidarg, procgrp;
|
||||
@@ -203,20 +192,18 @@ int exit_status; /* the process' exit status (for parent) */
|
||||
*===========================================================================*/
|
||||
PUBLIC int do_waitpid()
|
||||
{
|
||||
/* A process wants to wait for a child to terminate. If one is already waiting,
|
||||
* go clean it up and let this WAIT call terminate. Otherwise, really wait.
|
||||
/* A process wants to wait for a child to terminate. If a child is already
|
||||
* waiting, go clean it up and let this WAIT call terminate. Otherwise,
|
||||
* really wait.
|
||||
* A process calling WAIT never gets a reply in the usual way at the end
|
||||
* of the main loop (unless WNOHANG is set or no qualifying child exists).
|
||||
* If a child has already exited, the routine cleanup() sends the reply
|
||||
* to awaken the caller.
|
||||
* Both WAIT and WAITPID are handled by this code.
|
||||
*/
|
||||
|
||||
register struct mproc *rp;
|
||||
int pidarg, options, children;
|
||||
|
||||
/* A process calling WAIT never gets a reply in the usual way at the end
|
||||
* of the main loop (unless WNOHANG is set or no qualifying child exists).
|
||||
* If a child has already exited, the routine cleanup() sends the reply
|
||||
* to awaken the caller.
|
||||
*/
|
||||
|
||||
/* Set internal variables, depending on whether this is WAIT or WAITPID. */
|
||||
pidarg = (call_nr == WAIT ? -1 : m_in.pid); /* 1st param of waitpid */
|
||||
options = (call_nr == WAIT ? 0 : m_in.sig_nr); /* 3rd param of waitpid */
|
||||
@@ -272,11 +259,10 @@ register struct mproc *child; /* tells which process is exiting */
|
||||
/* Finish off the exit of a process. The process has exited or been killed
|
||||
* by a signal, and its parent is waiting.
|
||||
*/
|
||||
|
||||
struct mproc *parent = &mproc[child->mp_parent];
|
||||
int exitstatus;
|
||||
|
||||
/* Wake up the parent. */
|
||||
/* Wake up the parent by sending the reply message. */
|
||||
exitstatus = (child->mp_exitstatus << 8) | (child->mp_sigstatus & 0377);
|
||||
parent->mp_reply.reply_res2 = exitstatus;
|
||||
setreply(child->mp_parent, child->mp_pid);
|
||||
@@ -286,3 +272,4 @@ register struct mproc *child; /* tells which process is exiting */
|
||||
child->mp_flags = 0;
|
||||
procs_in_use--;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
* function.
|
||||
*/
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <minix/callnr.h>
|
||||
#include <signal.h>
|
||||
#include "mproc.h"
|
||||
|
||||
+81
-53
@@ -1,27 +1,31 @@
|
||||
/* This file contains the main program of the memory manager and some related
|
||||
/* This file contains the main program of the process manager and some related
|
||||
* procedures. When MINIX starts up, the kernel runs for a little while,
|
||||
* initializing itself and its tasks, and then it runs MM and FS. Both MM
|
||||
* initializing itself and its tasks, and then it runs PM and FS. Both PM
|
||||
* and FS initialize themselves as far as they can. FS then makes a call to
|
||||
* MM, because MM has to wait for FS to acquire a RAM disk. MM asks the
|
||||
* PM, because PM has to wait for FS to acquire a RAM disk. PM asks the
|
||||
* kernel for all free memory and starts serving requests.
|
||||
*
|
||||
* The entry points into this file are:
|
||||
* main: starts MM running
|
||||
* setreply: set the reply to be sent to process making an MM system call
|
||||
* main: starts PM running
|
||||
* setreply: set the reply to be sent to process making an PM system call
|
||||
*/
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <minix/utils.h>
|
||||
#include <minix/keymap.h>
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/com.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioc_memory.h>
|
||||
#include <string.h>
|
||||
#include "mproc.h"
|
||||
#include "param.h"
|
||||
|
||||
#include "../../kernel/type.h"
|
||||
|
||||
FORWARD _PROTOTYPE( void get_work, (void) );
|
||||
FORWARD _PROTOTYPE( void mm_init, (void) );
|
||||
FORWARD _PROTOTYPE( void pm_init, (void) );
|
||||
|
||||
#define click_to_round_k(n) \
|
||||
((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
|
||||
@@ -31,22 +35,25 @@ FORWARD _PROTOTYPE( void mm_init, (void) );
|
||||
*===========================================================================*/
|
||||
PUBLIC void main()
|
||||
{
|
||||
/* Main routine of the memory manager. */
|
||||
/* Main routine of the process manager. */
|
||||
|
||||
int result, proc_nr;
|
||||
struct mproc *rmp;
|
||||
|
||||
mm_init(); /* initialize memory manager tables */
|
||||
pm_init(); /* initialize process manager tables */
|
||||
|
||||
/* This is MM's main loop- get work and do it, forever and forever. */
|
||||
/* This is PM's main loop- get work and do it, forever and forever. */
|
||||
while (TRUE) {
|
||||
get_work(); /* wait for an MM system call */
|
||||
get_work(); /* wait for an PM system call */
|
||||
|
||||
/* Check for system notifications first. Special cases. */
|
||||
if (call_nr == HARD_STOP) { /* MINIX is shutting down */
|
||||
check_sig(-1, SIGKILL); /* kill all processes */
|
||||
sys_exit(0);
|
||||
/* never reached */
|
||||
} else if (call_nr == FKEY_PRESSED) { /* create debug dump */
|
||||
(void) do_fkey_pressed();
|
||||
result = SUSPEND; /* don't reply */
|
||||
} else if (call_nr == KSIG_PENDING) { /* signals pending */
|
||||
(void) ksig_pending();
|
||||
result = SUSPEND; /* don't reply */
|
||||
@@ -69,7 +76,7 @@ PUBLIC void main()
|
||||
for (proc_nr=0, rmp=mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) {
|
||||
if ((rmp->mp_flags & (REPLY | ONSWAP)) == REPLY) {
|
||||
if (send(proc_nr, &rmp->mp_reply) != OK)
|
||||
panic("MM can't reply to", proc_nr);
|
||||
panic("PM can't reply to", proc_nr);
|
||||
rmp->mp_flags &= ~REPLY;
|
||||
}
|
||||
}
|
||||
@@ -83,12 +90,11 @@ PUBLIC void main()
|
||||
PRIVATE void get_work()
|
||||
{
|
||||
/* Wait for the next message and extract useful information from it. */
|
||||
|
||||
if (receive(ANY, &m_in) != OK) panic("MM receive error", NO_NUM);
|
||||
if (receive(ANY, &m_in) != OK) panic("PM receive error", NO_NUM);
|
||||
who = m_in.m_source; /* who sent the message */
|
||||
call_nr = m_in.m_type; /* system call number */
|
||||
|
||||
/* Process slot of caller. Misuse MM's own process slot if the kernel is
|
||||
/* Process slot of caller. Misuse PM's own process slot if the kernel is
|
||||
* calling. The can happen in case of pending kernel signals.
|
||||
*/
|
||||
mp = &mproc[who < 0 ? PM_PROC_NR : who];
|
||||
@@ -100,13 +106,12 @@ PRIVATE void get_work()
|
||||
*===========================================================================*/
|
||||
PUBLIC void setreply(proc_nr, result)
|
||||
int proc_nr; /* process to reply to */
|
||||
int result; /* result of the call (usually OK or error #)*/
|
||||
int result; /* result of call (usually OK or error #) */
|
||||
{
|
||||
/* Fill in a reply message to be sent later to a user process. System calls
|
||||
* may occasionally fill in other fields, this is only for the main return
|
||||
* value, and for setting the "must send reply" flag.
|
||||
*/
|
||||
|
||||
register struct mproc *rmp = &mproc[proc_nr];
|
||||
|
||||
rmp->mp_reply.reply_res = result;
|
||||
@@ -118,12 +123,14 @@ int result; /* result of the call (usually OK or error #)*/
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* mm_init *
|
||||
* pm_init *
|
||||
*===========================================================================*/
|
||||
PRIVATE void mm_init()
|
||||
PRIVATE void pm_init()
|
||||
{
|
||||
/* Initialize the memory manager. */
|
||||
int s;
|
||||
/* Initialize the process manager. */
|
||||
int key, i, s;
|
||||
static struct system_image image[IMAGE_SIZE];
|
||||
register struct system_image *ip;
|
||||
static char core_sigs[] = { SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
|
||||
SIGEMT, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2 };
|
||||
static char ign_sigs[] = { SIGCHLD };
|
||||
@@ -146,52 +153,73 @@ PRIVATE void mm_init()
|
||||
sigaddset(&ign_sset, *sig_ptr);
|
||||
|
||||
/* Get the memory map of the kernel to see how much memory it uses. */
|
||||
if ((s=p_getmap(SYSTASK, kernel_map)) != OK)
|
||||
panic("MM couldn't get proc entry of SYSTASK",s);
|
||||
if ((s=get_mem_map(SYSTASK, kernel_map)) != OK)
|
||||
panic("PM couldn't get proc entry of SYSTASK",s);
|
||||
minix_clicks = (kernel_map[S].mem_phys + kernel_map[S].mem_len)
|
||||
- kernel_map[T].mem_phys;
|
||||
|
||||
/* Initialize MM's tables. Request a copy of the system image table that
|
||||
/* Initialize PM's tables. Request a copy of the system image table that
|
||||
* is defined at the kernel level to see which slots to fill in.
|
||||
*/
|
||||
for (proc_nr = 0; proc_nr <= INIT_PROC_NR; proc_nr++) {
|
||||
rmp = &mproc[proc_nr];
|
||||
rmp->mp_flags |= IN_USE;
|
||||
if ((s=p_getmap(proc_nr, rmp->mp_seg)) != OK)
|
||||
panic("MM couldn't get proc entry",s);
|
||||
if (rmp->mp_seg[T].mem_len != 0) rmp->mp_flags |= SEPARATE;
|
||||
minix_clicks += (rmp->mp_seg[S].mem_phys + rmp->mp_seg[S].mem_len)
|
||||
- rmp->mp_seg[T].mem_phys;
|
||||
if (OK != (s=sys_getimage(&image))) {
|
||||
printf("PM: warning, couldn't get system image table: %d\n", s);
|
||||
}
|
||||
mproc[INIT_PROC_NR].mp_pid = INIT_PID;
|
||||
procs_in_use = 0; /* start populating table */
|
||||
for (ip = &image[0]; ip < &image[IMAGE_SIZE]; ip++) {
|
||||
if (ip->proc_nr >= 0) { /* task have negative nrs */
|
||||
procs_in_use += 1; /* found user process */
|
||||
|
||||
/* Set process details. */
|
||||
rmp = &mproc[ip->proc_nr];
|
||||
rmp->mp_flags |= IN_USE | DONT_SWAP;
|
||||
rmp->mp_pid = (ip->proc_nr == INIT_PROC_NR) ?
|
||||
INIT_PID : get_free_pid();
|
||||
strncpy(rmp->mp_name, ip->proc_name, PROC_NAME_LEN);
|
||||
|
||||
/* Change signal handling behaviour. */
|
||||
sigfillset(&rmp->mp_ignore);
|
||||
sigfillset(&rmp->mp_sigmask);
|
||||
sigemptyset(&rmp->mp_catch);
|
||||
|
||||
/* Get memory map for this process from the kernel. */
|
||||
if ((s=get_mem_map(ip->proc_nr, rmp->mp_seg)) != OK)
|
||||
panic("couldn't get process entry",s);
|
||||
if (rmp->mp_seg[T].mem_len != 0) rmp->mp_flags |= SEPARATE;
|
||||
minix_clicks += rmp->mp_seg[S].mem_phys +
|
||||
rmp->mp_seg[S].mem_len - rmp->mp_seg[T].mem_phys;
|
||||
|
||||
/* Tell FS about this system process. */
|
||||
mess.PR_PROC_NR = ip->proc_nr;
|
||||
mess.PR_PID = rmp->mp_pid;
|
||||
if (OK != (s=send(FS_PROC_NR, &mess)))
|
||||
panic("PM can't sync up with FS", s);
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell FS no more SYSTEM processes follow and synchronize. */
|
||||
mess.PR_PROC_NR = NONE;
|
||||
if (sendrec(FS_PROC_NR, &mess) != OK || mess.m_type != OK)
|
||||
panic("PM can't sync up with FS", NO_NUM);
|
||||
|
||||
/* INIT process is somewhat special. */
|
||||
sigemptyset(&mproc[INIT_PROC_NR].mp_ignore);
|
||||
sigemptyset(&mproc[INIT_PROC_NR].mp_sigmask);
|
||||
sigemptyset(&mproc[INIT_PROC_NR].mp_catch);
|
||||
procs_in_use = LOW_USER + 1;
|
||||
|
||||
/* Wait for FS to send a message telling the RAM disk size then go "on-line".
|
||||
*/
|
||||
if (receive(FS_PROC_NR, &mess) != OK)
|
||||
panic("MM can't obtain RAM disk size from FS", NO_NUM);
|
||||
|
||||
ram_clicks = mess.MEM_CHUNK_SIZE;
|
||||
|
||||
/* Initialize tables to all physical mem. */
|
||||
/* Initialize tables to all physical memory. */
|
||||
mem_init(&free_clicks);
|
||||
total_clicks = minix_clicks + ram_clicks + free_clicks;
|
||||
total_clicks = minix_clicks + free_clicks;
|
||||
|
||||
/* Print memory information. */
|
||||
printf("Memory size=%uK ", click_to_round_k(total_clicks));
|
||||
printf("MINIX=%uK ", click_to_round_k(minix_clicks));
|
||||
printf("RAM disk=%uK ", click_to_round_k(ram_clicks));
|
||||
printf("System services=%uK ", click_to_round_k(minix_clicks));
|
||||
printf("Available=%uK\n\n", click_to_round_k(free_clicks));
|
||||
|
||||
/* Tell FS to continue. */
|
||||
if (send(FS_PROC_NR, &mess) != OK)
|
||||
panic("MM can't sync up with FS", NO_NUM);
|
||||
|
||||
/* Tell the memory task where my process table is for the sake of ps(1). */
|
||||
if ((mem = open("/dev/ram", O_RDWR)) != -1) {
|
||||
ioctl(mem, MIOCSPSINFO, (void *) mproc);
|
||||
close(mem);
|
||||
/* Register function keys with TTY for debug dumps. */
|
||||
for (key=SF7; key<=SF8; key++) {
|
||||
if ((i=fkey_enable(key))!=OK) {
|
||||
printf("Warning: PM couldn't register Shift+F%d key: %d\n",
|
||||
key-SF1+1, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -2,11 +2,11 @@
|
||||
* 31 Mar 2000
|
||||
* The entry points into this file are:
|
||||
* do_reboot: kill all processes, then reboot system
|
||||
* do_svrctl: memory manager control
|
||||
* do_getsysinfo: request copy of MM data structure
|
||||
* do_svrctl: process manager control
|
||||
* do_getsysinfo: request copy of PM data structure
|
||||
*/
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <minix/callnr.h>
|
||||
#include <signal.h>
|
||||
#include <sys/svrctl.h>
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
FORWARD _PROTOTYPE( char *find_key, (const char *params, const char *key));
|
||||
|
||||
/* MM gets a copy of all boot monitor parameters. */
|
||||
/* PM gets a copy of all boot monitor parameters. */
|
||||
PRIVATE char monitor_params[128*sizeof(char *)];
|
||||
|
||||
/*=====================================================================*
|
||||
@@ -57,8 +57,8 @@ PUBLIC int do_reboot()
|
||||
return(EINVAL);
|
||||
}
|
||||
|
||||
check_sig(-1, SIGKILL); /* kill all processes except init */
|
||||
tell_fs(REBOOT,0,0,0); /* tell FS to prepare for shutdown */
|
||||
check_sig(-1, SIGKILL); /* kill all processes except init */
|
||||
|
||||
sys_abort(m_in.reboot_flag, PM_PROC_NR, monitor_code, m_in.reboot_size);
|
||||
sys_exit(0);
|
||||
@@ -78,7 +78,7 @@ PUBLIC int do_svrctl()
|
||||
/* Initialize private copy of monitor parameters on first call. */
|
||||
if (! initialized) {
|
||||
if ((s=sys_getmonparams(monitor_params, sizeof(monitor_params))) != OK)
|
||||
printf("MM: Warning couldn't get copy of monitor params: %d\n",s);
|
||||
printf("PM: Warning couldn't get copy of monitor params: %d\n",s);
|
||||
else
|
||||
initialized = 1;
|
||||
}
|
||||
@@ -98,7 +98,7 @@ PUBLIC int do_svrctl()
|
||||
return(sys_svrctl(who, req, mp->mp_effuid == SUPER_USER, ptr));
|
||||
}
|
||||
|
||||
/* Control operations local to the MM. */
|
||||
/* Control operations local to the PM. */
|
||||
switch(req) {
|
||||
case MMGETPARAM: {
|
||||
struct sysgetenv sysgetenv;
|
||||
@@ -110,7 +110,7 @@ PUBLIC int do_svrctl()
|
||||
/* Check if boot monitor parameters are in place. */
|
||||
if (! initialized) return(EAGAIN);
|
||||
|
||||
/* Copy sysgetenv structure to MM. */
|
||||
/* Copy sysgetenv structure to PM. */
|
||||
if (sys_datacopy(who, ptr, SELF, (vir_bytes) &sysgetenv,
|
||||
sizeof(sysgetenv)) != OK) return(EFAULT);
|
||||
|
||||
@@ -170,7 +170,7 @@ PUBLIC int do_svrctl()
|
||||
}
|
||||
}
|
||||
|
||||
/* Become like MM and FS. */
|
||||
/* Become like PM and FS. */
|
||||
mp->mp_pid = mp->mp_procgrp = 0;
|
||||
mp->mp_parent = 0;
|
||||
return(OK); }
|
||||
|
||||
+3
-2
@@ -1,4 +1,4 @@
|
||||
/* This table has one slot per process. It contains all the memory management
|
||||
/* This table has one slot per process. It contains all the process management
|
||||
* information for each process. Among other things, it defines the text, data
|
||||
* and stack segments, uids and gids, and various flags. The kernel and file
|
||||
* systems have tables that are also indexed by process, with the contents
|
||||
@@ -30,7 +30,7 @@ EXTERN struct mproc {
|
||||
sigset_t mp_catch; /* 1 means catch the signal, 0 means don't */
|
||||
sigset_t mp_sigmask; /* signals to be blocked */
|
||||
sigset_t mp_sigmask2; /* saved copy of mp_sigmask */
|
||||
sigset_t mp_sigpending; /* signals being blocked */
|
||||
sigset_t mp_sigpending; /* pending signals to be handled */
|
||||
struct sigaction mp_sigact[_NSIG + 1]; /* as in sigaction(2) */
|
||||
vir_bytes mp_sigreturn; /* address of C library __sigreturn function */
|
||||
|
||||
@@ -58,5 +58,6 @@ EXTERN struct mproc {
|
||||
#define REPLY 0x200 /* set if a reply message is pending */
|
||||
#define ONSWAP 0x400 /* set if data segment is swapped out */
|
||||
#define SWAPIN 0x800 /* set if on the "swap this in" queue */
|
||||
#define DONT_SWAP 0x1000 /* never swap out this process */
|
||||
|
||||
#define NIL_MPROC ((struct mproc *) 0)
|
||||
|
||||
+6
-4
@@ -29,6 +29,9 @@ _PROTOTYPE( int size_ok, (int file_type, vir_clicks tc, vir_clicks dc,
|
||||
_PROTOTYPE( int do_dev_io, (void) );
|
||||
_PROTOTYPE( int do_dev_io, (void) );
|
||||
|
||||
/* dmp.c */
|
||||
_PROTOTYPE( int do_fkey_pressed, (void) );
|
||||
|
||||
/* exec.c */
|
||||
_PROTOTYPE( int do_exec, (void) );
|
||||
_PROTOTYPE( void rw_seg, (int rw, int fd, int proc, int seg,
|
||||
@@ -64,7 +67,6 @@ _PROTOTYPE( void setreply, (int proc_nr, int result) );
|
||||
_PROTOTYPE( int do_alarm, (void) );
|
||||
_PROTOTYPE( int do_kill, (void) );
|
||||
_PROTOTYPE( int ksig_pending, (void) );
|
||||
_PROTOTYPE( int do_ksig, (void) );
|
||||
_PROTOTYPE( int do_pause, (void) );
|
||||
_PROTOTYPE( int set_alarm, (int proc_nr, int sec) );
|
||||
_PROTOTYPE( int check_sig, (pid_t proc_id, int signo) );
|
||||
@@ -81,11 +83,11 @@ _PROTOTYPE( int do_trace, (void) );
|
||||
_PROTOTYPE( void stop_proc, (struct mproc *rmp, int sig_nr) );
|
||||
|
||||
/* utility.c */
|
||||
_PROTOTYPE( pid_t get_free_pid, (void) );
|
||||
_PROTOTYPE( int allowed, (char *name_buf, struct stat *s_buf, int mask) );
|
||||
_PROTOTYPE( int no_sys, (void) );
|
||||
_PROTOTYPE( void panic, (char *format, int num) );
|
||||
_PROTOTYPE( void tell_fs, (int what, int p1, int p2, int p3) );
|
||||
_PROTOTYPE( int get_stack_ptr, (int proc_nr, vir_bytes *sp) );
|
||||
_PROTOTYPE( int get_mem_map, (int proc_nr, struct mem_map *mem_map) );
|
||||
|
||||
/* procutils.c */
|
||||
_PROTOTYPE( int p_getsp, (int proc_nr, vir_bytes *sp) );
|
||||
_PROTOTYPE( int p_getmap, (int proc_nr, struct mem_map *mem_map) );
|
||||
|
||||
+20
-36
@@ -11,7 +11,6 @@
|
||||
* do_sigreturn: perform the SIGRETURN system call
|
||||
* do_sigsuspend: perform the SIGSUSPEND system call
|
||||
* do_kill: perform the KILL system call
|
||||
* do_ksig: accept a signal originating in the kernel (e.g., SIGINT)
|
||||
* do_alarm: perform the ALARM system call by calling set_alarm()
|
||||
* set_alarm: tell the clock task to start or stop a timer
|
||||
* do_pause: perform the PAUSE system call
|
||||
@@ -21,7 +20,7 @@
|
||||
* check_pending: check if a pending signal can now be delivered
|
||||
*/
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <minix/utils.h>
|
||||
#include <sys/stat.h>
|
||||
#include <minix/callnr.h>
|
||||
@@ -189,11 +188,17 @@ PUBLIC int do_kill()
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* do_ksig_pending *
|
||||
* ksig_pending *
|
||||
*===========================================================================*/
|
||||
PUBLIC int ksig_pending()
|
||||
{
|
||||
/* The kernel has notified the MM about pending signals. Request pending
|
||||
/* Certain signals, such as segmentation violations and DEL, originate in the
|
||||
* kernel. When the kernel detects such signals, it sets bits in a bit map.
|
||||
* As soon as PM is awaiting new work, the kernel sends PM a message containing
|
||||
* the process slot and bit map. That message comes here. The File System
|
||||
* also uses this mechanism to signal writing on broken pipes (SIGPIPE).
|
||||
*
|
||||
* The kernel has notified the PM about pending signals. Request pending
|
||||
* signals until all signals are handled. If there are no more signals,
|
||||
* NONE is returned in the process number field.
|
||||
*/
|
||||
@@ -211,27 +216,6 @@ PUBLIC int ksig_pending()
|
||||
return(SUSPEND); /* prevents sending reply */
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* do_ksig *
|
||||
*===========================================================================*/
|
||||
PUBLIC int do_ksig()
|
||||
{
|
||||
/* Certain signals, such as segmentation violations and DEL, originate in the
|
||||
* kernel. When the kernel detects such signals, it sets bits in a bit map.
|
||||
* As soon as MM is awaiting new work, the kernel sends MM a message containing
|
||||
* the process slot and bit map. That message comes here. The File System
|
||||
* also uses this mechanism to signal writing on broken pipes (SIGPIPE).
|
||||
*/
|
||||
int proc_nr;
|
||||
sigset_t sig_map;
|
||||
|
||||
/* Only kernel may make this call. */
|
||||
if (who != HARDWARE) return(EPERM);
|
||||
proc_nr = m_in.SIG_PROC;
|
||||
sig_map = (sigset_t) m_in.SIG_MAP;
|
||||
handle_ksig(proc_nr, sig_map);
|
||||
return(SUSPEND);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* handle_ksig *
|
||||
@@ -247,12 +231,12 @@ sigset_t sig_map;
|
||||
rmp = &mproc[proc_nr];
|
||||
if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) return;
|
||||
proc_id = rmp->mp_pid;
|
||||
mp = &mproc[0]; /* pretend kernel signals are from MM */
|
||||
mp = &mproc[0]; /* pretend kernel signals are from PM */
|
||||
mp->mp_procgrp = rmp->mp_procgrp; /* get process group right */
|
||||
|
||||
/* Check each bit in turn to see if a signal is to be sent. Unlike
|
||||
* kill(), the kernel may collect several unrelated signals for a
|
||||
* process and pass them to MM in one blow. Thus loop on the bit
|
||||
* process and pass them to PM in one blow. Thus loop on the bit
|
||||
* map. For SIGINT and SIGQUIT, use proc_id 0 to indicate a broadcast
|
||||
* to the recipient's process group. For SIGKILL, use proc_id -1 to
|
||||
* indicate a systemwide broadcast.
|
||||
@@ -331,7 +315,7 @@ int sec; /* how many seconds delay before the signal */
|
||||
ticks = LONG_MAX; /* eternity (really TMR_NEVER) */
|
||||
|
||||
if ((s=sys_signalrm(proc_nr, &ticks)) != OK)
|
||||
panic("MM couldn't set signal alarm", s);
|
||||
panic("PM couldn't set signal alarm", s);
|
||||
|
||||
remaining = (int) ((ticks + (HZ-1))/HZ);
|
||||
if (remaining < 0) remaining = INT_MAX; /* true value is too large */
|
||||
@@ -378,7 +362,7 @@ int signo; /* signal to send to process (1 to _NSIG) */
|
||||
|
||||
slot = (int) (rmp - mproc);
|
||||
if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) {
|
||||
printf("MM: signal %d sent to %s process %d\n",
|
||||
printf("PM: signal %d sent to %s process %d\n",
|
||||
(rmp->mp_flags & ZOMBIE) ? "zombie" : "dead", signo, slot);
|
||||
panic("", NO_NUM);
|
||||
}
|
||||
@@ -411,8 +395,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=p_getsp(slot, &new_sp)) != OK)
|
||||
panic("MM couldn't get new stack pointer",s);
|
||||
if ((s=get_stack_ptr(slot, &new_sp)) != OK)
|
||||
panic("PM couldn't get new stack pointer",s);
|
||||
sm.sm_stkptr = new_sp;
|
||||
|
||||
/* Make room for the sigcontext and sigframe struct. */
|
||||
@@ -487,7 +471,7 @@ int signo; /* signal to send to process (0 to _NSIG) */
|
||||
*/
|
||||
count = 0;
|
||||
error_code = ESRCH;
|
||||
for (rmp = &mproc[INIT_PROC_NR]; rmp < &mproc[NR_PROCS]; rmp++) {
|
||||
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
|
||||
if (!(rmp->mp_flags & IN_USE)) continue;
|
||||
if ((rmp->mp_flags & ZOMBIE) && signo != 0) continue;
|
||||
|
||||
@@ -564,7 +548,7 @@ int pro; /* which process number */
|
||||
/* A signal is to be sent to a process. If that process is hanging on a
|
||||
* system call, the system call must be terminated with EINTR. Possible
|
||||
* calls are PAUSE, WAIT, READ and WRITE, the latter two for pipes and ttys.
|
||||
* First check if the process is hanging on an MM call. If not, tell FS,
|
||||
* First check if the process is hanging on an PM call. If not, tell FS,
|
||||
* so it can check for READs and WRITEs from pipes, ttys and the like.
|
||||
*/
|
||||
|
||||
@@ -579,7 +563,7 @@ int pro; /* which process number */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Process is not hanging on an MM call. Ask FS to take a look. */
|
||||
/* Process is not hanging on an PM call. Ask FS to take a look. */
|
||||
tell_fs(UNPAUSE, pro, 0, 0);
|
||||
}
|
||||
|
||||
@@ -615,8 +599,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=p_getsp(slot, ¤t_sp)) != OK)
|
||||
panic("MM couldn't get new stack pointer",s);
|
||||
if ((s=get_stack_ptr(slot, ¤t_sp)) != OK)
|
||||
panic("PM couldn't get new stack pointer",s);
|
||||
adjust(rmp, rmp->mp_seg[D].mem_len, current_sp);
|
||||
|
||||
/* Write the memory map of all segments to begin the core file. */
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
|
||||
#define _TABLE
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <minix/callnr.h>
|
||||
#include <signal.h>
|
||||
#include "mproc.h"
|
||||
@@ -79,7 +79,7 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = {
|
||||
do_getset, /* 62 = setsid */
|
||||
do_getset, /* 63 = getpgrp */
|
||||
|
||||
do_ksig, /* 64 = KSIG: signals originating in the kernel */
|
||||
no_sys, /* 64 = unused */
|
||||
no_sys, /* 65 = UNPAUSE */
|
||||
no_sys, /* 66 = unused */
|
||||
no_sys, /* 67 = REVIVE */
|
||||
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
/* This file handles the memory manager's part of debugging, using the
|
||||
/* This file handles the process manager's part of debugging, using the
|
||||
* ptrace system call. Most of the commands are passed on to the system
|
||||
* task for completion.
|
||||
*
|
||||
@@ -20,7 +20,7 @@
|
||||
* task. The rest are handled entirely by the system task.
|
||||
*/
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <minix/com.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <signal.h>
|
||||
@@ -82,7 +82,7 @@ pid_t lpid;
|
||||
{
|
||||
register struct mproc *rmp;
|
||||
|
||||
for (rmp = &mproc[INIT_PROC_NR + 1]; rmp < &mproc[NR_PROCS]; rmp++)
|
||||
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
|
||||
if (rmp->mp_flags & IN_USE && rmp->mp_pid == lpid) return(rmp);
|
||||
return(NIL_MPROC);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* If there were any type definitions local to the Memory Manager, they would
|
||||
/* If there were any type definitions local to the Process Manager, they would
|
||||
* be here. This file is included only for symmetry with the kernel and File
|
||||
* System, which do have some local type definitions.
|
||||
*/
|
||||
|
||||
+81
-17
@@ -1,13 +1,16 @@
|
||||
/* This file contains some utility routines for MM.
|
||||
/* This file contains some utility routines for PM.
|
||||
*
|
||||
* The entry points are:
|
||||
* allowed: see if an access is permitted
|
||||
* no_sys: this routine is called for invalid system call numbers
|
||||
* panic: MM has run aground of a fatal error and cannot continue
|
||||
* tell_fs: interface to FS
|
||||
* get_free_pid: get a free process or group id
|
||||
* allowed: see if an access is permitted
|
||||
* no_sys: called for invalid system call numbers
|
||||
* panic: PM has run aground of a fatal error
|
||||
* tell_fs: interface to FS
|
||||
* get_mem_map: get memory map of given process
|
||||
* get_stack_ptr: get stack pointer of given process
|
||||
*/
|
||||
|
||||
#include "mm.h"
|
||||
#include "pm.h"
|
||||
#include <sys/stat.h>
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/com.h>
|
||||
@@ -16,6 +19,36 @@
|
||||
#include "mproc.h"
|
||||
#include "param.h"
|
||||
|
||||
#include <minix/config.h>
|
||||
#include <timers.h>
|
||||
#include <string.h>
|
||||
#include "../../kernel/const.h"
|
||||
#include "../../kernel/type.h"
|
||||
#include "../../kernel/proc.h"
|
||||
|
||||
/*===========================================================================*
|
||||
* get_free_pid *
|
||||
*===========================================================================*/
|
||||
PUBLIC pid_t get_free_pid()
|
||||
{
|
||||
static pid_t next_pid = INIT_PID + 1; /* next pid to be assigned */
|
||||
register struct mproc *rmp; /* check process table */
|
||||
int t; /* zero if pid still free */
|
||||
|
||||
/* Find a free pid for the child and put it in the table. */
|
||||
do {
|
||||
t = 0;
|
||||
next_pid = (next_pid < 30000 ? next_pid + 1 : INIT_PID + 1);
|
||||
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
|
||||
if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) {
|
||||
t = 1;
|
||||
break;
|
||||
}
|
||||
} while (t); /* 't' = 0 means pid free */
|
||||
return(next_pid);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* allowed *
|
||||
*===========================================================================*/
|
||||
@@ -27,13 +60,12 @@ int mask; /* R_BIT, W_BIT, or X_BIT */
|
||||
/* Check to see if file can be accessed. Return EACCES or ENOENT if the access
|
||||
* is prohibited. If it is legal open the file and return a file descriptor.
|
||||
*/
|
||||
|
||||
int fd;
|
||||
int save_errno;
|
||||
|
||||
/* Use the fact that mask for access() is the same as the permissions mask.
|
||||
* E.g., X_BIT in <minix/const.h> is the same as X_OK in <unistd.h> and
|
||||
* S_IXOTH in <sys/stat.h>. tell_fs(DO_CHDIR, ...) has set MM's real ids
|
||||
* S_IXOTH in <sys/stat.h>. tell_fs(DO_CHDIR, ...) has set PM's real ids
|
||||
* to the user's effective ids, so access() works right for setuid programs.
|
||||
*/
|
||||
if (access(name_buf, mask) < 0) return(-errno);
|
||||
@@ -62,7 +94,7 @@ int mask; /* R_BIT, W_BIT, or X_BIT */
|
||||
*===========================================================================*/
|
||||
PUBLIC int no_sys()
|
||||
{
|
||||
/* A system call number not implemented by MM has been requested. */
|
||||
/* A system call number not implemented by PM has been requested. */
|
||||
|
||||
return(EINVAL);
|
||||
}
|
||||
@@ -75,15 +107,14 @@ PUBLIC void panic(format, num)
|
||||
char *format; /* format string */
|
||||
int num; /* number to go with format string */
|
||||
{
|
||||
/* Something awful has happened. Panics are caused when an internal
|
||||
/* An unrecoverable error has occurred. Panics are caused when an internal
|
||||
* inconsistency is detected, e.g., a programming error or illegal value of a
|
||||
* defined constant.
|
||||
* defined constant. The process manager decides to shut down. This results
|
||||
* in a HARD_STOP notification to all system processes to allow local cleanup.
|
||||
*/
|
||||
|
||||
printf("Memory manager panic: %s ", format);
|
||||
if (num != NO_NUM) printf("%d",num);
|
||||
printf("Process manager panic: %s", format);
|
||||
if (num != NO_NUM) printf(": %d",num);
|
||||
printf("\n");
|
||||
tell_fs(SYNC, 0, 0, 0); /* flush the cache to the disk */
|
||||
sys_abort(RBT_PANIC);
|
||||
}
|
||||
|
||||
@@ -94,7 +125,7 @@ int num; /* number to go with format string */
|
||||
PUBLIC void tell_fs(what, p1, p2, p3)
|
||||
int what, p1, p2, p3;
|
||||
{
|
||||
/* This routine is only used by MM to inform FS of certain events:
|
||||
/* This routine is only used by PM to inform FS of certain events:
|
||||
* tell_fs(CHDIR, slot, dir, 0)
|
||||
* tell_fs(EXEC, proc, 0, 0)
|
||||
* tell_fs(EXIT, proc, 0, 0)
|
||||
@@ -102,7 +133,6 @@ int what, p1, p2, p3;
|
||||
* tell_fs(SETGID, proc, realgid, effgid)
|
||||
* tell_fs(SETSID, proc, 0, 0)
|
||||
* tell_fs(SETUID, proc, realuid, effuid)
|
||||
* tell_fs(SYNC, 0, 0, 0)
|
||||
* tell_fs(UNPAUSE, proc, signr, 0)
|
||||
*/
|
||||
message m;
|
||||
@@ -112,3 +142,37 @@ int what, p1, p2, p3;
|
||||
m.tell_fs_arg3 = p3;
|
||||
_taskcall(FS_PROC_NR, what, &m);
|
||||
}
|
||||
|
||||
|
||||
/*===========================================================================*
|
||||
* get_mem_map *
|
||||
*===========================================================================*/
|
||||
PUBLIC int get_mem_map(proc_nr, mem_map)
|
||||
int proc_nr; /* process to get map of */
|
||||
struct mem_map *mem_map; /* put memory map here */
|
||||
{
|
||||
struct proc p;
|
||||
int s;
|
||||
|
||||
if ((s=sys_getproc(&p, proc_nr)) != OK)
|
||||
return(s);
|
||||
memcpy(mem_map, p.p_memmap, sizeof(p.p_memmap));
|
||||
return(OK);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* get_stack_ptr *
|
||||
*===========================================================================*/
|
||||
PUBLIC int get_stack_ptr(proc_nr, sp)
|
||||
int proc_nr; /* 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)
|
||||
return(s);
|
||||
*sp = p.p_reg.sp;
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user