Skip Menu |
 

This queue is for tickets about the Proc-ProcessTable CPAN distribution.

Report information
The Basics
Id: 16978
Status: resolved
Priority: 0/
Queue: Proc-ProcessTable

People
Owner: Nobody in particular
Requestors: cfaber [...] fpsn.net
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: (no value)
Fixed in: (no value)

Attachments
0001-FreeBSD-procfs-implementation-fixed-all-fields-with-.patch
0002-FreeBSD-procfs-implementation-FreeBSD-6.0-and-later-.patch
FREEBSD.patch



Subject: Proc::ProcessTable fails to report correct information under FreeBSD 6.0
Download (untitled) / with headers
text/plain 1.9k
Running the sample script provided does work, however some fields do not contain useful information, Likely beacuse of a change in the OS: # Dump all the information in the current process table use Proc::ProcessTable; $t = new Proc::ProcessTable; foreach $p (@{$t->table}) { print "--------------------------------\n"; foreach $f ($t->fields){ print $f, ": ", $p->{$f}, "\n"; } } Sample result: -------------------------------- uid: 0 gid: 0 pid: 13 ppid: 0 pgrp: 0 sess: 0 flags: utime: 0.000000 stime: 0.000000 time: 0.000000 wchan: start: 0.000000 euid: 0 egid: 0 fname: idle:\040cpu1 state: ttydev: ttynum: 0 cmndline: idle: cpu1 priority: 0 -------------------------------- uid: 0 gid: 0 pid: 12 ppid: 0 pgrp: 0 sess: 0 flags: utime: 0.000000 stime: 0.000000 time: 0.000000 wchan: start: 0.000000 euid: 0 egid: 0 fname: idle:\040cpu2 state: ttydev: ttynum: 0 cmndline: idle: cpu2 priority: 0 -------------------------------- uid: 0 gid: 0 pid: 11 ppid: 0 pgrp: 0 sess: 0 flags: utime: 0.000000 stime: 0.000000 time: 0.000000 wchan: start: 0.000000 euid: 0 egid: 0 fname: idle:\040cpu3 state: ttydev: ttynum: 0 cmndline: idle: cpu3 priority: 0 -------------------------------- uid: 0 gid: 0 pid: 1 ppid: 0 pgrp: 1 sess: 1 flags: utime: 0.000000 stime: 0.000000 time: 0.000000 wchan: start: 0.000000 euid: 0 egid: 0 fname: init state: ttydev: ttynum: 0 cmndline: /sbin/init -- priority: 0 -------------------------------- uid: 0 gid: 0 pid: 10 ppid: 0 pgrp: 0 sess: 0 flags: utime: 0.000000 stime: 0.000000 time: 0.000000 wchan: start: 0.000000 euid: 0 egid: 0 fname: ktrace state: ttydev: ttynum: 0 cmndline: ktrace priority: 0 -------------------------------- uid: 0 gid: 0 pid: 0 ppid: 0 pgrp: 0 sess: 0 flags: utime: 0.000000 stime: 0.000000 time: 0.000000 wchan: start: 0.000000 euid: 0 egid: 0 fname: swapper state: ttydev: ttynum: 0 cmndline: swapper priority: 0
Download (untitled) / with headers
text/plain 461b
On Mon Jan 09 12:24:24 2006, guest wrote: Show quoted text
> Running the sample script provided does work, however some fields do > not contain useful information, Likely beacuse of a change in the OS:
[...] Indeed, in FreeBSD 6.0 the format of /proc/.../status changed. Attached are two patches. One is fixing the always broken microsecs calculation, and the second is fixing the changed procfs format, but still retaining the old pre-6.0 implementation. Regards, Slaven
Subject: 0002-FreeBSD-procfs-implementation-FreeBSD-6.0-and-later-.patch
From 712c79f035276249a6e5bc119b9bb6b23ef21f42 Mon Sep 17 00:00:00 2001 From: Slaven Rezic <slaven@rezic.de> Date: Sat, 13 Feb 2010 00:01:31 +0100 Subject: [PATCH 2/2] FreeBSD, procfs implementation: FreeBSD 6.0 and later changed procfs format --- os/FreeBSD.c | 21 +++++++++++++++++++++ os/FreeBSD.h | 12 ++++++++++++ 2 files changed, 33 insertions(+), 0 deletions(-) diff --git a/os/FreeBSD.c b/os/FreeBSD.c index a294b79..a4b2cac 100644 --- a/os/FreeBSD.c +++ b/os/FreeBSD.c @@ -8,14 +8,22 @@ struct procstat* get_procstat( char* path, struct procstat* prs){ if( (fp = fopen( path, "r" )) != NULL ){ fscanf(fp, +#ifdef PROCFS_FREEBSD_6 + "%s %d %d %d %d %s %s %d,%d %d,%d %d,%d %s %d %d %d,%d,%s", +#else "%s %d %d %d %d %d,%d %s %d,%d %d,%d %d,%d %s %d %d %d,%d,%s", +#endif &prs->comm, &prs->pid, &prs->ppid, &prs->pgid, &prs->sid, +#ifdef PROCFS_FREEBSD_6 + &prs->ttydev, +#else &prs->tdev_maj, &prs->tdev_min, +#endif &prs->flags, &prs->start, &prs->start_mic, @@ -93,6 +101,9 @@ void OS_get_table(){ double start_f; char *ttydev; int ttynum; +#ifdef PROCFS_FREEBSD_6 + struct stat tdev_stat; +#endif utime_f = prs.utime + prs.utime_mic/1000000.0; stime_f = prs.stime + prs.stime_mic/1000000.0; @@ -104,9 +115,19 @@ void OS_get_table(){ sprintf(time, "%f", time_f); sprintf(start, "%f", start_f); +#ifdef PROCFS_FREEBSD_6 + ttydev = prs.ttydev; + sprintf(pathbuf, "/dev/%s", ttydev); + if (stat(pathbuf, &tdev_stat) < 0){ + ttynum = -1; + } else { + ttynum = tdev_stat.st_rdev; + } +#else ttynum = makedev(prs.tdev_maj, prs.tdev_min); ttydev = devname(ttynum, S_IFCHR); if (ttydev == NULL) ttydev = "??"; +#endif /* get stuff out of /proc/PROC_ID/cmdline */ sprintf(pathbuf, "%s%s%s", "/proc/", procdirp->d_name, "/cmdline"); diff --git a/os/FreeBSD.h b/os/FreeBSD.h index 85b5117..4b6fca5 100644 --- a/os/FreeBSD.h +++ b/os/FreeBSD.h @@ -11,14 +11,25 @@ #include <stdlib.h> #include <string.h> +#if __FreeBSD_version >= 600000 +/* in FreeBSD 6.x the format of /proc/$pid/status changed */ +#define PROCFS_FREEBSD_6 +#else +#undef PROCFS_FREEBSD_6 +#endif + struct procstat { char comm[MAXCOMLEN+1]; int pid; int ppid; int pgid; int sid; +#ifdef PROCFS_FREEBSD_6 + char ttydev[SPECNAMELEN]; +#else int tdev_maj; int tdev_min; +#endif char flags[256]; /* XXX */ int start; int start_mic; @@ -102,3 +113,4 @@ static char* Fields[] = { #define F_LASTFIELD 19 }; + -- 1.6.4.3
Subject: 0001-FreeBSD-procfs-implementation-fixed-all-fields-with-.patch
From 7e982185411d18fdaf5883ae95b4e5b27240a5cd Mon Sep 17 00:00:00 2001 From: Slaven Rezic <slaven@rezic.de> Date: Sat, 13 Feb 2010 00:00:53 +0100 Subject: [PATCH 1/2] FreeBSD, procfs implementation: fixed all fields with microsecs --- os/FreeBSD.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/os/FreeBSD.c b/os/FreeBSD.c index 08b0919..a294b79 100644 --- a/os/FreeBSD.c +++ b/os/FreeBSD.c @@ -94,10 +94,10 @@ void OS_get_table(){ char *ttydev; int ttynum; - utime_f = prs.utime + prs.utime_mic/1000000; - stime_f = prs.stime + prs.stime_mic/1000000; + utime_f = prs.utime + prs.utime_mic/1000000.0; + stime_f = prs.stime + prs.stime_mic/1000000.0; time_f = utime_f + stime_f; - start_f = prs.start + prs.start_mic/1000000; + start_f = prs.start + prs.start_mic/1000000.0; sprintf(utime, "%f", utime_f); sprintf(stime, "%f", stime_f); -- 1.6.4.3
On Fri Feb 12 18:04:55 2010, SREZIC wrote: Show quoted text
> On Mon Jan 09 12:24:24 2006, guest wrote:
> > Running the sample script provided does work, however some fields do > > not contain useful information, Likely beacuse of a change in the OS:
> [...] > > Indeed, in FreeBSD 6.0 the format of /proc/.../status changed. Attached > are two patches. One is fixing the always broken microsecs calculation, > and the second is fixing the changed procfs format, but still retaining > the old pre-6.0 implementation.
Here's an amendment to the previous patch files. Please use only this one. This patch includes the following changes for FreeBSD: - use kvm implementation as default for FreeBSD 5.x and newer (because procfs is not anymore mounted by default) - fixes in the kvm implementation: - fixed start time if microsecs < 100000 - enhancements in the kvm implementation: - support for user and system time - using FreeBSD-kvm is possible now without any special permissions - fixes in the procfs implementation: - support for FreeBSD 6.x and later - fixed all fields with microsecs Regards, Slaven
Subject: FREEBSD.patch
Download FREEBSD.patch
text/x-diff 8.2k
diff --git c/README.freebsd w/README.freebsd deleted file mode 100644 index 4da4431..0000000 --- c/README.freebsd +++ /dev/null @@ -1,23 +0,0 @@ -SUPPORTED ATTRIBUTES -==================== - uid UID of process - gid GID of process - euid effective UID of process - egid effective GID of process - pid process ID - ppid parent process ID - pgrp process group - sess session ID - priority priority of process - ttynum tty number of process - flags flags of process - utime user mode time - stime kernel mode time - time user + system time - wchan address of current system call - fname file name - start start time (seconds since the epoch) - state state of process - ttydev path of process's tty - cmndline full command line of process - priority priority of process diff --git c/README.freebsd-kvm w/README.freebsd-kvm index 470f161..4c0ec09 100644 --- c/README.freebsd-kvm +++ w/README.freebsd-kvm @@ -12,6 +12,8 @@ SUPPORTED ATTRIBUTES sflags PS_* flags start start time time running time (in seconds) + utime user time (in seconds) + stime system time (in seconds) wchan current system call state state of process @@ -36,8 +38,6 @@ its use is not recommended in future. In addition, mapping processes space to /proc is not correct (at least, in 7 of 7 my freebsd servers with FreeBSD5 installed). -So, I decided to write this code. This module works via kvm system, all its -need is access to /dev/mem and /dev/kmem (you can add user to kmem group -in /etc/groups file). +So, I decided to write this code. This module works via the kvm system. Any comments please send to king2@kaluga.ru. diff --git c/README.freebsd-procfs w/README.freebsd-procfs new file mode 100644 index 0000000..4da4431 --- /dev/null +++ w/README.freebsd-procfs @@ -0,0 +1,23 @@ +SUPPORTED ATTRIBUTES +==================== + uid UID of process + gid GID of process + euid effective UID of process + egid effective GID of process + pid process ID + ppid parent process ID + pgrp process group + sess session ID + priority priority of process + ttynum tty number of process + flags flags of process + utime user mode time + stime kernel mode time + time user + system time + wchan address of current system call + fname file name + start start time (seconds since the epoch) + state state of process + ttydev path of process's tty + cmndline full command line of process + priority priority of process diff --git c/hints/freebsd.pl w/hints/freebsd.pl old mode 100644 new mode 100755 index 28a5b27..a18a0be --- c/hints/freebsd.pl +++ w/hints/freebsd.pl @@ -1 +1,11 @@ -symlink "os/FreeBSD.c", "OS.c" || die "Could not link os/FreeBSD.c to os/OS.c\n"; +require Config; +my($maj) = $Config::Config{osvers} =~ m{^(\d+)}; +if ($maj < 5) { + print STDERR "Using procfs implementation\n"; + symlink "os/FreeBSD.c", "OS.c" || die "Could not link os/FreeBSD.c to os/OS.c\n"; +} else { + print STDERR "Using kvm implementation\n"; + symlink "os/FreeBSD-kvm.c", "OS.c" || die "Could not link os/FreeBSD-kvm.c to os/OS.c\n"; + $self->{LIBS} = ['-lkvm']; +} + diff --git c/hints/freebsd_5.pl w/hints/freebsd_5.pl deleted file mode 100644 index aeee53b..0000000 --- c/hints/freebsd_5.pl +++ /dev/null @@ -1,2 +0,0 @@ -symlink "os/FreeBSD-kvm.c", "OS.c" || die "Could not link os/FreeBSD-kvm.c to os/OS.c\n"; -$self->{LIBS} = ['-lkvm']; diff --git c/os/FreeBSD-kvm.c w/os/FreeBSD-kvm.c index bc7f6f6..43c2611 100644 --- c/os/FreeBSD-kvm.c +++ w/os/FreeBSD-kvm.c @@ -2,8 +2,11 @@ #include <unistd.h> #include <sys/sysctl.h> #include <sys/proc.h> +#include <sys/times.h> #include <sys/user.h> +#include <fcntl.h> #include <kvm.h> +#include <paths.h> @@ -24,6 +27,8 @@ void OS_get_table(){ char state[20]; char start[20]; char time[20]; + char utime[20]; + char stime[20]; char flag[20]; char sflag[20]; @@ -32,7 +37,7 @@ void OS_get_table(){ int priority; /* Open the kvm interface, get a descriptor */ - if ((kd = kvm_open(NULL, NULL, NULL, 0, errbuf)) == NULL) { + if ((kd = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, NULL, O_RDONLY, errbuf)) == NULL) { fprintf(stderr, "kvm_open: %s\n", errbuf); ppt_croak("kvm_open: ", errbuf); } @@ -92,8 +97,10 @@ void OS_get_table(){ } - sprintf(start, "%d.%d", procs[i].ki_start.tv_sec, procs[i].ki_start.tv_usec); + sprintf(start, "%d.%06d", procs[i].ki_start.tv_sec, procs[i].ki_start.tv_usec); sprintf(time, "%.6f", procs[i].ki_runtime/1000000.0); + sprintf(utime, "%d.%06d", procs[i].ki_rusage.ru_utime.tv_sec, procs[i].ki_rusage.ru_utime.tv_usec); + sprintf(stime, "%d.%06d", procs[i].ki_rusage.ru_stime.tv_sec, procs[i].ki_rusage.ru_stime.tv_usec); sprintf(flag, "0x%04x", procs[i].ki_flag); sprintf(sflag, "0x%04x", procs[i].ki_sflag); @@ -113,6 +120,8 @@ void OS_get_table(){ start, time, + utime, + stime, procs[i].ki_wmesg, state, diff --git c/os/FreeBSD-kvm.h w/os/FreeBSD-kvm.h index bda9364..ca16153 100644 --- c/os/FreeBSD-kvm.h +++ w/os/FreeBSD-kvm.h @@ -13,7 +13,7 @@ /* We need to pass in a cap for ignore, lower for store on object */ /* We can just lc these! */ -static char Defaultformat[] = "iiiiiiisssssssissiiiiiii"; +static char Defaultformat[] = "iiiiiiisssssssssissiiiiiii"; /* Mapping of field to type */ static char* Fields[] = { @@ -29,6 +29,8 @@ static char* Fields[] = { "sflags", "start", "time", + "utime", + "stime", "wchan", "state", diff --git c/os/FreeBSD.c w/os/FreeBSD.c index 08b0919..a4b2cac 100644 --- c/os/FreeBSD.c +++ w/os/FreeBSD.c @@ -8,14 +8,22 @@ struct procstat* get_procstat( char* path, struct procstat* prs){ if( (fp = fopen( path, "r" )) != NULL ){ fscanf(fp, +#ifdef PROCFS_FREEBSD_6 + "%s %d %d %d %d %s %s %d,%d %d,%d %d,%d %s %d %d %d,%d,%s", +#else "%s %d %d %d %d %d,%d %s %d,%d %d,%d %d,%d %s %d %d %d,%d,%s", +#endif &prs->comm, &prs->pid, &prs->ppid, &prs->pgid, &prs->sid, +#ifdef PROCFS_FREEBSD_6 + &prs->ttydev, +#else &prs->tdev_maj, &prs->tdev_min, +#endif &prs->flags, &prs->start, &prs->start_mic, @@ -93,20 +101,33 @@ void OS_get_table(){ double start_f; char *ttydev; int ttynum; +#ifdef PROCFS_FREEBSD_6 + struct stat tdev_stat; +#endif - utime_f = prs.utime + prs.utime_mic/1000000; - stime_f = prs.stime + prs.stime_mic/1000000; + utime_f = prs.utime + prs.utime_mic/1000000.0; + stime_f = prs.stime + prs.stime_mic/1000000.0; time_f = utime_f + stime_f; - start_f = prs.start + prs.start_mic/1000000; + start_f = prs.start + prs.start_mic/1000000.0; sprintf(utime, "%f", utime_f); sprintf(stime, "%f", stime_f); sprintf(time, "%f", time_f); sprintf(start, "%f", start_f); +#ifdef PROCFS_FREEBSD_6 + ttydev = prs.ttydev; + sprintf(pathbuf, "/dev/%s", ttydev); + if (stat(pathbuf, &tdev_stat) < 0){ + ttynum = -1; + } else { + ttynum = tdev_stat.st_rdev; + } +#else ttynum = makedev(prs.tdev_maj, prs.tdev_min); ttydev = devname(ttynum, S_IFCHR); if (ttydev == NULL) ttydev = "??"; +#endif /* get stuff out of /proc/PROC_ID/cmdline */ sprintf(pathbuf, "%s%s%s", "/proc/", procdirp->d_name, "/cmdline"); diff --git c/os/FreeBSD.h w/os/FreeBSD.h index 85b5117..4b6fca5 100644 --- c/os/FreeBSD.h +++ w/os/FreeBSD.h @@ -11,14 +11,25 @@ #include <stdlib.h> #include <string.h> +#if __FreeBSD_version >= 600000 +/* in FreeBSD 6.x the format of /proc/$pid/status changed */ +#define PROCFS_FREEBSD_6 +#else +#undef PROCFS_FREEBSD_6 +#endif + struct procstat { char comm[MAXCOMLEN+1]; int pid; int ppid; int pgid; int sid; +#ifdef PROCFS_FREEBSD_6 + char ttydev[SPECNAMELEN]; +#else int tdev_maj; int tdev_min; +#endif char flags[256]; /* XXX */ int start; int start_mic; @@ -102,3 +113,4 @@ static char* Fields[] = { #define F_LASTFIELD 19 }; +
Download (untitled) / with headers
text/plain 1.2k
On 2010-02-12 18:55:49, SREZIC wrote: Show quoted text
> On Fri Feb 12 18:04:55 2010, SREZIC wrote:
> > On Mon Jan 09 12:24:24 2006, guest wrote:
> > > Running the sample script provided does work, however some fields do > > > not contain useful information, Likely beacuse of a change in the OS:
> > [...] > > > > Indeed, in FreeBSD 6.0 the format of /proc/.../status changed. Attached > > are two patches. One is fixing the always broken microsecs calculation, > > and the second is fixing the changed procfs format, but still retaining > > the old pre-6.0 implementation.
> > Here's an amendment to the previous patch files. Please use only this > one. This patch includes the following changes for FreeBSD: > - use kvm implementation as default for FreeBSD 5.x and newer (because > procfs is not anymore mounted by default) > - fixes in the kvm implementation: > - fixed start time if microsecs < 100000 > - enhancements in the kvm implementation: > - support for user and system time > - using FreeBSD-kvm is possible now without any special permissions > - fixes in the procfs implementation: > - support for FreeBSD 6.x and later > - fixed all fields with microsecs >
This patch is still fine with Proc-ProcessTable 0.46 and works for recent FreeBSD versions (e.g. 8.0 and 9.0). Regards, Slaven
closed in v0.47


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.