#define SI_CALL_STATS 9 /* system call statistics */
#define SI_PROCPUB_TAB 11 /* copy of public entries of process table */
#define SI_PROCALL_TAB 12 /* copy of both private and public entries */
+#define SI_PROCLIGHT_TAB 13 /* copy of light version of process table */
#endif
typedef struct proc ixfer_proc_t;
typedef struct mproc ixfer_mproc_t;
-typedef struct fproc ixfer_fproc_t;
static ixfer_proc_t proc_tab[NR_TASKS + NR_PROCS];
static ixfer_mproc_t mproc_tab[NR_PROCS];
-static ixfer_fproc_t fproc_tab[NR_PROCS];
+static struct fproc_light fproc_tab[NR_PROCS];
/*
* The number of processes added to the current number of processes when doing
}
}
- /* Retrieve the VFS process table, which has no magic number. */
- r = getsysinfo(VFS_PROC_NR, SI_PROC_TAB, fproc_tab, sizeof(fproc_tab));
+ /* Retrieve an extract of the VFS process table. */
+ r = getsysinfo(VFS_PROC_NR, SI_PROCLIGHT_TAB, fproc_tab,
+ sizeof(fproc_tab));
if (r != OK) {
printf("MIB: unable to obtain VFS process table (%d)\n", r);
int32_t * flag)
{
struct mproc *mp;
- struct fproc *fp;
+ struct fproc_light *fp;
struct proc *kp;
const char *wmesg;
uint64_t wchan;
} else if (mp->mp_flags & SIGSUSPENDED) {
wchan = 0x202;
wmesg = "pause";
- } else if (fp->fp_blocked_on != FP_BLOCKED_ON_NONE) {
- wchan = (fp->fp_blocked_on << 8) | 0x03;
- switch (fp->fp_blocked_on) {
+ } else if (fp->fpl_blocked_on != FP_BLOCKED_ON_NONE) {
+ wchan = (fp->fpl_blocked_on << 8) | 0x03;
+ switch (fp->fpl_blocked_on) {
case FP_BLOCKED_ON_PIPE:
wmesg = "pipe";
break;
* wchan value, and use the driver's process name,
* without parentheses, as wmesg text.
*/
- wchan |= (uint64_t)fp->fp_task << 16;
- fill_wmesg(wmptr, wmsz, fp->fp_task, FALSE /*ipc*/);
+ wchan |= (uint64_t)fp->fpl_task << 16;
+ fill_wmesg(wmptr, wmsz, fp->fpl_task, FALSE /*ipc*/);
break;
default:
/* A newly added flag we don't yet know about? */
fill_proc2_user(struct kinfo_proc2 * p, int mslot)
{
struct mproc *mp;
- struct fproc *fp;
+ struct fproc_light *fp;
time_t boottime;
dev_t tty;
struct timeval tv;
fp = &fproc_tab[mslot];
zombie = (mp->mp_flags & (TRACE_ZOMBIE | ZOMBIE));
- tty = (!zombie) ? fp->fp_tty : NO_DEV;
+ tty = (!zombie) ? fp->fpl_tty : NO_DEV;
p->p_eflag = 0;
if (tty != NO_DEV)
continue; /* TODO: revoke(2) support */
/* Do not access the fproc_tab slot of zombies. */
zombie = (mp->mp_flags & (TRACE_ZOMBIE | ZOMBIE));
- tty = (zombie) ? fproc_tab[mslot].fp_tty : NO_DEV;
+ tty = (zombie) ? fproc_tab[mslot].fpl_tty : NO_DEV;
if ((dev_t)arg == KERN_PROC_TTY_NODEV) {
if (tty != NO_DEV)
continue;
/* Set up the child and its memory map; copy its 'mproc' slot from parent. */
procs_in_use++;
*rmc = *rmp; /* copy parent's process slot to child's */
+ rmc->mp_sigact = mpsigact[next_child]; /* restore mp_sigact ptr */
+ memcpy(rmc->mp_sigact, rmp->mp_sigact, sizeof(mpsigact[next_child]));
rmc->mp_parent = who_p; /* record child's parent */
if (!(rmc->mp_trace_flags & TO_TRACEFORK)) {
rmc->mp_tracer = NO_TRACER; /* no tracer attached */
/* Set up the child and its memory map; copy its 'mproc' slot from parent. */
procs_in_use++;
*rmc = *rmp; /* copy parent's process slot to child's */
+ rmc->mp_sigact = mpsigact[next_child]; /* restore mp_sigact ptr */
+ memcpy(rmc->mp_sigact, rmp->mp_sigact, sizeof(mpsigact[next_child]));
rmc->mp_parent = who_p; /* record child's parent */
if (!(rmc->mp_trace_flags & TO_TRACEFORK)) {
rmc->mp_tracer = NO_TRACER; /* no tracer attached */
for (rmp=&mproc[0]; rmp<&mproc[NR_PROCS]; rmp++) {
init_timer(&rmp->mp_timer);
rmp->mp_magic = MP_MAGIC;
+ rmp->mp_sigact = mpsigact[rmp - mproc];
}
/* Build the set of signals which cause core dumps, and the set of signals
/* Needs to be included here, for 'ps' etc */
#include "const.h"
+/*
+ * The per-process sigaction structures are stored outside of the mproc table,
+ * so that the MIB service can avoid pulling them in, as they account for
+ * roughly 80% of the per-process state.
+ */
typedef struct sigaction ixfer_sigaction;
+EXTERN ixfer_sigaction mpsigact[NR_PROCS][_NSIG];
EXTERN struct mproc {
char mp_exitstatus; /* storage for status when process exits */
sigset_t mp_sigpending; /* pending signals to be handled */
sigset_t mp_ksigpending; /* bitmap for pending signals from the kernel */
sigset_t mp_sigtrace; /* signals to hand to tracer first */
- ixfer_sigaction mp_sigact[_NSIG]; /* as in sigaction(2) */
-#ifdef __ACK__
- char mp_padding[60]; /* align structure with new libc */
-#endif
+ ixfer_sigaction *mp_sigact; /* as in sigaction(2), pointer into mpsigact */
vir_bytes mp_sigreturn; /* address of C library __sigreturn function */
minix_timer_t mp_timer; /* watchdog timer for alarm(2), setitimer(2) */
clock_t mp_interval[NR_ITIMERS]; /* setitimer(2) repetition intervals */
#define REVIVING 0xDEEAD /* process is being revived from suspension */
#define PID_FREE 0 /* process slot free */
+/*
+ * Upon request from the MIB service, this table is filled with a relatively
+ * small subset of per-process fields, so that the MIB service can avoid
+ * pulling in the entire fproc table. Other fields may be added to this
+ * structure as required by the MIB service.
+ */
+EXTERN struct fproc_light {
+ dev_t fpl_tty; /* copy of fproc.fp_tty */
+ int fpl_blocked_on; /* copy of fproc.fp_blocked_on */
+ endpoint_t fpl_task; /* copy of fproc.fp_task */
+} fproc_light[NR_PROCS];
+
#endif /* __VFS_FPROC_H__ */
*===========================================================================*/
int do_getsysinfo(void)
{
+ struct fproc *rfp;
+ struct fproc_light *rfpl;
vir_bytes src_addr, dst_addr;
size_t len, buf_size;
int what;
src_addr = (vir_bytes) dmap;
len = sizeof(struct dmap) * NR_DEVICES;
break;
+ case SI_PROCLIGHT_TAB:
+ /* Fill the light process table for the MIB service upon request. */
+ rfpl = &fproc_light[0];
+ for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++, rfpl++) {
+ rfpl->fpl_tty = rfp->fp_tty;
+ rfpl->fpl_blocked_on = rfp->fp_blocked_on;
+ rfpl->fpl_task = rfp->fp_task;
+ }
+ src_addr = (vir_bytes) fproc_light;
+ len = sizeof(fproc_light);
+ break;
#if ENABLE_SYSCALL_STATS
case SI_CALL_STATS:
src_addr = (vir_bytes) calls_stats;