- Introduce some macros for field names, so that endpt, pendpt,

addr and taddr don't have to be defined any more, so that <sys/mman.h>
    can be included for proper prototypes of munmap() and friends.
  - rename our GETPID to MINIX_GETPID to avoid a name conflict with
    other sources
  - PM needs its own munmap() and munmap_text() to avoid sending messages
    to VM at the startup phase. It *does* want to do that, but only
    after initialising. So they're called again with unmap_ok set to 1
    later.
  - getnuid(), getngid() implementation
This commit is contained in:
Ben Gras 2009-09-21 14:48:19 +00:00
parent a0d8cc0765
commit 5f497bcf22
11 changed files with 85 additions and 24 deletions

View file

@ -18,7 +18,7 @@ LDFLAGS = -i
OBJ = main.o forkexit.o break.o exec.o time.o timers.o alarm.o \ OBJ = main.o forkexit.o break.o exec.o time.o timers.o alarm.o \
signal.o utility.o table.o trace.o getset.o misc.o \ signal.o utility.o table.o trace.o getset.o misc.o \
profile.o dma.o profile.o dma.o
# build local binary # build local binary
all build: $(SERVER) all build: $(SERVER)

View file

@ -13,8 +13,8 @@ PUBLIC int do_brk()
{ {
int r; int r;
/* Entry point to brk(addr) system call. */ /* Entry point to brk(addr) system call. */
r = vm_brk(mp->mp_endpoint, m_in.addr); r = vm_brk(mp->mp_endpoint, m_in.PMBRK_ADDR);
mp->mp_reply.reply_ptr = (r == OK ? m_in.addr : (char *) -1); mp->mp_reply.reply_ptr = (r == OK ? m_in.PMBRK_ADDR : (char *) -1);
return r; return r;
} }

View file

@ -113,6 +113,8 @@ PUBLIC int exec_newmem()
mp->mp_reply.reply_res3= flags; mp->mp_reply.reply_res3= flags;
if (allow_setuid) if (allow_setuid)
mp->mp_reply.reply_res3 |= EXC_NM_RF_ALLOW_SETUID; mp->mp_reply.reply_res3 |= EXC_NM_RF_ALLOW_SETUID;
} else {
printf("PM: newmem failed for %s\n", args.progname);
} }
return r; return r;
} }

View file

@ -248,6 +248,7 @@ int dump_core; /* flag indicating whether to dump core */
if((r=vm_willexit(proc_nr_e)) != OK) { if((r=vm_willexit(proc_nr_e)) != OK) {
panic(__FILE__, "exit_proc: vm_willexit failed", r); panic(__FILE__, "exit_proc: vm_willexit failed", r);
} }
vm_notify_sig_wrapper(rmp->mp_endpoint);
if (proc_nr_e == INIT_PROC_NR) if (proc_nr_e == INIT_PROC_NR)
{ {
@ -276,8 +277,7 @@ int dump_core; /* flag indicating whether to dump core */
} }
else else
{ {
printf("PM: FS died\n"); panic(__FILE__, "pm_exit: FS died", r);
return;
} }
/* The process is now officially exiting. The ZOMBIE flag is not enough, as /* The process is now officially exiting. The ZOMBIE flag is not enough, as

View file

@ -7,6 +7,7 @@
#include "pm.h" #include "pm.h"
#include <minix/callnr.h> #include <minix/callnr.h>
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/com.h>
#include <signal.h> #include <signal.h>
#include "mproc.h" #include "mproc.h"
#include "param.h" #include "param.h"
@ -29,17 +30,21 @@ PUBLIC int do_getset()
case GETUID: case GETUID:
r = rmp->mp_realuid; r = rmp->mp_realuid;
rmp->mp_reply.reply_res2 = rmp->mp_effuid; rmp->mp_reply.reply_res2 = rmp->mp_effuid;
if (pm_isokendpt(m_in.PM_ENDPT, &proc) == OK && proc >= 0)
rmp->mp_reply.reply_res3 = mproc[proc].mp_effuid;
break; break;
case GETGID: case GETGID:
r = rmp->mp_realgid; r = rmp->mp_realgid;
rmp->mp_reply.reply_res2 = rmp->mp_effgid; rmp->mp_reply.reply_res2 = rmp->mp_effgid;
if (pm_isokendpt(m_in.PM_ENDPT, &proc) == OK && proc >= 0)
rmp->mp_reply.reply_res3 = mproc[proc].mp_effgid;
break; break;
case GETPID: case MINIX_GETPID:
r = mproc[who_p].mp_pid; r = mproc[who_p].mp_pid;
rmp->mp_reply.reply_res2 = mproc[rmp->mp_parent].mp_pid; rmp->mp_reply.reply_res2 = mproc[rmp->mp_parent].mp_pid;
if(pm_isokendpt(m_in.endpt, &proc) == OK && proc >= 0) if(pm_isokendpt(m_in.PM_ENDPT, &proc) == OK && proc >= 0)
rmp->mp_reply.reply_res3 = mproc[proc].mp_pid; rmp->mp_reply.reply_res3 = mproc[proc].mp_pid;
break; break;

View file

@ -19,6 +19,7 @@
#include <minix/minlib.h> #include <minix/minlib.h>
#include <minix/type.h> #include <minix/type.h>
#include <minix/vm.h> #include <minix/vm.h>
#include <minix/crtso.h>
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
@ -208,6 +209,8 @@ int result; /* result of call (usually OK or error #) */
rmp->mp_flags |= REPLY; /* reply pending */ rmp->mp_flags |= REPLY; /* reply pending */
} }
extern int unmap_ok;
/*===========================================================================* /*===========================================================================*
* pm_init * * pm_init *
*===========================================================================*/ *===========================================================================*/
@ -340,6 +343,17 @@ PRIVATE void pm_init()
if(f > 0) printf("PM: failed to register %d processes with DS.\n", f); if(f > 0) printf("PM: failed to register %d processes with DS.\n", f);
system_hz = sys_hz(); system_hz = sys_hz();
/* Map out our own text and data. This is normally done in crtso.o
* but PM is an exception - we don't get to talk to VM so early on.
* That's why we override munmap() and munmap_text() in utility.c.
*
* _minix_unmapzero() is the same code in crtso.o that normally does
* it on startup. It's best that it's there as crtso.o knows exactly
* what the ranges are of the filler data.
*/
unmap_ok = 1;
_minix_unmapzero();
} }
/*===========================================================================* /*===========================================================================*

View file

@ -325,7 +325,7 @@ PUBLIC int do_getprocnr()
if (m_in.pid >= 0) { /* lookup process by pid */ if (m_in.pid >= 0) { /* lookup process by pid */
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) { for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
if ((rmp->mp_flags & IN_USE) && (rmp->mp_pid==m_in.pid)) { if ((rmp->mp_flags & IN_USE) && (rmp->mp_pid==m_in.pid)) {
mp->mp_reply.endpt = rmp->mp_endpoint; mp->mp_reply.PM_ENDPT = rmp->mp_endpoint;
#if 0 #if 0
printf("PM: pid result: %d\n", rmp->mp_endpoint); printf("PM: pid result: %d\n", rmp->mp_endpoint);
#endif #endif
@ -335,27 +335,24 @@ PUBLIC int do_getprocnr()
return(ESRCH); return(ESRCH);
} else if (m_in.namelen > 0) { /* lookup process by name */ } else if (m_in.namelen > 0) { /* lookup process by name */
key_len = MIN(m_in.namelen, PROC_NAME_LEN); key_len = MIN(m_in.namelen, PROC_NAME_LEN);
if (OK != (s=sys_datacopy(who_e, (vir_bytes) m_in.addr, if (OK != (s=sys_datacopy(who_e, (vir_bytes) m_in.PMBRK_ADDR,
SELF, (vir_bytes) search_key, key_len))) SELF, (vir_bytes) search_key, key_len)))
return(s); return(s);
search_key[key_len] = '\0'; /* terminate for safety */ search_key[key_len] = '\0'; /* terminate for safety */
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) { for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
if (((rmp->mp_flags & (IN_USE | EXITING)) == IN_USE) && if (((rmp->mp_flags & (IN_USE | EXITING)) == IN_USE) &&
strncmp(rmp->mp_name, search_key, key_len)==0) { strncmp(rmp->mp_name, search_key, key_len)==0) {
mp->mp_reply.endpt = rmp->mp_endpoint; mp->mp_reply.PM_ENDPT = rmp->mp_endpoint;
printf("PM: name %s result: %d\n", search_key,
rmp->mp_endpoint);
return(OK); return(OK);
} }
} }
printf("PM: name %s result: ESRCH\n", search_key);
return(ESRCH); return(ESRCH);
} else { /* return own/parent process number */ } else { /* return own/parent process number */
#if 0 #if 0
printf("PM: endpt result: %d\n", mp->mp_reply.endpt); printf("PM: endpt result: %d\n", mp->mp_reply.PM_ENDPT);
#endif #endif
mp->mp_reply.endpt = who_e; mp->mp_reply.PM_ENDPT = who_e;
mp->mp_reply.pendpt = mproc[mp->mp_parent].mp_endpoint; mp->mp_reply.PM_PENDPT = mproc[mp->mp_parent].mp_endpoint;
} }
return(OK); return(OK);
@ -378,7 +375,7 @@ PUBLIC int do_getpuid()
return EPERM; return EPERM;
} }
ep= m_in.endpt; ep= m_in.PM_ENDPT;
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) { for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
if ((rmp->mp_flags & IN_USE) && (rmp->mp_endpoint == ep)) { if ((rmp->mp_flags & IN_USE) && (rmp->mp_endpoint == ep)) {

View file

@ -1,13 +1,10 @@
/* The following names are synonyms for the variables in the input message. */ /* The following names are synonyms for the variables in the input message. */
#define addr m1_p1
#define exec_name m1_p1 #define exec_name m1_p1
#define exec_len m1_i1 #define exec_len m1_i1
#define func m6_f1 #define func m6_f1
#define grp_id m1_i1 #define grp_id m1_i1
#define namelen m1_i2 #define namelen m1_i2
#define pid m1_i1 #define pid m1_i1
#define endpt m1_i1
#define pendpt m1_i2
#define seconds m1_i1 #define seconds m1_i1
#define which_timer m1_i1 #define which_timer m1_i1
#define new_val m1_p1 #define new_val m1_p1
@ -18,7 +15,6 @@
#define status m1_i1 #define status m1_i1
#define usr_id m1_i1 #define usr_id m1_i1
#define request m2_i2 #define request m2_i2
#define taddr m2_l1
#define data m2_l2 #define data m2_l2
#define sig_nr m1_i2 #define sig_nr m1_i2
#define sig_nsa m1_p1 #define sig_nsa m1_p1

View file

@ -306,6 +306,28 @@ PUBLIC int do_pause()
return(SUSPEND); return(SUSPEND);
} }
PRIVATE vm_notify_sig_wrapper(endpoint_t ep)
{
/* get IPC's endpoint,
* the reason that we directly get the endpoint
* instead of from DS server is that otherwise
* it will cause deadlock between PM, VM and DS.
*/
struct mproc *rmp;
endpoint_t ipc_ep = 0;
for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
if (!(rmp->mp_flags & IN_USE))
continue;
if (!strcmp(rmp->mp_name, "ipc")) {
ipc_ep = rmp->mp_endpoint;
vm_notify_sig(ep, ipc_ep);
return;
}
}
}
/*===========================================================================* /*===========================================================================*
* sig_proc * * sig_proc *
*===========================================================================*/ *===========================================================================*/
@ -411,6 +433,7 @@ int signo; /* signal to send to process (1 to _NSIG) */
* ready. * ready.
*/ */
unpause(slot, FALSE /*!for_trace*/); unpause(slot, FALSE /*!for_trace*/);
vm_notify_sig_wrapper(rmp->mp_endpoint);
return; return;
} }
else if (sigismember(&rmp->mp_sig2mess, signo)) { else if (sigismember(&rmp->mp_sig2mess, signo)) {

View file

@ -55,7 +55,7 @@ PUBLIC int do_trace()
if ((child=find_proc(m_in.pid))==NIL_MPROC) if ((child=find_proc(m_in.pid))==NIL_MPROC)
return(ESRCH); return(ESRCH);
r= sys_trace(m_in.request,child->mp_endpoint,m_in.taddr,&m_in.data); r= sys_trace(m_in.request,child->mp_endpoint,m_in.PMTRACE_ADDR,&m_in.data);
if (r != OK) return(r); if (r != OK) return(r);
mp->mp_reply.reply_trace = m_in.data; mp->mp_reply.reply_trace = m_in.data;
@ -80,7 +80,7 @@ PUBLIC int do_trace()
child->mp_ctime= 0; child->mp_ctime= 0;
#endif #endif
r= sys_trace(m_in.request,child->mp_endpoint,m_in.taddr,&m_in.data); r= sys_trace(m_in.request,child->mp_endpoint,m_in.PMTRACE_ADDR,&m_in.data);
if (r != OK) return(r); if (r != OK) return(r);
mp->mp_reply.reply_trace = m_in.data; mp->mp_reply.reply_trace = m_in.data;
@ -135,7 +135,7 @@ PUBLIC int do_trace()
child->mp_flags &= ~STOPPED; child->mp_flags &= ~STOPPED;
break; break;
} }
r= sys_trace(m_in.request,child->mp_endpoint,m_in.taddr,&m_in.data); r= sys_trace(m_in.request,child->mp_endpoint,m_in.PMTRACE_ADDR,&m_in.data);
if (r != OK) return(r); if (r != OK) return(r);
mp->mp_reply.reply_trace = m_in.data; mp->mp_reply.reply_trace = m_in.data;

View file

@ -28,6 +28,12 @@
#include "../../kernel/type.h" #include "../../kernel/type.h"
#include "../../kernel/proc.h" #include "../../kernel/proc.h"
#define munmap _munmap
#define munmap_text _munmap_text
#include <sys/mman.h>
#undef munmap
#undef munmap_text
/*===========================================================================* /*===========================================================================*
* get_free_pid * * get_free_pid *
*===========================================================================*/ *===========================================================================*/
@ -111,3 +117,21 @@ PUBLIC int pm_isokendpt(int endpoint, int *proc)
return OK; return OK;
} }
int unmap_ok = 0;
PUBLIC int munmap(void *addrstart, vir_bytes len)
{
if(!unmap_ok)
return ENOSYS;
return _munmap(addrstart, len);
}
PUBLIC int munmap_text(void *addrstart, vir_bytes len)
{
if(!unmap_ok)
return ENOSYS;
return _munmap_text(addrstart, len);
}