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 #include #include +#include #include +#include #include +#include @@ -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 #include +#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 }; +