![]() |
|
| Daemon News Ezine | BSD News | BSD Mall | BSD Support Forum | BSD Advocacy | BSD Updates |
sysctl On NetBSD - An Easy Way To Get Process DataSean Davis <dive@endersgame.net>A few months ago, I got curious. I wanted to know if I could write a program to give me the total used CPU seconds of every running process, and do it totally without using procfs. After an hour or so of digging through ps source (basesrc/usr.bin/ps on CVS) for NetBSD, I had gotten a basic enough understanding of sysctl to write a program that would show me the proc addresses of every running processes. Needless to say, I wanted more. Eventually I stumbled on a way to get into the proc structure, by dereferencing (I believe that is the term) it from the kinfo_proc structure that holds all the data for every process. The sysctl() call is more useful than many would think at first glance. When I first looked at it, I thought the only use one could get out of it was being able to do what /sbin/sysctl does from my own C code - it can do so much more. With a MIB (Management Information Base) of CTL_KERN, KERN_PROC, KERN_PROC_UID, and a UID, I am able to get all the running processes for the specified UID. This turned out to be what I wanted for my program. After a few hours of digging through the system include files, I found the data I wanted. I'll illustrate where it is for any C programmers out there:
kp (struct kinfo_proc *)
|
+-kp_eproc (struct eproc)
|
+-e_paddr (struct proc *)
|
+-p_rtime (struct timeval)
|
+-tv_sec (long)
+-tv_usec (long)
^
|
+- the tv_sec and tv_usec values are the most important data in the
whole program, as that's where the cpu time stuff is :)
What the program does is this:
[dive@eros(/home/dive/cvs/code)] % make cputime-nbsd cc -Wall -g -o cputime-nbsd cputime-nbsd.c [dive@eros(/home/dive/cvs/code)] % ./cputime-nbsd [root (uid 0 )]: 3154.125071 cpu seconds used (total of 47 processes) [dive (uid 1000 )]: 2200.416325 cpu seconds used (total of 21 processes) [qmaild (uid 1002 )]: 0.449536 cpu seconds used (total of 1 process) [qmaill (uid 1003 )]: 1.958566 cpu seconds used (total of 4 processes) [qmailq (uid 1005 )]: 0.599276 cpu seconds used (total of 1 process) [qmailr (uid 1006 )]: 0.62749 cpu seconds used (total of 1 process) [qmails (uid 1007 )]: 3.563539 cpu seconds used (total of 1 process) [www (uid 1008 )]: 1.902132 cpu seconds used (total of 10 processes) [david (uid 1009 )]: 44.860979 cpu seconds used (total of 3 processes) [tinydns (uid 1036 )]: 0.66071 cpu seconds used (total of 1 process) [dnslog (uid 1037 )]: 5.77964 cpu seconds used (total of 2 processes) [dnscache (uid 1038 )]: 8.522690 cpu seconds used (total of 1 process) [dive@eros(/home/dive/cvs/code)] % I find the program useful, so I can see just how badly what I'm running is eating my CPU. Another use for the data could be to check every x seconds, and if a process has used more than x seconds since the last check, alert the user (or root) that something is using too much CPU. I haven't implimented this in C, but I do have some code on a MOO I run that does exactly that. It is wonderful for catching runaway loops. You can view/download the source for the program here. And that about wraps it up. I hope you find the program useful, and if not, at least you learned a little something about sysctl :) - Sean |