diff --git a/servers/pm/Makefile b/servers/pm/Makefile index b33e408de..eb43f436f 100644 --- a/servers/pm/Makefile +++ b/servers/pm/Makefile @@ -18,7 +18,7 @@ LDFLAGS = -i 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 \ - profile.o dma.o + profile.o dma.o # build local binary all build: $(SERVER) diff --git a/servers/pm/break.c b/servers/pm/break.c index b2afdf823..71779cb96 100644 --- a/servers/pm/break.c +++ b/servers/pm/break.c @@ -13,8 +13,8 @@ PUBLIC int do_brk() { int r; /* Entry point to brk(addr) system call. */ - r = vm_brk(mp->mp_endpoint, m_in.addr); - mp->mp_reply.reply_ptr = (r == OK ? m_in.addr : (char *) -1); + r = vm_brk(mp->mp_endpoint, m_in.PMBRK_ADDR); + mp->mp_reply.reply_ptr = (r == OK ? m_in.PMBRK_ADDR : (char *) -1); return r; } diff --git a/servers/pm/exec.c b/servers/pm/exec.c index 3f9a0411d..054908480 100644 --- a/servers/pm/exec.c +++ b/servers/pm/exec.c @@ -113,6 +113,8 @@ PUBLIC int exec_newmem() mp->mp_reply.reply_res3= flags; if (allow_setuid) mp->mp_reply.reply_res3 |= EXC_NM_RF_ALLOW_SETUID; + } else { + printf("PM: newmem failed for %s\n", args.progname); } return r; } diff --git a/servers/pm/forkexit.c b/servers/pm/forkexit.c index 0cdc7c24d..36fe0a36b 100644 --- a/servers/pm/forkexit.c +++ b/servers/pm/forkexit.c @@ -248,6 +248,7 @@ int dump_core; /* flag indicating whether to dump core */ if((r=vm_willexit(proc_nr_e)) != OK) { panic(__FILE__, "exit_proc: vm_willexit failed", r); } + vm_notify_sig_wrapper(rmp->mp_endpoint); if (proc_nr_e == INIT_PROC_NR) { @@ -276,8 +277,7 @@ int dump_core; /* flag indicating whether to dump core */ } else { - printf("PM: FS died\n"); - return; + panic(__FILE__, "pm_exit: FS died", r); } /* The process is now officially exiting. The ZOMBIE flag is not enough, as diff --git a/servers/pm/getset.c b/servers/pm/getset.c index dd0868aec..7b26a2482 100644 --- a/servers/pm/getset.c +++ b/servers/pm/getset.c @@ -7,6 +7,7 @@ #include "pm.h" #include #include +#include #include #include "mproc.h" #include "param.h" @@ -29,17 +30,21 @@ PUBLIC int do_getset() case GETUID: r = rmp->mp_realuid; 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; case GETGID: r = rmp->mp_realgid; 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; - case GETPID: + case MINIX_GETPID: r = mproc[who_p].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; break; diff --git a/servers/pm/main.c b/servers/pm/main.c index c77caff92..586c21e4b 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -208,6 +209,8 @@ int result; /* result of call (usually OK or error #) */ rmp->mp_flags |= REPLY; /* reply pending */ } +extern int unmap_ok; + /*===========================================================================* * pm_init * *===========================================================================*/ @@ -340,6 +343,17 @@ PRIVATE void pm_init() if(f > 0) printf("PM: failed to register %d processes with DS.\n", f); 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(); } /*===========================================================================* diff --git a/servers/pm/misc.c b/servers/pm/misc.c index fe92eed81..fd752f242 100644 --- a/servers/pm/misc.c +++ b/servers/pm/misc.c @@ -325,7 +325,7 @@ 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.endpt = rmp->mp_endpoint; + mp->mp_reply.PM_ENDPT = rmp->mp_endpoint; #if 0 printf("PM: pid result: %d\n", rmp->mp_endpoint); #endif @@ -335,27 +335,24 @@ PUBLIC int do_getprocnr() 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_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))) 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 | EXITING)) == IN_USE) && strncmp(rmp->mp_name, search_key, key_len)==0) { - mp->mp_reply.endpt = rmp->mp_endpoint; - printf("PM: name %s result: %d\n", search_key, - rmp->mp_endpoint); + mp->mp_reply.PM_ENDPT = rmp->mp_endpoint; return(OK); } } - printf("PM: name %s result: ESRCH\n", search_key); return(ESRCH); } else { /* return own/parent process number */ #if 0 - printf("PM: endpt result: %d\n", mp->mp_reply.endpt); + printf("PM: endpt result: %d\n", mp->mp_reply.PM_ENDPT); #endif - mp->mp_reply.endpt = who_e; - mp->mp_reply.pendpt = mproc[mp->mp_parent].mp_endpoint; + mp->mp_reply.PM_ENDPT = who_e; + mp->mp_reply.PM_PENDPT = mproc[mp->mp_parent].mp_endpoint; } return(OK); @@ -378,7 +375,7 @@ PUBLIC int do_getpuid() return EPERM; } - ep= m_in.endpt; + ep= m_in.PM_ENDPT; for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) { if ((rmp->mp_flags & IN_USE) && (rmp->mp_endpoint == ep)) { diff --git a/servers/pm/param.h b/servers/pm/param.h index c199c5594..4bf19d969 100644 --- a/servers/pm/param.h +++ b/servers/pm/param.h @@ -1,13 +1,10 @@ /* The following names are synonyms for the variables in the input message. */ -#define addr m1_p1 #define exec_name m1_p1 #define exec_len m1_i1 #define func m6_f1 #define grp_id m1_i1 #define namelen m1_i2 #define pid m1_i1 -#define endpt m1_i1 -#define pendpt m1_i2 #define seconds m1_i1 #define which_timer m1_i1 #define new_val m1_p1 @@ -18,7 +15,6 @@ #define status m1_i1 #define usr_id m1_i1 #define request m2_i2 -#define taddr m2_l1 #define data m2_l2 #define sig_nr m1_i2 #define sig_nsa m1_p1 diff --git a/servers/pm/signal.c b/servers/pm/signal.c index ca1c73f6a..c9244d246 100644 --- a/servers/pm/signal.c +++ b/servers/pm/signal.c @@ -306,6 +306,28 @@ PUBLIC int do_pause() 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 * *===========================================================================*/ @@ -411,6 +433,7 @@ int signo; /* signal to send to process (1 to _NSIG) */ * ready. */ unpause(slot, FALSE /*!for_trace*/); + vm_notify_sig_wrapper(rmp->mp_endpoint); return; } else if (sigismember(&rmp->mp_sig2mess, signo)) { diff --git a/servers/pm/trace.c b/servers/pm/trace.c index fb3fc656d..004fc73c1 100644 --- a/servers/pm/trace.c +++ b/servers/pm/trace.c @@ -55,7 +55,7 @@ PUBLIC int do_trace() if ((child=find_proc(m_in.pid))==NIL_MPROC) 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); mp->mp_reply.reply_trace = m_in.data; @@ -80,7 +80,7 @@ PUBLIC int do_trace() child->mp_ctime= 0; #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); mp->mp_reply.reply_trace = m_in.data; @@ -135,7 +135,7 @@ PUBLIC int do_trace() child->mp_flags &= ~STOPPED; 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); mp->mp_reply.reply_trace = m_in.data; diff --git a/servers/pm/utility.c b/servers/pm/utility.c index a479ed461..2e1838dfc 100644 --- a/servers/pm/utility.c +++ b/servers/pm/utility.c @@ -28,6 +28,12 @@ #include "../../kernel/type.h" #include "../../kernel/proc.h" +#define munmap _munmap +#define munmap_text _munmap_text +#include +#undef munmap +#undef munmap_text + /*===========================================================================* * get_free_pid * *===========================================================================*/ @@ -111,3 +117,21 @@ PUBLIC int pm_isokendpt(int endpoint, int *proc) 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); + +}