warning: Creating default object from empty value in /var/www/ on line 33.

Nagios utils.php script for PHP plugins

I couldn't find a "utils.php" script for making it easier to write nagios plugins in PHP so I thought I'd whip one up.  This is a combination of the utils.php from CVS I found laying around the web and a port of Nagios::Plugin::Range perl module.  It seems to pass all the tests that I found for the nagios plugins range documentation.

 * Created on Sep 14, (c) 2006 by Marcel K�hn
 * GPL licensed,
 * Ported nagios range checking from Nagios::Plugin::Range
 * by Doug Warner <>
function detectOS(){
	$arr	=	posix_uname();
	return strtolower($arr["sysname"]);
function verifyOS($supportedOSarray){
	$runningOS	=	detectOS();
		return TRUE;
		return FALSE;
function machineName(){
	$arr	=	posix_uname();
	return strtolower($arr["nodename"]);
class Nagios_Plugin_Range {
	const INSIDE = 1;
	const OUTSIDE = 0;
	protected $range;
	protected $start = 0;
	protected $end = 0;
	protected $start_infinity = false;
	protected $end_infinity = false;
	protected $alert_on;
	public function __construct($range) {
		$this->range = $range;
	public function valid() {
		return isset($this->alert_on);
	public function check_range($value) {
		$false = false;
		$true = true;
		if ($this->alert_on == self::INSIDE) {
			$false = true;
			$true = false;
		/* DEBUG
		echo "  R:$this->range; V:$value; S:$this->start, E:$this->end, ".
			"SI: " . ( $this->start_infinity ? 'T' : 'F') . ', ' .
			"EI: " . ( $this->end_infinity ? 'T' : 'F') . ', ' .
			"InOut: " . ( $this->alert_on == self::INSIDE ? 'I' : 'O') . '; ' .
		if (!$this->end_infinity && !$this->start_infinity ) {
			if ($this->start <= $value && $value <= $this->end) {
				return $false;
			} else {
				return $true;
		elseif (!$this->start_infinity && $this->end_infinity) {
			if ( $value >= $this->start ) {
				return $false;
			} else {
				return $true;
		elseif ($this->start_infinity && !$this->end_infinity) {
			if ($value <= $this->end) {
				return $false;
			} else {
				return $true;
		else {
			return $false;
	# Returns a N::P::Range object if the string is a conforms to a Nagios Plugin range string, otherwise null
	protected function parse_range_string($string) {
		$valid = 0;
		$alert_on = self::OUTSIDE;
		$string = preg_replace('/\s/', '', $string);
		$value = "[-+]?[\d\.]+";
		$value_re = "${value}(?:e${value})?";
		# check for valid range definition
		if ( !preg_match('/[\d~]/', $string)
			|| !preg_match("/^\@?(${value_re}|~)?(:(${value_re})?)?$/", $string)) {
			echo "invalid range definition '$string'";
		if (preg_match('/^\@/', $string)) {
			$string = preg_replace('/^\@/', '', $string);
			$alert_on = self::INSIDE;
		 # '~:x'
		if (preg_match('/^~/', $string)) {
			$string = preg_replace('/^~/', '', $string);
			$this->start_infinity = true;
		# '10:'
		if (preg_match("/^(${value_re})?:/", $string, $matches)) {
			if (!empty($matches[1])) {
			$this->end_infinity = true;  # overridden below if there's an end specified
			$string = preg_replace("/^(${value_re})?:/", '', $string);
		# 'x:10' or '10'
		if (preg_match("/^(${value_re})$/", $string)) {
		if ($valid
			&& ($this->start_infinity || $this->end_infinity || $this->start <= $this->end)) {
			$this->alert_on = $alert_on;
	protected function set_range_start($value) {
		$this->start = (integer) $value;
		if (empty($this->start)) {
			$this->start = 0;
		$this->start_infinity = false;
	protected function set_range_end($value) {
		$this->end = (integer) $value;
		if (empty($this->end)) {
			$this->end = 0;
		$this->end_infinity = false;

Western Digital 1.5TB Green Drives - Not for your Linux Software RAID

I recently bought a couple Western Digital 1.5TB "Green" Drives (WD15EADS) to rebuild my home media storage array with higher-density disks.  I already had one Segate 1.5TB drive (ST31500341AS) I was using for a "scratch" drive  (rpm mock builds, storing MythTV recordings, secondary backup) that I had problems using at all until Seagate released a firmware update, so I was skeptical about buying more of those.  I thought the green drives would be fine; that despite their variable rotational speed, the power savings and ability to spin up to higher speeds when needed would work out fine.

Unfortunately once I had a couple of these drives in a software RAID 5 array I began to notice problems.  When copying data to the array I would see decent transfer rates of ~33MB/s for 30-40 seconds but I would then see the transfer rate drop to 200-500KB/s for 2-3 minutes.  Since the array was initially built with only the WD drives I was pretty sure the problem was isolated to those drives.  Even after adding the Seagate drive the problems remained.

To test my assumption that the WD drives were somehow causing problems I began an rsync and waited until the transfer "paused".  I then did a "dd" against each of the drives in the array, seeking to a new position in the drive between tries.  It consistently showed the WD drive only getting 100-250KB/s while the Seagate drive would get ~90MB/s.

Once replacing all the WD drives with equivalent Seagate drives the array is resyncing at ~90MB/s; almost 3 times what I was getting with the WD drives alone.

When I first started seeing these problems with the WD drives I thought it might be related to the idle command so I downloaded the WDIDLE3.exe program to increase the idle time from the default 8 seconds to 25 seconds, and then later disabling the idle time out.  When this didn't fix anything I downloaded the WDTLER.exe program to enable TLER for the drives which also didn't affect the drives at all (I didn't expect this to since I wasn't seeing data completely stop or the drives drop out of the array).

I'm not sure what to do with these WD drives; while they seem to work fine independantly, they don't perform correctly at all when put into a RAID array.  I'm beginning to get afraid that as the hard drives get larger and larger the complexity of the firmware is growing too quickly for drive manufacterers to keep them performing reliably.

Default gnome-terminal size

Here's the command I found to set the default gnome-terminal height:

gconftool-2 /desktop/gnome/applications/terminal/exec --type string -s 'gnome-terminal --geometry=85x40'

Now when I hit "meta-t" I get the size gnome-terminal that I like.

Oh, to get "meta-t" to work, you might want to set this as well:

gconftool-2 /apps/metacity/global_keybindings/run_command_terminal --type string -s '<Mod4>t'

Setting up an hdhomerun and "no devices found"

I'm trying to get an hdhomerun set up and my firewall is getting in the way.

After stracing the hdhomerun_config binary and seeing that the discover calls out on the network broadcast ( here) on port 65001 I did some tcpdumping (also knowing my hdhomerun was at and I'm at

$ sudo tcpdump -i br0 -nn host or host
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br0, link-type EN10MB (Ethernet), capture size 96 bytes

11:08:07.093315 IP > UDP, length 20
11:08:07.093653 IP > UDP, length 20
11:08:07.093707 IP > ICMP host unreachable - admin prohibited, length 56
11:08:07.593858 IP > UDP, length 20
11:08:07.594196 IP > UDP, length 20
11:08:07.594239 IP > ICMP host unreachable - admin prohibited, length 56
11:08:08.093823 IP > UDP, length 20
11:08:08.094166 IP > UDP, length 20
11:08:08.094221 IP > ICMP host unreachable - admin prohibited, length 56
11:08:08.593821 IP > UDP, length 20
11:08:08.594135 IP > UDP, length 20
11:08:08.594179 IP > ICMP host unreachable - admin prohibited, length 56

11:08:14.843469 IP > UDP, length 20
11:08:14.843778 IP > UDP, length 20
11:08:14.843845 IP > ICMP host unreachable - admin prohibited, length 56
11:08:15.093830 IP > UDP, length 20
11:08:15.094152 IP > UDP, length 20
11:08:15.094228 IP > ICMP host unreachable - admin prohibited, length 56
11:08:15.593791 IP > UDP, length 20
11:08:15.594095 IP > UDP, length 20
11:08:15.594149 IP > ICMP host unreachable - admin prohibited, length 56
11:08:15.843824 IP > UDP, length 20
11:08:15.844131 IP > UDP, length 20
11:08:15.844195 IP > ICMP host unreachable - admin prohibited, length 56

So I can see that the hdhomerun is responding, but from random ports.

So poking a hole in my firewall for responses from (in case I have m udp source port 65001 I can communicate with this.  Now I'll have to see how streaming works once I get it added to MythTV.


New Years Update (3 month edition)

Lots of stuff have been going on around here.  I've been busy with a number of household projects and Jocelyn and Jared continue to grow.

Project-wise I've been busy setting up some home-automation. It's mostly focused on Christmas-y things right now, but I'd like to move it past that.  I finally found some wall switches that will allow me to replace my midi wall switches without converting everything to the paddle-type wall switches so I'm planning on replacing the switches for the outside lights so I can then remotely control them to turn them all on/off at the same time.

We also got a 40" Samsung LCD TV (LN40A550) for Christmas and I've been busy fixing various things to accomodate that.  I updated our Logitech Harmony remote to include the proper inputs for activities, but needed to contact Logitech to have them fix the input switching (it cycles to the previous input if the same input is selected again - a problem when switching to another activity that uses the same input).  I'm also having some problems with my PVR - video tearing and no surround sound.  The former problem is new, but I knew about the latter one for awhile, just hadn't looked into it.  I've ordered a new video and sound card to try to rectify those problems, so we'll see how that goes.

I've also been trying out new photo management software.  f-spot seems pretty nice and I'm pretty much ready to start importing photos into it. I have a problem where photos edited with it are inheriting the incorrect umask which needs fixed first.  This is one of the reasons I'm so behind on updating photos on my website; once this process is smoothed out I hope it goes a lot faster.

One of the reasons I haven't made more headway in that department is because I was sick for a couple days last week with a nasty stomach bug.  It only really lasted one day and another day to recover, but it of course removed an entire day of productivity that is difficult to get back with two little ones.

Jocelyn is growing up so fast.  Yesterday she started saying "love you" which was very exciting.  She's forming 3 and 4 word sentences for some things now, and her vocabulary is definitely growing every day.  She's not thrilled about going back to day care yet, but I'm sure she'll adapt quickly.  New schedules are always difficult.

We had tried taking her pacifiers away over Christmas but it Did Not Go Well.  There was a couple days where she refused to nap and was a royal grump.  We tried trimming the pacifiers since they were starting to die anyway, but that didn't work either.  After a couple days we ended up buying her new ones since she needs the sleep right now.  She only uses them to sleep and she definitely isn't the oldest toddler I've seen with one.  I'm sure it'll come in time.

Jared is getting big and learning new things as well.  He's at least 15 lbs (14 weeks) and sits very well in his Bumbo seat.  He has big grins for his mom, dad, and sister.  Jocelyn's really starting to warm up to him, and I'm sure once he starts sitting up and really playing with things in a couple months she'll be very interested in playing with him as well.

Dennis and Michelle moved up a couple weeks ago and we were able to go out to dinner with them last Friday.  It twas really nice to be able to see them and to be able to just sit and talk with friends w/o the kids around.  Tiff and I hadn't been out by ourselves since Jared came along and the break was very nice.

Tiff started back to work this week since taking off for maternity leave.  So far things have been going well, but it's too early to tell how much her kids will like her compared to her sub. that was in for most of the school year so far.

Other projects going on?  trying to build a new firewall that uses vlans and runs Fedora instead of CentOS to provide access to more up-to-date software.  Cleaning the garage.  Fixing my laptop.

Oh yeah, I need to write about the laptop.  My Dell Latitude D630 (purchased in Feb 2008) seems to have two primary problems right now:

  1. The battery is dead.  It last about half an hour and reports its run time incorrectly.  Luckily I contacted Dell about this before the warranty ran out (1 year on batteries)
  2. I have the dreaded "vertical lines" problem with my nVidia GPU.  Its looking like I'm going to get a motherboard replacement out of it. Joy.

While the battery problem wasn't critical, the video problem locks my laptop up when it happens, and it happens frequently after the computer is warmed up -- typically a couple minutes after booting now.  Evil.

Because of my laptop problems I've re-visited my need to get my homedir into a VCS.  I'm slowing getting this set up and will blog more once I have a better solution.  The biggest problem I'm running into right now is needing a way to symlink dot-files in place from my checked-out folder to my root home dir.  ie, If I check out my .vimrc to src/homedir/dotfiles-core/vimrc I need to symlink ~/.vimrc to ~/src/homedir/dotfiles-core/vimrc.  And I'd prefer to not do this manually.

I'm also moving my rss feeds from akregator into rss2email on my server.  This gives me two things: 1) I get updates even when my laptop is off, and 2) I can check my feeds from webmail.  I can also add new feeds remotely by ssh-ing into my server if needed, but that happens pretty infrequently.  I'd probably just email myself the link to add later.  The biggest thing going on with this right now is re-categorizing my feeds.

To categorize my feeds I'm giving them a custom email address to send the updates to; something like rss-(category)@.  Then my .mailfilter looks like this:

if (/^User-Agent: rss2email/:h)
    include ".mailfilter.rss"

and then .mailfilter.rss has:

if (/To:.*rss-([\w-]+)/:h)
    to "Maildir/.INBOX.rss.$MATCH1/"

# other lists
to "Maildir/.INBOX.rss/"

This allows me to easily add folders and categories without modifying my maildrop rc file.

I think that's it for current going-ons.  Maybe the next update won't be so huge.


Version controlling my home dir

For awhile now I've noticed that things in my home dir aren't setup optimally for my work flow. I've been trying to run with SELinux enabled and I run into development problems when I try to run web applications out of my home directory. Various parts of my home directory are version controlled separately due to the software projects they're part of, but not as a whole.

What I'd like is to setup some other place for "projects" (Mozdev code and docs, other software projects, RPM building, etc) and then version control my home dir.

The problem is I'm not sure how much this helps me. Things like IM clients still are going to want to log things to ~/.somedir/log which is evil. SELinux contexts for files in /home/myprojects is still going to be wrong; I'm not going to be able to run webapps out of there, either. Moving my docs out of my home dir might be a pain due to xdg-user-dirs needing to be setup correctly to point at the document dir

I'd really love to have a lean, mean homedir that is version controlled that I can port around between boxes. Have people attempted this before? What about the above problems?

This Modern Life

Jocelyn the Vi user

Jocelyn's definitely going to be a vi user; when she's done typing she immediately hits 'escape' and will pound 'escape' repeatedly when things aren't acting the way she thinks they should.

All your boxes are upgraded to F8

I finally have all my boxes upgraded to F8 (via yum; viva la Live Upgrage SIG!). It really wasn't as bad as I anticipated, and in fact, probably much better than my anaconda-based upgrade for F7 since I had all my third-party repos enabled for the upgrade and didn't have many stragglers after it was all done.

Two of my home servers were still running FC-6 (!!). These boxes presented some problems getting upgraded since they were running some more esoteric package sets. My one server gave me fits of problems with getting unmet dependencies for packages that clearly existed. This one was an x86_64 box and was giving me a "missing dependency" for glibc.i686. /me shrugs. "yum upgrade" rather than "yum upgrade yum* rpm*" seemed to get it fixed. I did have to remove a number of packages beforehand, but that didn't bother me much.

Overall I am very impressed with the F8 release. My statements earlier about Fedora not having enough direction were apparently completely without merit, or were just the result of not having enough first-hand experience with what had been going on. Hopefully I'll be able to give a bigger hand to development for F9 and keep the great work going.

Disable console blanking

echo setterm -powersave off -powerdown 0 -blank 0 >> /etc/rc.local

Argo hard drive upgrade with growing RAID1 array

Yesterday Kevin and I swapped in some 250G hard drives for our old 80G drives. The 80G drives were setup in a RAID-1 configuration. With our recent upgrade to CentOS 5 we gained the ability to do online growing of RAID-1 arrays, so it was a good time to upgrade (actually, it was planned that way ;-P).

So the first step was swapping the new drives in and letting the array resync each time. When replacing the drives, we also modified the partition so it utilized the entire disk.

Old disk:
/dev/sdb3 : start=  2313360, size=158513355, Id=fd

New disk:
/dev/sdb3 : start=  2313360, size=486078705, Id=fd

Then, all was required was to re-add the disk to the array to get it syncing:
$ mdadm --manage --add /dev/md1  /dev/sdb3

After each drive was finished syncing, we needed to get grub setup on the device again to use its own copy of /boot (props to the Dell Software Raid and Grub HOW-TO).

$ grub<br />
> device (hd0) /dev/sdb<br />
> root (hd0,0)<br />
> setup (hd0)

These steps were performed again for the other drive.

After both new drives were in, it was time to grow the RAID-1 array:
$ mdadm --grow /dev/md1 --size=max

After the array finished syncing, it was time to resize the filesystem:
$ resize2fs

And that leaves us with a much larger root partition! Where it was 90% full before, it's now 30% full:

$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/md1              229G   64G  154G  30% /


Some Clarifications and Concessions

My recent blog post about direction and online updates sparked some interest - and some interesting discussion. Through that discussion, I wanted to post some clarifications and concessions about the original article.

Concession: I wasn't correct about my statement that Fedora has a "lack of direction" - it's direction is exactly that its maintainers can try to do what they want to improve the distribution.
Clarification: Fedora is not an easy place to get along at - Just read fedora-devel list and you will find that most people post messages that are incredibly selfish and full of negativity - this doesn't feel like "community" to me. Even in my discussion on the #fedora-devel channel, my previous post was immediate construed as "OMG apt-get rulz FTW" fanboy love instead of the actual criticism that online updates should be supported. It still took an hour of discussion to get it understood what I was desiring and for some agreement and constructive ideas to come around
Concession: apt-get upgrade might not rock - I don't have strong experiences here and shouldn't have stated that it was great.
Clarification: Fedora should support online upgrades - "Online upgrades" means you can upgrade from release X to release Y without needing to reboot into some installer (rebooting for a new kernel or FS changes are fine). Fedora does have the YumUpgradeFaq wiki page, but the very first bullet point is Don't. This mentality needs to change in order for online upgrades to succeed.
Concession: someone needs take charge to make online updates happen - As gregdek pointed out, things don't change if someone doesn't champion it. At the same time, OSS is not only about "scratching your own itch", it's about community. Just because a user requests a feature doesn't mean we should expect the user to implement it every time.
Clarification: I'm excited about Fedora, and I'd love to help make it be better - I've been a Red Hat user for 8-9 years; and I've tried other distributions in the past. The issues I've pointed out are the ones that have been bugging me for awhile now, and the ones I'd like to see changed. I wasn't really prepared for the first reply to my blog to be "well do something about it", but they're right.

I had a good discussion with skvidal, wwoods, f13, gregdek, and others in #fedora-devel about how upgrades currently work, the progress being made towards media-less upgrades, and the problems faced by online upgrades. I hope to have the ideas and concepts laid out into a wiki page soon where everyone can contribute their ideas on how to improve things.

I'm also a little disappointed that no one made it to my last point - or perhaps they were so enraged by my first two points that they just stopped reading - about packages with optional features. I know it's been discussed a little bit on the fedora-devel list, but I have no idea what it would take or what maintenance would be like. That's probably something else I should work on writing ideas down about.

What Fedora needs is some direction - and online upgrades

Some of the biggest problems I see in Fedora these days are the following:

  1. Lack of direction

    Since Fedora is a distribution for developers by developers in order to test out new technology, the main tree ends up being a hodge-podge of whatever each individual maintainer feels like working on. Unless there is an individual or small group of individuals that desires things to be a certain way, then you have to abide by those rules (take for example, no kmods in Fedora).

    If Fedora had a better sense of what it should be doing it would polarize developers along the same path rather than everyone working for their own goals.

    For example, I haven't seen any real ground-startling features for Fedora 7 or 8. Sure, Fedora 7 had "the merge", but that mostly was for maintainers benefit (arguably) and again was driven by very few people. For Fedora 8 one of the "big features" was supposed to be a rework of the init system, but that's again been pushed off. Instead we get features like "online desktop" and "NetworkManager". While these do improve user experience, they are very small nitches that don't involve developers for all of Fedora - just tiny groups of people. Everyone else is left to do whatever they want, so long as they don't piss off one of the groups that are in control.

  2. Upgrades aren't supported - All hail Anaconda - the great upgraderinstaller!

    Fedora (and RHEL/CentOS) needs to be able to upgrade online, using a tool like yum (or smart, or apt - I don't really care which tool it is - right now it seems smart could handle it better than yum). Most of the other distros can do this without problems (Gentoo, Ubuntu, Debian).

  3. No optional featuresets for packages - You have packages that either include the feature or do not.

I'm not sure how to fix the problems, but I do know that Fedora needs to make the following happen:

  1. Make upgrades work - Even with Anaconda it wasn't possible to upgrade from FC-6 to F-7 without broken packages - an online upgrade would have arguable gone better, but it "wasn't supported". "yum upgrade" should work like "apt-get upgrade" between versions.

    With the rolling release like we've been having the past couple versions, it's very easy for someone with an up-to-date release have newer packages than are available with the release of the next version.

    Case in point: FC-6 had KDE 3.5.7, but F-7 shipped with KDE 3.5.6. Immediately after release 3.5.7 was available as an update for F-7, but an upgrade from FC-6 to F-7 wasn't supported due to libata changes (hda->sda). This stuff needs worked out so that you can update from one version to the next easily.

  2. Optional package features - Offer packages that can somehow enable/disable features based on what other packages are installed. Be able to install package foo that has either mysql or postgresql support, or both - even if they're compile flags. That is to say, if I have mysql currently installed, and I install foo, I get foo w/ mysql. Or if I try to install foo without mysql or postgresql, provide some way of saying that they can be supported if you install them.

Both of these problems are hard. They require coordination across all of the package maintainers. Perhaps they're features that could polarize the maintainers to a common goal and make Fedora better.


I've had this little script laying around for awhile that I use as a wrapper for RCS to check out a group of files in one batch, edit them all, and commit them. So I setup repository for rcsedit in case others want to try it out.

It should be pretty easy to try out, just:


Should get you the script to use. I typically install it to /usr/local/bin. It will use your default $EDITOR if you have one defined, otherwise it will use vim. If the files exist it will check them all out (or only the ones that exist), edit them, and commit them as one batch (allows you to enter a log message once for all changes).

Let me know if you can think of any improvements.

remotebackup project

For some years now I've relied on a script written by Lindsay Snider while at for all my backup needs. A year or so ago a presentation was done at CPLug that described the tool, and it was agreed that the script should become public somewhere so people can use it.

It wasn't really clear whose job it was going to be to setup the project publically, so it kinda just was forgotten. I was recently looking into backup tools again and decided it was time to get the tool out there and integrate my local changes into a canonical copy.

So now we have the remotebackup project with a public SVN tree.

Feel free to send any questions/comments/ideas my way for now while we work out the structure of who will be working on the project.