Robert de Bock

Update Soekris bios firmware from your Apple Mac OS X machine

When you are using a Soekris, a new bios is published every now and then. Because I had to search-copy-try-paste quite some time to get my Apple Mac OS X to upload the most recent Soekris (net4521) bios.

Here is what you need:

I downloaded b4501_133.bin.

The driver for the IOGear USB-to-serial cable creates a device called /dev/tty.PL2303-00002006. The Soekris will most likely run on 19200 bps. If your Soekris spits out unreadable text, try a speed like 9600. If you are able to access the Soekris bios, you can always change the serial speed using "set ConSpeed=19200" for example.

# cu -l /dev/tty.PL2303-00002006 -s 19200
POST: 012345689bcefghipsajklnopqr,,,tvwxy

comBIOS ver. 1.33  20080103  Copyright (C) 2000-2007 Soekris Engineering.

net45xx

0064 Mbyte Memory                        CPU Elan SC520 133 Mhz

Pri Mas  LEXAR ATA FLASH                 LBA Xlt 999-32-63  1007 Mbyte

Slot   Vend Dev  ClassRev Cmd  Stat CL LT HT  Base1    Base2   Int
-------------------------------------------------------------------
0:00:0 1022 3000 06000000 0006 2280 00 00 00 00000000 00000000
0:17:0 104C AC51 06070000 0107 0210 10 3F 82 A0000000 020000A0 10
0:17:1 104C AC51 06070000 0107 0210 10 3F 82 A0001000 020000A0 10
0:18:0 100B 0020 02000000 0107 0290 00 3F 00 0000E101 A0002000 11
0:19:0 100B 0020 02000000 0107 0290 00 3F 00 0000E201 A0003000 05

1 Seconds to automatic boot.   Press Ctrl-P for entering Monitor.

> download -

Start sending file using XMODEM/CRC protocol.
~+./lsz -X b4501_133.bin
Sending b4501_133.bin, 608 blocks: Give your local XMODEM receive command now.
Bytes Sent:  77824   BPS:1745                           

Transfer complete

File downloaded succesfully, size 608 Blocks.

> flashupdate
Updating BIOS Flash ,,,,,,,,,,,,..,,,,.. Done.

> reboot

Good, you are done!

Install your Soekris (or any other machine) with OpenBSD using OpenBSD

To install OpenBSD on your Soekris machine, (or any other machine) take these steps to create an OpenBSD installation server. This instruction help you setup a DHCP, TFTP and HTTP server required for a network installation of OpenBSD.

This setup creates an autonomous install server, that can be disconnected from the internet. During the setup this machine is connected to the internet to install all required software.

First; install an OpenBSD machine. This may either be virtual or physical. Just install the default set of software and make sure it's connected to the internet. (It does not matter if you are using DHCP or a static IP configuration.)

This instruction is based on OpenBSD 4.5, but will likely work for future releases.

Install a DHCP server.

# export PKG_PATH=http://mirror.roothell.org/pub/OpenBSD/4.5/packages/i386/
# pkg_add isc-dhcp-server
isc-dhcp-server-3.1.1: complete

Configure the DHCP server. This step is very dependent of your network configuration, so don't just copy paste everything, but try to understand (using man pages) what's configured.
My /etc/dhcpd.conf looks like this now:

option  domain-name "home.meinit.nl";
option  domain-name-servers 192.168.1.1;

subnet 192.168.1.0 netmask 255.255.255.0 {
        range 192.168.1.32 192.168.1.127;
        host pxe-client {
                hardware ethernet 02:03:04:05:06:07;
                filename "pxeboot";
                next-server 192.168.1.1;
        }
}

Be aware; the "hardware ethernet" address mentioned above is not correct. It needs to be set to what the MAC address is of the machine you would like to install.

Make sure it start by modifying /etc/rc.conf.local, like this:

# echo "dhcpd_flags=" >> /etc/rc.conf.local

Enable the TFTP server in /etc/inetd.conf: (It's installed by default on an OpenBSD installation!)

tftp            dgram   udp     wait    root    /usr/libexec/tftpd      tftpd -s /tftpboot

Create some directories and restart inetd:
# pkill -HUP inetd

Now get the kernel that is being used when booting over the network and retreive the PXE boot code.

# cd /tftpboot
# ftp http://mirror.roothell.org/pub/OpenBSD/4.5/i386/bsd.rd
Trying 88.198.153.75...
Requesting http://mirror.roothell.org/pub/OpenBSD/4.5/i386/bsd
100% |*******************************************************************************|  5461 KB    00:06
Successfully retrieved file.
# echo "set tty com0
stty com0 19200
boot bsd.rd" > etc/boot.conf
# ftp http://mirror.roothell.org/pub/OpenBSD/4.5/i386/pxeboot
Trying 88.198.153.75...
Requesting http://mirror.roothell.org/pub/OpenBSD/4.5/i386/pxeboot
100% |*******************************************************************************| 53276       00:00   
Successfully retrieved file.

Enable a HTTP server.

# echo "httpd_flags=" >> /etc/rc.conf.local

Now get all required software sets you'd like to offer.

# ftp http://mirror.roothell.org/pub/OpenBSD/4.5/i386/index.txt
Trying 88.198.153.75...
Requesting http://mirror.roothell.org/pub/OpenBSD/4.5/i386/index.txt
100% |*******************************************************************************|   266       00:00   
Successfully retrieved file.
# cat index.txt | grep -v '.iso' | tee index.txt | while read file ; do
>  ftp http://mirror.roothell.org/pub/OpenBSD/4.5/i386/"$file"         
> done
100% |********************************************************************************|   106 KB    00:00   
100% |********************************************************************************| 22356       00:00   
100% |********************************************************************************|  1022       00:00   
100% |********************************************************************************| 46941 KB    00:27   
100% |********************************************************************************|  6539 KB    00:02   
100% |********************************************************************************|  6558 KB    00:03   
100% |********************************************************************************|  5461 KB    00:02   
100% |********************************************************************************| 44724       00:00   
100% |********************************************************************************|  2048       00:00   
100% |********************************************************************************| 87874 KB    00:59   
100% |********************************************************************************|   501 KB    00:00   
100% |********************************************************************************|  1440 KB    00:00   
100% |********************************************************************************|  1440 KB    00:00   
100% |********************************************************************************|  1440 KB    00:00   
100% |********************************************************************************|  2555 KB    00:00   
100% |********************************************************************************|  8032 KB    00:03   
100% |********************************************************************************|  2866 KB    00:02   
100% |********************************************************************************| 53276       00:00   
100% |********************************************************************************|  9761 KB    00:07   
100% |********************************************************************************| 75214       00:01   
100% |********************************************************************************| 34745 KB    00:26   
100% |********************************************************************************| 19478 KB    00:11   
100% |********************************************************************************|  2698 KB    00:06   

Now that everything is ready, reconfigure your network to use a static IP which is usable in the network you are planning this installation server.

NOTA BENE: you have enabled a DHCP server, if your network already uses a DHCP server, clients might get an IP address from your DHCP server, which is likely incorrect and/or conflicting with the exiting DHCP server. Normally you'd like to use one DHCP server per network.

# echo "inet 192.168.1.1 255.255.255.0 192.168.1.255" > /etc/hostname.em0
# echo "lookup file" > /etc/resolv.conf
# reboot

Now in the freshly installed client, modify/create /etc/boot.conf with this content:

set tty com0
stty com0 19200

The Soekris uses these setting to be able to access the serial console.

Okay, after your install server has been rebooted, go and boot an uninstalled client.

For soekris users; connect your console cable, see the machine boot.

You will see that it's first getting the pxeboot code, then the kernel (bsd). When the kernel has booted, select your bootservers IP address to install software from and enter "/" at the server directory question.

Add a permanent static route to Mac OS X

As a reminder for myself, but likely useful for you! If you are in a situation where you'd like to add a static route to you Mac OS X machine, you could issue:

$ sudo route add 10.0.0.0/8 192.168.1.1

This commands tells the TCP/IP stack to sent traffic with the destination 10.*.*.* via 192.168.1.1. But, this command is only active after issuing it and before the next reboot. To "save" this command, make it permanent, you can take these simple steps.
$ sudo mkdir /Library/StartupItems/AddRoute
# cd /Library/StartupItems/AddRoute
$ echo "{
        Description     = \"Add static routing tables\";
        Provides        = (\"AddRoutes\");
        Requires        = (\"Network\");
        OrderPreference = \"None\";
}" > StartupParameters.plist
$ echo "#!/bin/sh

# Set up static routing tables
# Roark Holz, Thursday, April 6, 2006

. /etc/rc.common

StartService ()
{
        ConsoleMessage "Adding Static Routing Tables"
sudo route add 10.0.0.0/8 192.168.200.15
}

StopService ()
{
        return 0
}

RestartService ()
{
        return 0
}

RunService "$1"" > AddRoutes
$ sudo chmod 755 AddRoutes

Now you should be prepared. After a reboot, the route will be visible. (netstat -rnf inet)

Nagios check for Centreon to create CPU graphs for Linux

Centreon is a great front-end for Nagios, the well known monitoring tool.

Nagios only performs "up" and "down" checks, Centreon adds performance graph capabilities.

Centreon comes with many checks to measure values, like traffic on eth0, a ping response time check, an ntp check and so on. Many checks are based on SNMP, so for Linux machines net-snmp should be installed.

What Centreon is missing, is an SNMP check that reports CPU usage and graphs the information. Here is a shell script to get the values for a specified host and return the CPU-idle percentage, CPU-system percentage and CPU-user percentage.

The script depends on a binary snmpget found in the package net-snmp-utils. Install it on the Nagios pollers that perform this check.

This script implements Performance Data as described by Nagios, which is very short means that besides outputting readable data, it also outputs performance data after the pipe ("|") mark, separated by a comma.
The script has been designed to incorporate all described requirements by Nagios plugins.

#!/bin/sh

# Nagios plugin to report CPU usage on Linux boxes.

usage() {
# This function is called when a user enters impossible values.
echo "Usage: $0 -H HOSTADDRESS [-C COMMUNITY] [-w WARNING] [-c CRITICAL] [-v VERSION]"
echo
echo " -H HOSTADDRESS"
echo "     The host to check, either IP address or a resolvable hostname."
echo " -w WARNING"
echo "     The percentage of cpu-idle to start warning, defaults to 15."
echo " -c CRITICAL"
echo "     The percentage op cpu-idle to reflect a critical state, defaults to 5."
echo " -C COMMUNITY"
echo "     The SNMP community to use, defaults to public."
echo " -v VERSION"
echo "     The SNMTP version to use, defaults to 2c."
exit 3
}

readargs() {
# This function reads what options and arguments were given on the
# command line.
while [ "$#" -gt 0 ] ; do
  case "$1" in
   -H)
    if [ "$2" ] ; then
     host="$2"
     shift ; shift
    else
     echo "Missing a value for $1."
     echo
     shift
     usage
    fi
   ;;
   -w)
    if [ "$2" ] ; then
     warning="$2"
     shift ; shift
    else
     echo "Missing a value for $1."
     echo
     shift
     usage
    fi
   ;;
   -c)
    if [ "$2" ] ; then
     critical="$2"
     shift ; shift
    else
     echo "Missing a value for $1."
     echo
     shift
     usage
    fi
   ;;
   -C)
    if [ "$2" ] ; then
     community="$2"
     shift ; shift
    else
     echo "Missing a value for $1."
     echo
     shift
     usage
    fi
   ;;
   -v)
    if [ "$2" ] ; then
     version="$2"
     shift ; shift
    else
     echo "Missing a value for $1."
     echo
     shift
     usage
    fi
   ;;
   *)
    echo "Unknown option $1."
    echo
    shift
    usage
   ;;
  esac
done
}

setvariables() {
# Here is a function to set some default values.
cpurawidle="UCD-SNMP-MIB::ssCpuRawIdle.0"
cpurawuser="UCD-SNMP-MIB::ssCpuRawUser.0"
cpurawsystem="UCD-SNMP-MIB::ssCpuRawSystem.0"
if [ ! "$warning" ] ; then warning="15" ; fi
if [ ! "$critical" ] ; then critical="5" ; fi
tmpdir="/tmp/nagios"
}

checkvariables() {
# This function checks if all collected input is correct.
if [ ! "$host" ] ; then
  echo "Please specify a hostname or IP address."
  echo
  usage
fi
if [ "$warning" -lt "$critical" ] ; then
  echo "Critical may not be higher than warning. Please modify your critical an warning values."
  echo
  usage
fi
if [ ! "$community" ] ; then
  # The public community is used when a user did not enter a community.
  community="public"
fi
if [ ! "$version" ] ; then
  # Version 2c is used when a user did not enter a version.
  version="2c"
fi
if [ ! -d "$tmpdir" ] ; then
  mkdir "$tmpdir"
  if [ $? -gt 0 ] ; then
   echo "Unknown cannot create $tmpdir!"
   exit 3
  fi
fi
}

getandprintresults() {
# First, get all values in one snmpget session. I think this is lighter for
# the machine that is queried compared to three separated snmpgets.
snmpget -c "$community" -v "$version" -t 3 "$host" "$cpurawidle" "$cpurawuser" "$cpurawsystem" | while read mib equals type digit ; do
case "$mib" in
  # This output is returned for the cpuidle value.
  UCD-SNMP-MIB::ssCpuRawIdle.0)
   cpuidlevalue="$digit"
  ;;
  # This output is returned for the cpuuser value.
  UCD-SNMP-MIB::ssCpuRawUser.0)
   cpuuservalue="$digit"
  ;;
  # This output is returned for the cpusystem value.
  UCD-SNMP-MIB::ssCpuRawSystem.0)
   cpusystemvalue="$digit"

   if [ -f "$tmpdir"/"$host".cpuidle ] ; then
    cpuidlediff=$(($cpuidlevalue - $(cat "$tmpdir"/"$host".cpuidle)))
   fi
   echo "$cpuidlevalue" > "$tmpdir"/"$host".cpuidle

   if [ -f "$tmpdir"/"$host".cpuuser ] ; then
    cpuuserdiff=$(($cpuuservalue - $(cat "$tmpdir"/"$host".cpuuser)))
   fi
   echo "$cpuuservalue" > "$tmpdir"/"$host".cpuuser

   if [ ! -f "$tmpdir"/"$host".cpusystem ] ; then
    echo "$cpusystemvalue" > "$tmpdir"/"$host".cpusystem
    echo "First run, gathering data."
    exit 3
   else
    cpusystemdiff=$(($cpusystemvalue - $(cat "$tmpdir"/"$host".cpusystem)))
    echo "$cpusystemvalue" > "$tmpdir"/"$host".cpusystem
   fi

   # Add all differences, so a calculation of the percentage can be made later.
   allcpu=$(($cpuidlediff + $cpuuserdiff + $cpusystemdiff))

   # Now calculate how many percent each value represents.
   cpuidlevalue=$((($cpuidlediff*100)/$allcpu))
   cpuuservalue=$((($cpuuserdiff*100)/$allcpu))
   cpusystemvalue=$((($cpusystemdiff*100)/$allcpu))

   # Now see if any of these percentages is over a threshold.
   if [ "$cpuidlevalue" -lt "$critical" ] ; then
    # First see if it's in a critical state.
    echo "CPU CRITICAL idle value: $cpuidlevalue%|cpuidle=$cpuidlevalue% cpuuservalue=$cpuuservalue% cpusystemvalue=$cpusystemvalue%"
    exit 2
   elif [ "$cpuidlevalue" -lt "$warning" ] ; then
    # Now see if warning applies.
    echo "CPU WARNING idle value: $cpuidlevalue%|cpuidle=$cpuidlevalue% cpuuservalue=$cpuuservalue% cpusystemvalue=$cpusystemvalue%"
    exit 1
   else
    # If neither critical, nor warning apply, it must be OK!
    echo "CPU OK idle value: $cpuidlevalue%|cpuidle=$cpuidlevalue% cpuuservalue=$cpuuservalue% cpusystemvalue=$cpusystemvalue%"
    exit 0
   fi
  ;;
  esac
done
}

# The calls to the different functions.
readargs "$@"
setvariables
checkvariables
getandprintresults

Don't forget to chmod (755) the script on the Poller(s).

Now go into the Centreon web front end and add a command at:
Configuration - Commands - Add.
I named the check "check_cpu" where the command line is:

$USER1$/check_snmp_cpu -H $HOSTADDRESS$ -C $ARG1$

Bind this check to a service template and bind a hostgroup to the service template. Remember Centreon does not use $USER2$, but $_HOSTSNMPCOMMUNITY$.

Pasting shell scripts from Microsoft Word into Putty

As a Linux/UNIX engineer you will have to cope with the strange behaviour of Microsofts products. Microsoft Word replaces a simple double quote (") for an angled quote. Now when you paste that code into Putty, your (angled) quotes are replaced for dots.

To correct this behaviour open Microsoft Word, click Tools then Autocorrection options and on the unselect Smart Quotes. (You may want to disable other "handy" features as well.

Finally, I am able to paste documented code into Putty!

Simple AWK script to show filesystems that are almost full

Here is a simple oneliner to show filesystems that are nearly full:

df -k | awk '$4 > 85 {print $7,$4}'

What it does;

  1. df -k - This displays the filesystems and how full they are.
  2. awk '$4 > 85 {print $7,$4}' - This prints the 7th and 4th column, when the 4th column is greater than 85.

An alternative to top for AIX

Almost everybody loves the GNU command top. Top displays information about what's going on at your system. Some systems don't provide top, this script can be used as an alternative for top:

#!/bin/sh

# If the shell script is stopped with CTRL+C, the screen
# might need to be sized correctly.
trap 'eval $(resize); exit 2' 2

# A loop to display activity.
while [ 1 ] ; do
eval $(resize)
output=$(ps -eF "pcpu time pid user comm" | grep -v TIME | sort -rn | head -$(("$LINES"-2)))
echo ' %CPU      TIME    PID     USER    COMMAND'
echo "$output"
sleep 3
done

Hopeful: Linux professionals will survive the recession

Linux professionals (administrators, engineers, architects) will manage during the financial crisis. That's what sites like Cyberciti predict.

It's hard to tell what the impacts of the recession will be for Linux professionals, but here is why "we" should be perfectly fine:

  • Linux is free - Sure it is, although the "enterprise programs" all cost money when you require support. Be aware that free (as in money) software does not mean installing and maintaining it is free; you need Linux professionals to help out.
  • Linux is scalable - You can start now for a limited amount of money, when better times arrive, you will be ready to expand your infrastructure.
  • Linux is stable - Invest some money now to setup infrastructure, when it's done it won't just stop working!
  • Linux is the way to go - For the server market Linux is very common. This will only grow in the years to come so you will be ready for the future.

Well Linux professional, hope that helps you to manage during these "interesting" times.

Aesthetics of shell scripting

Here is the problem; you need to print a single line filled with dashes. Will you just echo 80 dashes or write a beautiful loop for it?

The ease solution

$ echo "--------------------------------------------------------------------------------"

The aesthetic solution

$ n=0 ; while [ $n -lt 80 ] ; do printf "-" ; n=$(($n+1)) ; done ; echo

Both give the same result, but the easy solution is faster. Result from the machine where I am working on:

Test Easy way Aesthetics way
Time to execute: 0.000 seconds 0.039 seconds
Bytes on disk 88 70
Complexity level 1 7
System calls 37 657
lines printed in 1 minute 1471371 18318

The numbers show that simplicity is more efficient.

Prepare your Linux box for Daylight Saving Time (summer or winter time)

The summertime is starting soon. What can you do on your Linux machine to be prepared for Daylight Saving Time?

The bad news

Time is a very complicated matter; it shifts every half year, there are leap years and seconds, some countries change the start or end date of summertime, many countries have multiple timezones, some servers can be in one zone while the users can be in a different zone, and so on.
All the timezone information is stored in /usr/share/zoneinfo. The directories and files in there are definitions of what the displayed time should be. The displayed time is based on Coordinated Universal Time (UTC) adjusted to the rules listed in a timezone file in /usr/share/zoneinfo.
To modify the timezone for your computer; copy a timezone file to /etc/localtime. For example to set the timezone to Europe/Amsterdam:

# cp /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime

Chances are that your distribution has a tool available to help you. Use it; it's likely easier. Fedora uses a tool called system-config-time to manage time and timezones.

The good news

Most likely your Linux box is already prepared for DST. Above all that, Network Time Protocol (NTP) is so extremely easy to use, that syncing your time is no problem at all. To be prepared for DST, use NTP and update all packages on your Fedora machine like this:

# yum update
# yum install ntp
# service ntpd start
# chkconfig ntpd on

For any other distribution; update you system, install ntp and start it.

About Consultancy Articles Contact




References Red Hat Certified Architect By Robert de Bock Robert de Bock
Curriculum Vitae By Fred Clausen +31 6 14 39 58 72
By Nelson Manning [email protected]
Syndicate content