2005-12-31
Notes on getting a Solaris hardware inventory
Being able to find out what hardware is in a random machine is one of those things you don't think about very much until you inherit responsibility for a bunch of machines that you didn't build yourself.
The best hardware inventory program I've used is SGI's hinv
(although it doesn't have enough disk information). Linux has decent
hardware inventory support, but not bundled into a single command; you
have to look through a bunch of /proc files and know a few commands
like lspci. Unfortunately, Solaris is less friendly.
The old-fashioned way to get hardware information is to look at the
kernel's boot messages; on Solaris this is in syslog or via dmesg.
However, these logs get aged away if the system has been up for a
while. (I've been known to arrange for kernel syslog messages to never
expire, but I haven't set that up on my Solaris systems yet.)
The best program seems to be prtdiag, which gives CPU, memory, and
some hardware slot information (and works for non-root users, always a
bonus). There's also prtconf and a number of others, but they don't
seem to give much additional useful information about hardware.
The names of stuff in /devices has a some information, but I suspect
a good familiarity with Solaris device driver names is needed for best
results. (Solaris /proc is for processes only, so there is nothing
like Linux's collection of informative files.)
(People seem to use Magnicomp's sysinfo a fair bit, but it's
commercial software (with a 30 day free trial), and binary packages on
systems without real package managers make me twitchy. And its
installer has glitches that don't inspire confidence.)
A logical consequence of def being an executable statement
I've mentioned before that in Python, def is actually an executable
statement (in FunctionDefinitionOrder). A logical consequences of this
is that default values for function arguments are evaluated only once,
when the def runs.
I say this because expressions generally get evaluated when any
Python statement runs, so the expressions in things like 'def
foobar(a, b=greeble(c), d=None):' are not being an exception. The
exception would be if they were not evaluated then and were instead
preserved as little lambda expressions to be evaluated later.
On an interesting side note, setting default values for arguments is
one of the two places in Python where the same variable name can be in
two different scopes simultaneously; the other is invoking a function
with keyword arguments. Everywhere else you write 'a=a' the two
a's are the same, but in these two cases the a being assigned to
is in the new function's scope and the expression's a is in your
current scope.
The result can be a little bit confusing, as you can see in StructsWithDefaults. (Which is one reason I like to avoid it.)
Sidebar: mutable default arguments
This means that mutable default arguments are usually not what you want, because if you change them they will stay mutated in subsequent invocations of the function. The usual pattern around this is something like:
def foobar(a, deflst=None):
if deflst is None:
deflst = []
....