Subject: w cmd on energy saving machines: problem and proposed solution
To: None <tech-userlevel@netbsd.org>
From: Ignatios Souvatzis <is@netbsd.org>
List: tech-userlevel
Date: 06/15/2001 22:28:52
Hi,
w(1) on one of my systems shows:
marie w !% w
9:57PM up 7 days, 46 mins, 2 users, load averages: 0.07, 0.14, 0.15
USER TTY FROM LOGIN@ IDLE WHAT
is p1 jocelyn.sub-etha 8:08PM 199days w
is p2 jocelyn.sub-etha 9:03PM 199days -csh
I investigated, and noticed that
- /dev is mounted noatime (I want to make the disk spin down when unused, and
I was told to set noatime for this)
- w uses current time minus the tty's access time as the idle time.
However, at the time the internally used idle time is used in any way,
the sleep time of the process is already known to w. Therefore, I propose
to use that instead:
--- w.c.original Fri Jun 15 21:40:38 2001
+++ w.c Fri Jun 15 22:18:40 2001
@@ -232,8 +232,7 @@
size = sizeof(dev_t);
(void) sysctl(mib, 2, &ep->tdev, &size, NULL, 0);
}
- if ((ep->idle = now - stp->st_atime) < 0)
- ep->idle = 0;
+ ep->idle = 0;
}
if (ut)
(void)fclose(ut);
@@ -265,6 +264,7 @@
*/
if (proc_compare(ep->kp, kp)) {
ep->kp = kp;
+ ep->idle = kp->p_slptime;
lognamelen = max(lognamelen,
strlen(kp->p_login));
}
@@ -277,6 +277,7 @@
else if (ep->tdev == 0 && kp->p_tdev == NODEV
&& ep->ftpd_pid == kp->p_pid) {
ep->kp = kp;
+ ep->idle = kp->p_slptime;
lognamelen = max(lognamelen,
strlen(kp->p_login));
}
marie w !% obj/w
10:18PM up 7 days, 1:07, 2 users, load averages: 0.12, 0.13, 0.10
USER TTY FROM LOGIN@ IDLE WHAT
is p1 jocelyn.sub-etha 8:08PM 0 obj/w
is p2 jocelyn.sub-etha 9:03PM 49 -csh
Note that now processes that use cpu time, but do not a-ccess the tty,
are not counted as idle, contrary to the old behaviour. One example is
tail -f on files that don't change. If we really care, the code could be
changed like this:
--- w.c.original Fri Jun 15 21:40:38 2001
+++ w.c Fri Jun 15 22:13:47 2001
@@ -234,6 +234,8 @@
}
if ((ep->idle = now - stp->st_atime) < 0)
ep->idle = 0;
+ else if (stp->st_atime < ep->utmp.ut_time)
+ ep->idle = -1;
}
if (ut)
(void)fclose(ut);
@@ -265,6 +267,8 @@
*/
if (proc_compare(ep->kp, kp)) {
ep->kp = kp;
+ if (ep->idle < 0)
+ ep->idle = kp->p_slptime;
lognamelen = max(lognamelen,
strlen(kp->p_login));
}
@@ -277,6 +281,8 @@
else if (ep->tdev == 0 && kp->p_tdev == NODEV
&& ep->ftpd_pid == kp->p_pid) {
ep->kp = kp;
+ if (ep->idle < 0)
+ ep->idle = kp->p_slptime;
lognamelen = max(lognamelen,
strlen(kp->p_login));
}
to only use sleep time when the tty access time is unreasonable.
Thoughts?
Appendix: finger (actually fingerd) shows the same problem, because the
same definition of idle time is used. Best we can do here is to clip the
idle time to the login time. (Else we'd have to make it a kmem groveler, too.)
Thoughts here?
Regards,
-is