Solaris 'w' command bug?


While reviewing some system information last week , I came across a discrepancy (which I would think is a bug – at least according to the idle time description in the w manual pages) in the Solaris ‘w’ output:

$ date
Wed Dec 21 10:19:59 EST 2005

$ w

10:19am up 5 day(s), 19:52, 2 users, load average: 0.02, 0.03, 0.04
User tty login@ idle JCPU PCPU what
user1234 pts/1 10:19am 51 myapp

$ who -u

user1234 pts/1 Dec 21 10:19 . 10503 (1.2.3.4)

The user “user1234” logged in at 10:19, and according to w has been idle for 51 minutes (since they have been logged in for one minute or less, they obviously cannot be idle for 51 minutes). A quick check of w.c reveals that idle time is calculated using the atime from a stat of /dev/pts/[1-9]+:

if (stat(ttyname, &stbuf) != -1) {
lastaction = stbuf.st_atime;
diff = now - lastaction;
diff = DIV60(diff);

While who.c uses the mtime from a stat of /dev/pts/[1-9]+:

if ((rc = stat(path, stbufp)) != -1) {
idle = timnow - stbufp->st_mtime;

To understand when atime and mtime are updated, I read through the Solaris stat(2) manual page:

st_atime Time when file data was last accessed. Changed by the following functions: creat(), mknod(), pipe(), utime(2), and read(2).

st_mtime Time when data was last modified. Changed by the following functions: creat(), mknod(), pipe(), utime(), and write(2).

Since there seems to be some inconsistency (atime in w and mtime in who) in the source code, I thought I would look at my favorite OS (FreeBSD / Darwin) to see how they implemented w:

# From FreeBSD source code
touched = stp->st_atime;
if (touched < ep->utmp.ut_time) {
touched = ep->utmp.ut_time;
}
if ((ep->idle = now - touched) < 0)
ep->idle = 0;

So this explains it. Since the user logged in and didn’t do anything, the pseudo-terminal would have been written to but not necessarily read from (I assume since the pseudo-terminal is setup by the terminal driver after the user is authenticated). FreeBSD fixes this problem by adding an additional check to compare idle time to the time the user logged in, which seems to address this issue. I posted this issue to the Solaris discussion forums, but unfortunately no one replied. Since the putback model with opensolaris is still somewhat new and requires an excessive amount of work on the contributor’s behalf, I think I will just chock this up to fun and move my code analysis efforts back to Apache and FreeBSD (which is a super neat OS).

This article was posted by Matty on 2005-12-26 11:18:00 -0400 -0400