From 2e4ec2a85c9801553f0610fd584721d9b8a4c254 Mon Sep 17 00:00:00 2001 From: Martin Baulig Date: Mon, 10 Aug 1998 08:09:37 +0000 Subject: [PATCH] Some more work here. --- sysdeps/freebsd/open.c | 2 +- sysdeps/freebsd/prockernel.c | 4 ++ sysdeps/freebsd/proclist.c | 9 +++ sysdeps/freebsd/procmem.c | 124 ++++++++++++++++------------------- sysdeps/freebsd/procsignal.c | 4 ++ sysdeps/freebsd/procstate.c | 4 ++ sysdeps/freebsd/proctime.c | 39 +++++------ sysdeps/freebsd/procuid.c | 4 ++ 8 files changed, 102 insertions(+), 88 deletions(-) diff --git a/sysdeps/freebsd/open.c b/sysdeps/freebsd/open.c index 66b0f9e3..17ab20cc 100644 --- a/sysdeps/freebsd/open.c +++ b/sysdeps/freebsd/open.c @@ -70,7 +70,7 @@ glibtop_open_p (glibtop *server, const char *program_name, glibtop_error_io_r (server, "kvm_open"); /* Drop priviledges. */ - + if (setreuid (server->machine.euid, server->machine.uid)) _exit (1); diff --git a/sysdeps/freebsd/prockernel.c b/sysdeps/freebsd/prockernel.c index fbb45d40..8fd107aa 100644 --- a/sysdeps/freebsd/prockernel.c +++ b/sysdeps/freebsd/prockernel.c @@ -75,6 +75,8 @@ glibtop_get_proc_kernel_p (glibtop *server, memset (buf, 0, sizeof (glibtop_proc_kernel)); + glibtop_suid_enter (server); + /* Get the process information */ pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); if ((pinfo == NULL) || (count != 1)) @@ -126,6 +128,8 @@ glibtop_get_proc_kernel_p (glibtop *server, /* Taken from `wchan ()' in `/usr/src/bin/ps/print.c'. */ + glibtop_suid_leave (server); + buf->nwchan = (u_int64_t) pinfo [0].kp_proc.p_wchan &~ KERNBASE; if (pinfo [0].kp_proc.p_wchan && pinfo [0].kp_proc.p_wmesg) { diff --git a/sysdeps/freebsd/proclist.c b/sysdeps/freebsd/proclist.c index 2c1e371e..68d6f870 100644 --- a/sysdeps/freebsd/proclist.c +++ b/sysdeps/freebsd/proclist.c @@ -69,8 +69,17 @@ glibtop_get_proclist_p (glibtop *server, glibtop_proclist *buf, memset (buf, 0, sizeof (glibtop_proclist)); + glibtop_suid_enter (server); + /* Get the process data */ pinfo = kvm_getprocs (server->machine.kd, which, arg, &count); + if ((pinfo == NULL) || (count < 1)) + glibtop_error_io_r (server, "kvm_getprocs (proclist)"); + + glibtop_suid_leave (server); + + count--; + /* Allocate count objects in the pids_chain array * Same as malloc is pids is NULL, which it is. */ pids = glibtop_realloc_r (server, pids, count * sizeof (unsigned)); diff --git a/sysdeps/freebsd/procmem.c b/sysdeps/freebsd/procmem.c index e2295856..716688a7 100644 --- a/sysdeps/freebsd/procmem.c +++ b/sysdeps/freebsd/procmem.c @@ -27,27 +27,52 @@ #include #include -#include -#include #include #include #include -#include + +#include +#include +#include +#include static const unsigned long _glibtop_sysdeps_proc_mem = (1 << GLIBTOP_PROC_MEM_SIZE) + (1 << GLIBTOP_PROC_MEM_VSIZE) + (1 << GLIBTOP_PROC_MEM_RESIDENT) + -/* (1 << GLIBTOP_PROC_MEM_SHARE) + */ (1 << GLIBTOP_PROC_MEM_RSS) + (1 << GLIBTOP_PROC_MEM_RSS_RLIM); +#ifndef LOG1024 +#define LOG1024 10 +#endif + +/* these are for getting the memory statistics */ +static int pageshift; /* log base 2 of the pagesize */ + +/* define pagetok in terms of pageshift */ +#define pagetok(size) ((size) << pageshift) + /* Init function. */ void glibtop_init_proc_mem_p (glibtop *server) { + register int pagesize; + server->sysdeps.proc_mem = _glibtop_sysdeps_proc_mem; + + /* get the page size with "getpagesize" and calculate pageshift + * from it */ + pagesize = getpagesize (); + pageshift = 0; + while (pagesize > 1) { + pageshift++; + pagesize >>= 1; + } + + /* we only need the amount of log(2)1024 for our conversion */ + pageshift -= LOG1024; } /* Provides detailed information about a process. */ @@ -56,73 +81,36 @@ void glibtop_get_proc_mem_p (glibtop *server, glibtop_proc_mem *buf, pid_t pid) { -#if 0 struct kinfo_proc *pinfo; - struct vmspace vms; - struct vm_map vmm; - struct pstats ps; - int count, f; + struct user *u_addr = (struct user *)USRSTACK; + struct plimit plimit; + struct vmspace *vms; + int count; + + glibtop_suid_enter (server); + + /* Get the process data */ + pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); + if ((pinfo == NULL) || (count < 1)) + glibtop_error_io_r (server, "kvm_getprocs (proclist)"); + + if (kvm_read (server->machine.kd, + (unsigned long) pinfo [0].kp_proc.p_limit, + (char *) &plimit, sizeof (plimit)) != sizeof (plimit)) + glibtop_error_io_r (server, "kvm_read (plimit)"); + + buf->rss_rlim = (u_int64_t) + (plimit.pl_rlimit [RLIMIT_RSS].rlim_cur); - glibtop_init_p (server, GLIBTOP_SYSDEPS_PROC_MEM, 0); + glibtop_suid_leave (server); + + vms = &pinfo [0].kp_eproc.e_vm; + + buf->vsize = buf->size = (u_int64_t) pagetok + (vms->vm_tsize + vms->vm_dsize + vms->vm_ssize) << LOG1024; - memset (buf, 0, sizeof (glibtop_proc_mem)); + buf->resident = buf->rss = (u_int64_t) pagetok + (vms->vm_rssize) << LOG1024; - f = open ("/dev/kmem", O_RDONLY, NULL); - if (f == NULL) - glibtop_error_io_r (server, "open (/dev/kmem)"); - - /* Read the vmspace from kernel memeory */ - lseek (f, (long)pinfo[0].kp_proc.p_vmspace, SEEK_SET); - if (read (f, &vms, sizeof (struct vmspace)) < 0) - glibtop_error_io_r (server, "read"); - /* Read the vm_map from kernel memeory */ - /* [FIXME: ] lseek (f, (long) vms.vm_map, SEEK_SET); */ - if (read (f, &vmm, sizeof (struct vm_map)) < 0) - glibtop_error_io_r (server, "read"); - /* Read the pstats [for the RSS rlimit] from kernel memory. */ - lseek (f, (long)pinfo[0].kp_proc.p_stats, SEEK_SET); - if (read (f, &ps, sizeof (struct pstats)) < 0) - glibtop_error_io_r (server, "read"); - close (f); - - /* Get the process information */ - kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); - if (count != 1) { - /* Return no information */ - return; - } - - /* size: total # of pages in memory - (segsz_t)pinfo[0].kp_proc.p_vmspace.(vm_tsize + vm_dsize + vm_ssize) - */ - buf->size = (u_int64_t) (vms.vm_tsize + vms.vm_dsize + vms.vm_ssize); - /* vsize: number of pages of VM - (vm_size_t)pinfo[0].kp_proc.p_vmspace.vm_map.size - */ - buf->vsize = (u_int64_t) vmm.size; - - /* resident: number of resident (non-swapped) pages [4k] - (long)pmap_resident_count(pinfo[0]->kp_proc.p_vmspace.vm_map.pmap); - */ - buf->resident = (u_int64_t) pmap_resident_count (vmm.pmap); - - /* share: number of pages shared (mmap'd) memory - ??? vm_object has this info, but how to get it? - Even if we could, it's not reachable information. - */ - - - /* rss: resident set size - (segsz_t)kp_proc.p_vmspace.vm_rssize - */ - buf->rss = (u_int64_t) vms.vm_rssize; - /* rss_rlim: current rss limit [bytes] - (rlim_t)kp_proc.p_limit.pl_rlimit[RLIMIT_RSS].rlim_cur - or - (long)kp_proc.p_stats->p_ru.ru_maxrss */ - buf->rss_rlim = ps.p_ru.ru_maxrss; - - /* Set the flags */ buf->flags = _glibtop_sysdeps_proc_mem; -#endif } diff --git a/sysdeps/freebsd/procsignal.c b/sysdeps/freebsd/procsignal.c index 51436888..074d1568 100644 --- a/sysdeps/freebsd/procsignal.c +++ b/sysdeps/freebsd/procsignal.c @@ -51,11 +51,15 @@ glibtop_get_proc_signal_p (glibtop *server, memset (buf, 0, sizeof (glibtop_proc_signal)); + glibtop_suid_enter (server); + /* Get the process information */ pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); if ((pinfo == NULL) || (count != 1)) glibtop_error_io_r (server, "kvm_getprocs (%d)", pid); + glibtop_suid_leave (server); + /* signal: mask of pending signals. * pinfo [0].kp_proc.p_siglist */ diff --git a/sysdeps/freebsd/procstate.c b/sysdeps/freebsd/procstate.c index da9dd75e..3805ca06 100644 --- a/sysdeps/freebsd/procstate.c +++ b/sysdeps/freebsd/procstate.c @@ -53,11 +53,15 @@ glibtop_get_proc_state_p (glibtop *server, memset (buf, 0, sizeof (glibtop_proc_state)); + glibtop_suid_enter (server); + /* Get the process information */ pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); if ((pinfo == NULL) || (count != 1)) glibtop_error_io_r (server, "kvm_getprocs (%d)", pid); + glibtop_suid_leave (server); + strncpy (buf->cmd, pinfo [0].kp_proc.p_comm, sizeof (buf->cmd)-1); buf->cmd [sizeof (buf->cmd)-1] = 0; diff --git a/sysdeps/freebsd/proctime.c b/sysdeps/freebsd/proctime.c index bc5a19ca..c73d3ea0 100644 --- a/sysdeps/freebsd/proctime.c +++ b/sysdeps/freebsd/proctime.c @@ -26,10 +26,11 @@ #include static const unsigned long _glibtop_sysdeps_proc_time = -(1 << GLIBTOP_PROC_TIME_START_TIME) + (1 << GLIBTOP_PROC_TIME_UTIME) + -(1 << GLIBTOP_PROC_TIME_STIME) + (1 << GLIBTOP_PROC_TIME_CUTIME) + -(1 << GLIBTOP_PROC_TIME_CSTIME) + (1 << GLIBTOP_PROC_TIME_TIMEOUT) + -(1 << GLIBTOP_PROC_TIME_IT_REAL_VALUE); +(1 << GLIBTOP_PROC_TIME_RTIME) + (1 << GLIBTOP_PROC_TIME_FREQUENCY); + +static const unsigned long _glibtop_sysdeps_proc_time_user = +(1 << GLIBTOP_PROC_TIME_UTIME) + (1 << GLIBTOP_PROC_TIME_STIME) + +(1 << GLIBTOP_PROC_TIME_CUTIME) + (1 << GLIBTOP_PROC_TIME_CSTIME); #define tv2sec(tv) (((u_int64_t) tv.tv_sec * 1000000) + (u_int64_t) tv.tv_usec) @@ -38,7 +39,8 @@ static const unsigned long _glibtop_sysdeps_proc_time = void glibtop_init_proc_time_p (glibtop *server) { - server->sysdeps.proc_time = _glibtop_sysdeps_proc_time; + server->sysdeps.proc_time = _glibtop_sysdeps_proc_time | + _glibtop_sysdeps_proc_time_user; } /* Taken from /usr/src/sys/kern/kern_resource.c */ @@ -111,6 +113,8 @@ glibtop_get_proc_time_p (glibtop *server, glibtop_proc_time *buf, memset (buf, 0, sizeof (glibtop_proc_time)); + glibtop_suid_enter (server); + /* Get the process information */ pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); if ((pinfo == NULL) || (count != 1)) @@ -127,6 +131,8 @@ glibtop_get_proc_time_p (glibtop *server, glibtop_proc_time *buf, /* Well, we just do the same getrusage () does ... */ register struct rusage *rup; + + glibtop_suid_leave (server); rup = &pstats.p_ru; calcru(&(pinfo [0]).kp_proc, @@ -139,21 +145,16 @@ glibtop_get_proc_time_p (glibtop *server, glibtop_proc_time *buf, buf->cstime = tv2sec (pstats.p_cru.ru_stime); buf->start_time = tv2sec (pstats.p_start); + + buf->flags = _glibtop_sysdeps_proc_time_user; } -#if 0 - fprintf (stderr, "TIME: (%ld, %ld) - %ld (%ld, %ld) - %d (%d, %d, %d)\n", - (long) pinfo [0].kp_proc.p_rtime.tv_sec, - (long) pinfo [0].kp_proc.p_rtime.tv_usec, - (unsigned long) (buf->utime + buf->stime), - (unsigned long) buf->utime, - (unsigned long) buf->stime, - (int) pinfo [0].kp_proc.p_uticks + - (int) pinfo [0].kp_proc.p_sticks + - (int) pinfo [0].kp_proc.p_iticks, - (int) pinfo [0].kp_proc.p_uticks, - (int) pinfo [0].kp_proc.p_sticks, - (int) pinfo [0].kp_proc.p_iticks); -#endif + glibtop_suid_leave (server); + + buf->rtime = tv2sec (pinfo [0].kp_proc.p_rtime); + + buf->frequency = 1000000; + + buf->flags |= _glibtop_sysdeps_proc_time; } diff --git a/sysdeps/freebsd/procuid.c b/sysdeps/freebsd/procuid.c index 4015caf3..80e785dc 100644 --- a/sysdeps/freebsd/procuid.c +++ b/sysdeps/freebsd/procuid.c @@ -53,11 +53,15 @@ glibtop_get_proc_uid_p (glibtop *server, glibtop_proc_uid *buf, memset (buf, 0, sizeof (glibtop_proc_uid)); + glibtop_suid_enter (server); + /* Get the process information */ pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid, &count); if ((pinfo == NULL) || (count != 1)) glibtop_error_io_r (server, "kvm_getprocs (%d)", pid); + glibtop_suid_leave (server); + buf->uid = pinfo [0].kp_eproc.e_pcred.p_ruid; buf->euid = pinfo [0].kp_eproc.e_pcred.p_svuid; buf->gid = pinfo [0].kp_eproc.e_pcred.p_rgid;