Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Oct 2007 12:45:36 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        "Constantine A. Murenin" <cnst@freebsd.org>
Cc:        arch@freebsd.org
Subject:   sensors fun..
Message-ID:  <200710171245.36949.jhb@freebsd.org>

next in thread | raw e-mail | index | archive | help
[Trying to redirect this off cvs-all & friends.. ]

So as I said previously, I thought about this some more offline last night / 
this morning and looked at the code some and here are my thoughts:

Things I like about the current sensors code:

- I like the actual sensor object used to represent a sensor.  It has a few 
basic things like a string for a name, a type (I would have just done 
a "units" for the value, but the type is basically that), and a basic alarm 
state. (I might have done 4 states, think green, yellow, orange, red mapped 
to good, warning, critical, bad.  However, the 3 states in the current code 
is fine.  4 states might be overkill.)
- I like having the lm(4), etc. sensors report status via an object like this 
instead of just getting some string out of a tool like 'mbmon'.  A framework 
should provide the data so that multiple utilities can use it.
- I'm not entirely opposed to having kernel drivers for various known sensor 
providers like lm(4), etc.  OTOH, I could see a driver just providing ioctls 
to query the list of sensors and a sensor's value similar to using requests 
to the IPMI BMC to request SDR data via ioctls to /dev/ipmi0 as the kernel -> 
userland interface.

Things I'm not a big fan of:

- Forcing all sensors to be in the kernel.  A general rule in most OSes is to 
minimize the amount of stuff in the kernel.  The kernel is easily the most, 
erm, "sensitive" process in the system.  A segfault has much more serious 
consequences in the kernel (panic) than in userland (SIGSEGV).  It also makes 
it more complicated to add "psuedo" sensors.

For example, if I wanted a sensor for CPU usage based on the kern.cp_time 
sysctl, I could easily do that in userland by quering the sysctl 
periodically, computing the relative % busy and set a status based on a set 
of trigger points.  Similarly, you could conceive having 
virtual/pseudo/whatever sensors for disk space, etc.  At some point you do 
risk duplicating SNMP traps with sensord I suppose.

I also genuinely think it is better to keep lots of state around in userland 
rather than in the kernel.  That is, I think the kernel should provide a way 
to query a sensor (RAID drivers provide ioctls to communicate with the 
firmware, IPMI has ioctls to allow userland to communicate with the BMC, some 
drivers may provide ioctl/sysctl/whatever to read sensor values directly), 
but I don't think we should try to store history (see the cp_time example 
above) or extended state (keeping track of which drives exist so you can 
detect a drive that goes away) in the kernel.  That belongs in userland.  I 
think it can be ok for some sensors to be completely in the kernel and just 
get queried directly from userland, but I don't think that is a valid design 
constraint to enforce on all sensors.

Things I think are dubious at best:

- That it is more secure to put code in the kernel than as root in userland.  
It seems odd to even have to mention this, but it should be painfully obvious 
that a bug in a driver has much worse consequences than a bug in a user app 
running as root (or even better, some dedicated non-privileged account in a 
group that can send ioctls to /dev/ipmi0 or other monitored devices).  I 
guess maybe I can see a viewpoint where you hope that a driver bug always 
panics and doesn't just corrupt data and so it's more likely to get a SA's 
attention and be less exploitable maybe?  I can understand that 'mbmon' is 
untrusted code, but it seems to me that there are some less drastic measures 
than rewriting it all as kernel code, namely 1) audit the existing code, or 
2) rewrite it all as userland code, ideally less privileged.

Other things that might be nice:

- IWBN to have a userland interface to sensors.  For example, if nothing else 
a sensor enumerator rather than duplicating the sysctl loop as the current 
code does.  This would make it easier to at least adjust the current 
artificial limit on the number of sensors since only one place in userland 
would have to change.  (BTW, having an artificial limit on the number of 
sensors is lame.  This is an example where using the normal way of walking a 
sysctl tree is superior.  You can lose the entire limit.)  Having a userland 
interface also makes it easier to have backends that are entirely in 
userland.
- An snmp module that uses the above userland interface to export sensors via 
snmp.  bsnmp already has a way to load modules at runtime (at least startup 
time) to add new MIBS.  This would allow remote monitoring of various sensors 
if people prefer that to having a daemon on the box post alerts.  If nothing 
else, it lets you add mrtg or rrdtool type graphs of the history of sensors 
if desired.

Basically, I think there should be a "real" abstracted interface in userland 
that can use various backends.  One backend could be to query sensors from 
drivers that provide them directly (lm(4), etc.).  Another backend could use 
the existing IPMI interface to query SDR sensors via IPMI commands to the 
BMC.  Different RAID controllers could provide backends that communicate with 
the firmware to maintain whatever state is needed, etc. but w/o doing all 
that in the device driver.  People could write their own custom sensors w/o 
having to write a kernel module.  Maybe that's a bigger vision than you were 
shooting for.  I'm not sure phk@ will agree with this one either fwiw. :)

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200710171245.36949.jhb>