Fixed 'ps' utility: now get process table addresses with getsysinfo() calls.

To be done: get copies of process tables instead of using /dev/(k)mem.
This commit is contained in:
Jorrit Herder 2005-06-06 13:51:50 +00:00
parent cde16504a1
commit 2f74381dcc
12 changed files with 97 additions and 40 deletions

View file

@ -13,7 +13,7 @@
*
* VERY IMPORTANT NOTE:
* To compile ps, the kernel/, fs/ and pm/ source directories must be in
* ../ relative to the directory where ps is compiled (normally the
* ../../ relative to the directory where ps is compiled (normally the
* tools source directory).
*
* If you want your ps to be useable by anyone, you can arrange the
@ -75,12 +75,10 @@
#include "../../kernel/const.h"
#include "../../kernel/type.h"
#include "../../kernel/proc.h"
#undef printf /* kernel's const.h defined this */
#include "../../servers/pm/mproc.h"
#include "../../servers/fs/fproc.h"
#include "../../servers/fs/const.h"
#undef printf /* fs's const.h defined this */
/*----- ps's local stuff below this line ------*/
@ -103,8 +101,11 @@ size_t n_ttyinfo; /* Number of tty info slots */
/* Macro to convert memory offsets to rounded kilo-units */
#define off_to_k(off) ((unsigned) (((off) + 512) / 1024))
/* Number of tasks and processes. */
int nr_tasks, nr_procs;
/* Number of tasks and processes and addresses of the main process tables. */
int nr_tasks, nr_procs;
vir_bytes proc_addr, mproc_addr, fproc_addr;
extern int errno;
/* Process tables of the kernel, MM, and FS. */
struct proc *ps_proc;
@ -133,6 +134,7 @@ int kmemfd, memfd; /* file descriptors of [k]mem */
#define L_HEADER " F S UID PID PPID PGRP SZ RECV TTY TIME CMD\n"
#define L_FORMAT "%3o %c %3d %5s %5d %5d %4d %10s %3s %s %s\n"
struct pstat { /* structure filled by pstat() */
dev_t ps_dev; /* major/minor of controlling tty */
uid_t ps_ruid; /* real uid */
@ -273,10 +275,11 @@ char *argv[];
char *ke_path; /* paths of kernel, */
char *mm_path; /* mm, */
char *fs_path; /* and fs used in ps -U */
struct psinfo psinfo;
char pid[2 + sizeof(pid_t) * 3];
unsigned long ustime;
char cpu[sizeof(clock_t) * 3 + 1 + 2];
struct kinfo kinfo;
int s;
(void) signal(SIGSEGV, disaster); /* catch a common crash */
@ -298,10 +301,13 @@ char *argv[];
if ((kmemfd = open(KMEM_PATH, O_RDONLY)) == -1) err(KMEM_PATH);
if ((memfd = open(MEM_PATH, O_RDONLY)) == -1) err(MEM_PATH);
if (gettynames() == -1) err("Can't get tty names");
if (ioctl(memfd, MIOCGPSINFO, (void *) &psinfo) == -1)
err("can't get PS info from kernel");
nr_tasks = psinfo.nr_tasks;
nr_procs = psinfo.nr_procs;
getsysinfo(PM_PROC_NR, SI_PROC_ADDR, &mproc_addr);
getsysinfo(FS_PROC_NR, SI_PROC_ADDR, &fproc_addr);
getsysinfo(PM_PROC_NR, SI_KINFO, &kinfo);
proc_addr = kinfo.proc_addr;
nr_tasks = kinfo.nr_tasks;
nr_procs = kinfo.nr_procs;
/* Allocate memory for process tables */
ps_proc = (struct proc *) malloc((nr_tasks + nr_procs) * sizeof(ps_proc[0]));
@ -312,19 +318,19 @@ char *argv[];
/* Get kernel process table */
if (addrread(kmemfd, (phys_clicks) 0,
psinfo.proc, (char *) ps_proc,
proc_addr, (char *) ps_proc,
(nr_tasks + nr_procs) * sizeof(ps_proc[0]))
!= (nr_tasks + nr_procs) * sizeof(ps_proc[0]))
err("Can't get kernel proc table from /dev/kmem");
/* Get mm/fs process tables */
if (addrread(memfd, ps_proc[nr_tasks + PM_PROC_NR].p_memmap[D].mem_phys,
psinfo.mproc, (char *) ps_mproc,
mproc_addr, (char *) ps_mproc,
nr_procs * sizeof(ps_mproc[0]))
!= nr_procs * sizeof(ps_mproc[0]))
err("Can't get mm proc table from /dev/mem");
if (addrread(memfd, ps_proc[nr_tasks + FS_PROC_NR].p_memmap[D].mem_phys,
psinfo.fproc, (char *) ps_fproc,
fproc_addr, (char *) ps_fproc,
nr_procs * sizeof(ps_fproc[0]))
!= nr_procs * sizeof(ps_fproc[0]))
err("Can't get fs proc table from /dev/mem");
@ -360,7 +366,7 @@ char *argv[];
if (opt_long) printf(L_FORMAT,
buf.ps_flags, buf.ps_state,
buf.ps_euid, pid, buf.ps_ppid,
buf.ps_euid, pid, buf.ps_ppid,
buf.ps_pgrp,
off_to_k((buf.ps_tsize
+ buf.ps_stack - buf.ps_data
@ -513,8 +519,8 @@ struct pstat *bufp;
bufp->ps_recv = ps_proc[p_ki].p_getfrom;
bufp->ps_utime = ps_proc[p_ki].user_time;
bufp->ps_stime = ps_proc[p_ki].sys_time;
bufp->ps_utime = ps_proc[p_ki].p_user_time;
bufp->ps_stime = ps_proc[p_ki].p_sys_time;
bufp->ps_procargs = ps_mproc[p_nr].mp_procargs;

View file

@ -88,11 +88,6 @@ struct sigmsg {
#define MESS_SIZE (sizeof(message)) /* might need usizeof from fs here */
#define NIL_MESS ((message *) 0)
struct psinfo { /* information for the ps(1) program */
u16_t nr_tasks, nr_procs; /* NR_TASKS and NR_PROCS constants. */
vir_bytes proc, mproc, fproc; /* addresses of the main process tables. */
};
/* This is used to obtain system information through SYS_GETINFO. */
struct kinfo {
phys_bytes code_base; /* base of kernel code */

View file

@ -35,6 +35,11 @@
#define RBT_RESET 4 /* hard reset the system */
#endif
/* What system info to retrieve with sysgetinfo(). */
#define SI_KINFO 0 /* get kernel info via PM */
#define SI_PROC_ADDR 1 /* address of process table */
#define SI_PROC_TAB 2 /* copy of entire process table */
/* NULL must be defined in <unistd.h> according to POSIX Sec. 2.7.1. */
#define NULL ((void *)0)

View file

@ -9,7 +9,6 @@ int what; /* what information is requested */
void *where; /* where to put it */
{
message m;
m.m1_i1 = what;
m.m1_p1 = where;
if (_syscall(who, GETSYSINFO, &m) < 0) return(-1);

View file

@ -46,6 +46,7 @@ OBJECTS = \
$(LIBRARY)(getppid.o) \
$(LIBRARY)(getuid.o) \
$(LIBRARY)(getprocnr.o) \
$(LIBRARY)(getsysinfo.o) \
$(LIBRARY)(findproc.o) \
$(LIBRARY)(ioctl.o) \
$(LIBRARY)(isatty.o) \
@ -224,6 +225,9 @@ $(LIBRARY)(getpid.o): getpid.s
$(LIBRARY)(getppid.o): getppid.s
$(CC1) getppid.s
$(LIBRARY)(getsysinfo.o): getsysinfo.s
$(CC1) getsysinfo.s
$(LIBRARY)(getprocnr.o): getprocnr.s
$(CC1) getprocnr.s

View file

@ -23,7 +23,7 @@ EXTERN struct buf {
zone_t b__v2_ind[V2_INDIRECTS(MAX_BLOCK_SIZE)]; /* V2 indirect block */
d1_inode b__v1_ino[V1_INODES_PER_BLOCK]; /* V1 inode block */
d2_inode b__v2_ino[V2_INODES_PER_BLOCK(MAX_BLOCK_SIZE)]; /* V2 inode block */
bitchunk_t b__bitmap[BITMAP_CHUNKS(MAX_BLOCK_SIZE)]; /* bit map block */
bitchunk_t b__bitmap[FS_BITMAP_CHUNKS(MAX_BLOCK_SIZE)]; /* bit map block */
} b;
/* Header portion of the buffer. */

View file

@ -66,9 +66,10 @@
#define NR_DIR_ENTRIES(b) ((b)/DIR_ENTRY_SIZE) /* # dir entries/blk */
#define SUPER_SIZE usizeof (struct super_block) /* super_block size */
#define PIPE_SIZE(b) (V1_NR_DZONES*(b)) /* pipe size in bytes */
#define BITMAP_CHUNKS(b) ((b)/usizeof (bitchunk_t))/* # map chunks/blk */
#define BITCHUNK_BITS (usizeof(bitchunk_t) * CHAR_BIT)
#define BITS_PER_BLOCK(b) (BITMAP_CHUNKS(b) * BITCHUNK_BITS)
#define FS_BITMAP_CHUNKS(b) ((b)/usizeof (bitchunk_t))/* # map chunks/blk */
#define FS_BITCHUNK_BITS (usizeof(bitchunk_t) * CHAR_BIT)
#define FS_BITS_PER_BLOCK(b) (FS_BITMAP_CHUNKS(b) * FS_BITCHUNK_BITS)
/* Derived sizes pertaining to the V1 file system. */
#define V1_ZONE_NUM_SIZE usizeof (zone1_t) /* # bytes in V1 zone */

View file

@ -35,7 +35,26 @@
*===========================================================================*/
PUBLIC int do_getsysinfo()
{
struct fproc *proc_addr;
vir_bytes src_addr, dst_addr;
size_t len;
int s;
switch(m_in.info_what) {
case SI_PROC_ADDR:
proc_addr = &fproc[0];
src_addr = (vir_bytes) &proc_addr;
len = sizeof(struct fproc *);
break;
default:
return(EINVAL);
}
dst_addr = (vir_bytes) m_in.info_where;
if (OK != (s=sys_datacopy(SELF, src_addr, who, dst_addr, len)))
return(s);
return(OK);
}

View file

@ -45,6 +45,8 @@
#define svrctl_req m2_i1
#define svrctl_argp m2_p1
#define pm_stime m1_i1
#define info_what m1_i1
#define info_where m1_p1
/* The following names are synonyms for the variables in the output message. */
#define reply_type m_type

View file

@ -54,14 +54,14 @@ bit_t origin; /* number of bit to start searching at */
if (origin >= map_bits) origin = 0; /* for robustness */
/* Locate the starting place. */
block = origin / BITS_PER_BLOCK(sp->s_block_size);
word = (origin % BITS_PER_BLOCK(sp->s_block_size)) / BITCHUNK_BITS;
block = origin / FS_BITS_PER_BLOCK(sp->s_block_size);
word = (origin % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS;
/* Iterate over all blocks plus one, because we start in the middle. */
bcount = bit_blocks + 1;
do {
bp = get_block(sp->s_dev, start_block + block, NORMAL);
wlim = &bp->b_bitmap[BITMAP_CHUNKS(sp->s_block_size)];
wlim = &bp->b_bitmap[FS_BITMAP_CHUNKS(sp->s_block_size)];
/* Iterate over the words in block. */
for (wptr = &bp->b_bitmap[word]; wptr < wlim; wptr++) {
@ -74,8 +74,8 @@ bit_t origin; /* number of bit to start searching at */
for (i = 0; (k & (1 << i)) != 0; ++i) {}
/* Bit number from the start of the bit map. */
b = ((bit_t) block * BITS_PER_BLOCK(sp->s_block_size))
+ (wptr - &bp->b_bitmap[0]) * BITCHUNK_BITS
b = ((bit_t) block * FS_BITS_PER_BLOCK(sp->s_block_size))
+ (wptr - &bp->b_bitmap[0]) * FS_BITCHUNK_BITS
+ i;
/* Don't allocate bits beyond the end of the map. */
@ -119,9 +119,9 @@ bit_t bit_returned; /* number of bit to insert into the map */
} else {
start_block = START_BLOCK + sp->s_imap_blocks;
}
block = bit_returned / BITS_PER_BLOCK(sp->s_block_size);
word = (bit_returned % BITS_PER_BLOCK(sp->s_block_size)) / BITCHUNK_BITS;
bit = bit_returned % BITCHUNK_BITS;
block = bit_returned / FS_BITS_PER_BLOCK(sp->s_block_size);
word = (bit_returned % FS_BITS_PER_BLOCK(sp->s_block_size)) / FS_BITCHUNK_BITS;
bit = bit_returned % FS_BITCHUNK_BITS;
mask = 1 << bit;
bp = get_block(sp->s_dev, start_block + block, NORMAL);

View file

@ -53,18 +53,42 @@ PUBLIC int do_freemem()
return(OK);
}
/*=====================================================================*
* do_getsysinfo *
*=====================================================================*/
/*===========================================================================*
* do_getsysinfo *
*===========================================================================*/
PUBLIC int do_getsysinfo()
{
struct mproc *proc_addr;
vir_bytes src_addr, dst_addr;
struct kinfo kinfo;
size_t len;
int s;
switch(m_in.info_what) {
case SI_KINFO: /* kernel info is obtained via PM */
sys_getkinfo(&kinfo);
src_addr = (vir_bytes) &kinfo;
len = sizeof(struct kinfo);
break;
case SI_PROC_ADDR: /* get address of PM process table */
proc_addr = &mproc[0];
src_addr = (vir_bytes) &proc_addr;
len = sizeof(struct mproc *);
break;
default:
return(EINVAL);
}
dst_addr = (vir_bytes) m_in.info_where;
if (OK != (s=sys_datacopy(SELF, src_addr, who, dst_addr, len)))
return(s);
return(OK);
}
/*=====================================================================*
* do_getprocnr *
*=====================================================================*/
/*===========================================================================*
* do_getprocnr *
*===========================================================================*/
PUBLIC int do_getprocnr()
{
register struct mproc *rmp;

View file

@ -27,6 +27,8 @@
#ifdef _SIGMESSAGE
#define sig_msg m1_i1
#endif
#define info_what m1_i1
#define info_where m1_p1
#define reboot_flag m1_i1
#define reboot_code m1_p1
#define reboot_size m1_i2