NRPE returning no output?

command[check_recent_core]=PLUGINPATH/check_recent_core.sh --file="$ARG1" --freshness=$ARG2$

Spot the error? I only wasted an hour of my life and another 30 minutes of co-workers trying to figure out why I kept getting a "NRPE: No output returned from plugin" error in Nagios. The issue? $ARG1 is missing a closing “$”. *slams head on desk*

Useful C Debug Macro

Tonight I took the plunge to get back into some more C coding. In getting my environment setup I came across a useful debugging macro. This macro will output the filename and line number every time it’s expanded. I wanted to make sure I understood how the macro was working before just copying and pasting it into my source code so I’ve broken it down below for myself and others to understand.

Here is a copy of the code that I slightly modified to also include the function name from where the debug macro is being used.

First we check if the DEBUG macro has been defined at all. If it has been, we declare a function-like _DEBUG macro that will get expanded to our debugging function. If DEBUG has not been defined, we still declare our function-like macro the same but with just no body so the macro will not be expanded to anything.

Our _DEBUG macro makes use of a few predefined macros:
__FILE__: Expands to the current file name. This will not print the shortname of the file.
__FUNCTION__: Expands to the current function the code is being executed from. This is a C99 and GCC feature only.
__LINE__: Expands to the current line number in the file

We also make use of ‘variadic macros’ aka macros that accept a variable number of arguments. A variadic macro can be defined named or unnamed. We use the named method which involves putting an argument name followed by ‘…’ which is later referenced by just using the argument name in the macro body. An unnamed variadic macro just involves using ‘…’ and later referenced in the macro body using the predefined macro __VA_ARGS__

A default format string is passed into printf to take care of the formatting for the filename, function name and line number. Immediately after the default format string, we specify the fmt argument we used that will get assigned our own format string that we pass into the _DEBUG macro. This will all get expanded to "%s:%s:%d: " "val of fmt" which is valid C syntax.

To activate the _DEBUG macro we can define DEBUG in our gcc command

gcc -g -D DEBUG

My Stay Puft Marshmallow Man Moment

A couple years ago I was sitting at a poker table for my final interview for a sys admin position with . It had been a long day of mentally exhausting questions, and the interview was coming to a close. The person I was interviewing with sat for a moment and pondered his next question for me.

“You’ve got a building across the street with a bunch of data on a server. The building is on fire. You’ve got a connection between the two buildings. What’s the fastest way to get the data over to you before the building burns down?”

“I’d use dd over netcat”
What the fuck did I just say?

The interviewer gave me a strange look and asked me to elaborate.

I knew right away what I said was not the best answer. In fact, I knew anything I would have said at that very moment would have been wrong. As soon as I heard the question, “I couldn’t help it. It just popped in there.” There was more information needed to answer the question correctly. I spent the next few minutes awkwardly elaborating on the idea and eventually shifted into a completely different answer as I talked out the problem more.

Part of being a sys admin sometimes means having to make important decisions during major disasters. These issues will come up at anytime, and they don’t care if you are running on 2 hours of sleep. The worst thing to do in these situations is to act on the first thing that pops into your mind. Seemingly harmless commands can turn into disasters quickly. Stop and think for a few moments, gather additional information and formulate a few possible actions to take. The few moments spent thinking before taking any action could be the difference between a smooth outage and an outage where a 100 foot tall marshmallow man comes marching out of the Temple of Gozer.

Determining my most used focal length in photos with python and dcraw

For the holidays I got a new Canon 7D camera. I’ve been saving quite a few amazon gift cards over the last year that I was previously planning on using towards purchasing the camera but thankfully Santa delivered me one. My current lens collection consists of

The lens collection has been built over the last 4 years from when I first got my Canon Rebel XT and I’ve been fairly happy with them thus far. As part of looking into what new lens to get I wanted to know what focal length I shot with the most over the previous years. A quick look with

find . -type f -name '*.CR2' | wc -l

shows I have 4697 RAW images in my photos folder, so I’ll need some sort of automated solution to figure this out.

My first inclination was to poke around Python’s PIL and see if it supported reading of RAW images, it didn’t appear to do so that option was out. I looked at the Canon RAW format at http://www.sno.phy.queensu.ca/~phil/exiftool/canon_raw.html and contemplated doing some parsing of the files to extract the info I needed from the EXIF data. I remembered in the past I had used UFRaw to play around with RAW conversion in Linux a while back and saw they are using a nice simple tool to do their RAW parsing called dcraw. It’s a small C program that I was able to compile the source with the following commands…

sudo apt-get install libjpeg-dev liblcms-dev
gcc -o dcraw -O4 dcraw.c -lm -ljpeg -llcms

Using dcraw seemed like the path of least resistance and now I just needed to wrap some code around it to go through all of my RAW images and extract the EXIF info and keep a hash table of the focal length value. I whipped up a small python script and posted a gist of it over on github.

It’s fairly straight forward and could easily be modified to do more, like collect aperture sizes or any other EXIF data. I may go back and build it out a bit more to make it more flexible in what data it collects, but for now this suited my needs at the time. My top 10 focal lengths ended up being

Total pics to process: 4697
Length: 50.0  , Count: 1624
Length: 22.0  , Count: 576
Length: 18.0  , Count: 423
Length: 200.0  , Count: 404
Length: 55.0  , Count: 373
Length: 10.0  , Count: 192
Length: 70.0  , Count: 176
Length: 37.0  , Count: 74
Length: 16.0  , Count: 33

Takes close to 11 seconds on average to calculate that for 4697 images.

I had been wanting to upgrade my 50mm f/1.8 lens for a bit as I’d really started to notice the short comings of it. The lens has a hard time focusing and also had a bit of a back focusing issue. Since my Uncle borrows my camera a lot when he goes on vacation I worked out a deal with him to purchase the 50mm f/1.4 for me and in exchange I’d give him my old Canon Rebel XT with the kit lens and the 50mm f/1.8 lens.

The kit lens was a great walk about lens so I’m currently trying to decide on a good and reasonably priced lens to cover somewhere in the 18-100mm range. I’m reading through a bunch of comments on amazon reviews and dpreview forums to figure out what my best bang for my buck would be for a lens in that range.

Python pip on Ubuntu Lucid Lynx

Lately I’ve been reading up on Django a bit in an effort to get back into programming.  It seems the preferred way of running Django is inside a virtualenv environment.  I try to stick to packages when possible for installing applications and saw that the python-virtualenv package wasn’t too far behind at version 1.4.5, where the latest is at 1.5.1.  This appeared at first to suit me just fine until I discovered the version of pip that gets installed along with python-virtualenv is at 0.3.1, where the latest is at 0.8.1.  The version of pip installed is so old that it doesn’t have support for the “uninstall” command yet, blech.  Luckily you can do the following from within pip to upgrade itself

sudo pip install --upgrade pip

Now back to reading about setting up a virtualenv environment