Feb 2 2010

Defeating the AC_CHECK_HEADER cache

The AC_CHECK_HEADER macro caches its result, so if you want to call it again with a different CPPFLAGS it will just remember the result of the first execution.

If you want to defeat this cache, as I did, this is the pattern:

header=foo.h
cache_var=AS_TR_SH([ac_cv_header_$header])
...
AC_CHECK_HEADER([$header])
...
CPPFLAGS="-I/opt/local/include"
$as_unset $cache_var
AC_CHECK_HEADER([$header])
...

AS_TR_SH does the escaping (giving ac_cv_header_foo_h in this case), $as_unset is the portable way to unset a shell variable in autotools.

Incidentally, if you don’t restore CPPFLAGS to its original user-set value, I will hunt you down and shave your head.


Oct 8 2009

AC_TYPE_UINT8_T and friends

If you get errors like this:

$ autoreconf
configure.ac:110: error: possibly undefined macro: AC_TYPE_UINT8_T
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
configure.ac:111: error: possibly undefined macro: AC_TYPE_UINT16_T
configure.ac:112: error: possibly undefined macro: AC_TYPE_UINT32_T
configure.ac:113: error: possibly undefined macro: AC_TYPE_UINT64_T
configure.ac:115: error: possibly undefined macro: AC_TYPE_SSIZE_T
autoreconf: /usr/bin/autoconf failed with exit status: 1

It probably just means you have an old autoconf. These macros were introduced in autoconf 2.60. But it’s probably no big deal if you have a sensible stdint.h.


Aug 24 2009

Terminal Merge Conflict Resolution

A very important tool in the toolbox of any collaborating developer is a merge conflict resolution tool. OS X has the fantastic FileMerge, there are various graphical tools for linux like kdiff3, but I have yet to hear of one for the terminal. There’s vimdiff, but it is really not up to the task of merge conflict resolution (doesn’t handle 3-way diffs). There’s probably something in emacs, just because there’s always something for emacs. Emacs users please enlighten me, I’m not above using emacs for merge-conflict resolution. Might even be the gateway drug.

It doesn’t seem overly hard (at least, no harder than writing kdiff3 or FileMerge) to make an ncurses tool that will take a 3-way merge and let you efficiently choose A, B, or edit for each diff section. Can it really be that nobody has done it yet?


Jul 15 2009

Encoder mailbox not found

My PVR-150 that I got used from eBay would occasionally spaz out and complain “Encoder mailbox not found” when trying to load the firmware. It happened when I first got it, then didn’t happen for months, then happened again and went away with a reboot, then happened and wouldn’t stop until I switched PCI slots.

Then it worked, for about an hour, and puked with “Encoder firmware dead!” or something like that. Something was dead, anyway. I took this as a sign that it wasn’t a driver or IRQ problem, but a bad card. (Yes, I’m rather thick.) So I got a (supposedly) new card from eBay for just a few more dollars than the original used one cost. It has been working for several days without complaint, so I think it must be a bad card.

But if you want to try your luck with this PVR-150, I’ll be happy to mail it to you. Maybe it was a problem with my VIA motherboard.

And most importantly, for those of you out there searching for “encoder mailbox not found”, it may just be time to get a new card. If not, try switching PCI slots.


Apr 10 2009

Kill your Kids

Not literally, of course. This is programming talk, those of you who aren’t programmers can let your eyes glaze over.

I wanted a script to start a bunch of little servers, then wait around for them to finish or when the user interrupts with Ctrl-C, clean up the servers instead of orphaning them. I wanted to propagate the SIGINT to the child processes. I wanted to kill the kids.

The simple way, if you just want to make sure the kids are killed and you don’t care how:

sleep 300 &
# etc.
trap "kill $(echo $(jobs -p)) 2>/dev/null" EXIT
wait

If you only want to trap SIGINT and want to make sure you send SIGINT (not SIGKILL) to the children, then you want to do something like:

trap "kill -INT $(echo $(jobs -p)) 2>/dev/null" INT
wait

Update: I was asked by a shell scripting guru why I needed to do $(echo $(jobs -p)) and not just $(jobs -p). I intended to cover that but forgot. The reason is that $(jobs -p) has newlines and while that’s not usually a problem it is in a trap statement, because it’s evaluated at creation time not at run time. It also means that processes created after you create the trap wouldn’t be killed. Then, he suggested a function instead. Pure brilliance. Where does he come up with these things? Here’s the improved version:

function killkids() { kill $(jobs -p); }
trap "killkids" EXIT

You can still redirect stderr if you want to, but the reason I was directing stderr was because some of the kids may have already died (early evaluation remember) and then kill would needlessly complain. This way, it kills all the kids that are still alive, none more none less.


Feb 18 2009

git GUIs

One of the nice things about git is due to its UNIXy design and its massive and ever-growing popularity, there are a lot of really nice bells and whistles, and I think we can expect to see even more. For example, GitHub.

While most git interaction is with simple commands in the terminal, it often pays to be able to get a birds-eye view of the revision history, or what I will call the DAG. The original tool for this is gitk. Gitk is functional, but it’s really really unpleasant. It’s written in Tcl/Tk—what did you expect? Some of us have higher standards for usability.

I tried out a few git GUIs and I have settled on two that I think are best of breed. The first is tig. Tig is an ncurses program, so it excels for remote operation over ssh, for quick dives into the repository without reaching for the mouse, and in keyboard use. Think of it as mutt for git. It’s a fantastic program and I use it most frequently.

I have customized my tig setup slightly:
$ cat /Users/fugalh/.tigrc
set show-rev-graph = yes
color cursor white blue
$ alias | grep tig
alias tiga='tig --all'

The second is GitX. It’s a mac app in every good sense, and it’s an excellent git GUI. As you can tell from the screenshot, it’s a bit easier on the eyes for visualizing complicated DAGs (not that this screenshot is of a complicated DAG).

If you use GitX be sure to “Enable Terminal Usage…” so you can start it on the current repository on the terminal by typing gitx.


Feb 14 2009

ssh tricks

Dennis Muhlestein posted a quick ssh tip, and then a couple of really neat gems emerged in the comments. For the sake of those who didn’t click through, and my non-Utah readers, I repeat them here:

  1. ssh-copy-id is a little utility to copy your public key to a remote server. Passwordless authentication has never been easier to set up!

    ssh-keygen -t rsa
    ssh-copy-id $remote_host

  2. ControlPath reuses the same connection for subsequent logins, so if you ssh into the same server from several terminals the logins after the first happen much faster. This is a really neat trick.

    # in ~/.ssh/config
    Host *
    ControlMaster auto
    ControlPath ~/.ssh/master-%r@%h:%p


Jan 15 2009

VPN DNS

I have a VPN and a DNS server that serves up forward and reverse DNS for my VPN hosts, which zone I call wan. When I want to look at my Cacti graphs, I go to gwythaint.wan and as long as my laptop is on the VPN I can see them wherever I am. In theory anyway. In practice, getting this to work without screwing up other things is harder.

I’ll leave out the myriad permutations that I tried over the past couple of weeks and show you the one that actually works well. That is to have a caching and forwarding name server on your laptop, and to add localhost to your list of nameservers. For best results, you would have it forwarding to the name server your DHCP server gives you, with an explicit forward over the VPN for the wan zone (and its reverse). resolvconf on Linux can do this. Your situation may warrant a static forwarder for non-wan addresses, in which case you just set that forwarder and be done with it. If your various DHCP nameservers are a bit more subtle—perhaps serving up internal domains of their own—then you may have to not forward and/or recurse except explicitly for wan.

I just took the default BIND9 configuration on my system and tweaked it thus:

// local/vpn stuff
zone "wan" {
    type forward;
    forwarders { 172.17.77.1; 172.17.0.1; };
};
zone "17.172.in-addr.arpa" {
    type forward;
    forwarders { 172.17.77.1; 172.17.0.1; };
};

On most systems the default named.conf is already some reasonable caching setup, so you wouldn’t have to tweak it beyond that. Then I added localhost to the nameserver list (/etc/resolv.conf on Linux, in the network preferences pane on OS X) and checked that it works with a dig @localhost gwythaint.wan.

Things got tricky because dig and host on my laptop were taking forever to
return when I queried localhost—6 seconds or so. I chased this wild goose for
awhile and in the end I didn’t find the reason (it still does it), but I
verified that it’s not a problem. If you use the -v flag to host you notice
that the actual queries took <1ms, so whatever else host and dig are doing may
not be relevant. Even stranger, if you do host -v gwythaint.wan and don’t
specify to query localhost, everything resolves instantly and yet it reports
that it queried localhost (which you can verify with the non-traffic on repeat
requests via tcpdump). It hasn’t slowed down any other applications (a 6-second
slowdown on DNS lookups would be very obvious), so I chalk it up to “who
cares?” If host and dig on OS X return the right answer, and you verify they’re
querying the right server, then you’re good to go.


Jan 10 2009

Moving MythTV

I had MythTV on falcon, then I got a new graphics card for gwythaint and so I moved the frontend to gwythaint (HD, yay). Then I got a new hard disk and decided to put the big disks in gwythaint, which meant falcon no longer needed to be a mythtv backend of any sort (gwythaint was already doing all the transcoding). Moving the mythtv backend was not as simple as it should have been. These instructions outline what I did at first. The database step was not an issue, and of course copying was simple enough, but MythTV couldn’t find my moved files.

Poking around in the logs revealed it was still trying to get the movies from falcon, even though I had removed the backend on falcon. So as a stopgap I reinstalled the backend on falcon, set it up as a secondary backend, and set up a samba share so it could access the MythTV data storage directory. Now whenever I watched anything it would go back and forth across the LAN. Whee!

I was puzzled by these assertions that you can just move files between storage directories and MythTV would just find them, when it didn’t seem to be even trying on my setup. Then it came to me in a flash of insight. It wasn’t trying to look for them because it thought they were still there. I had the same data storage directory path on both machines: /av/myth. It saw the filenames it expected in gwythaint:/av/myth and so it assumed that no update was needed, although the files were originally on falcon:/av/myth. So I created a symlink from /av/myth to /av/myth-dummy and added that to the storage group. Still, that did not help.

The final solution was to hack the database directly:

mysql> update recorded set hostname='gwythaint' where hostname='falcon';
Query OK, 53 rows affected (0.00 sec)
Rows matched: 53  Changed: 53  Warnings: 0

Jan 10 2009

Sensible Graphs with Cacti

I love Cacti. It’s an excellent tool for visualizing interesting statistics like bandwidth usage, CPU and load average, memory usage, etc. It’s relatively straightforward to set up, if slightly klunky, and it takes a lot of guesswork out of questions that are otherwise difficult to answer. (I should note here that Cacti is a sort of front-end to RRDtool which does all the hard work as far as the visualization is concerned.)

But some of the default graphs that come with Cacti are absolute rubbish. I took it upon myself to fix the two worst offenders this week: the load average graph and the memory usage graph. Let’s compare, shall we?

Here’s the default load average graph:

default load average graph

This graph is just plain wrong. It stacks the load averages one on top of the other which makes it impossible to get a real reading for the 5 and 15 minute averages, and makes things look worse than they are. If that textual explanation went over your head, compare with this repaired load average graph and all will be made clear:

my load average graph

Wow, you can actually see how the averages are, well, averages. Funny thing about proper graphs.

This change is simple enough to do yourself so I won’t provide a template download in the interest of expanding your mind (hopefully without exploding your skull). Right after I show you my pretty memory usage graph, that is.

First, let’s see the default memory usage graph:

default memory usage graph

If you can tell what that graph is saying at a glance, you’re better than I. This one doesn’t so much lie as beat around the bush. The vital information is there, if you know how to read it. The key is that the stuff you see totals the RAM that is available for programs to consume (free+buffers+cache), so the smaller the area of the graph, the less memory you have available. It also doesn’t show swap. Swap is available on another graph (also in terms of free swap not swap used), but on a separate graph you miss out on the relative comparison.

Here’s the memory graph I came up with:

my memory usage graph

I think it is self-explanatory and that it has all the information you could ask of a memory usage graph presented in the clearest possible way. Maybe I’m a bit biased, but you have to admit it’s better.

So how do we modify and create graphs in Cacti for fun and profit? Let’s begin with the load average graph. No, scratch that. Let’s begin with some terminology.

Cacti has graph templates that define what the graph will look like. We’ll spend a lot of time creating and modifying those. It also has data templates for telling it how to get the data (e.g. the SNMP OID or the script to run). You use a data template to create a data source which actually fetches and stores that data, and you use a graph template to create a graph that is associated with a device (host) and its data sources. Data sources are usually created automatically when you create a graph. There’s one more oddball thing called a CDEF which is basically a rudimentary RPN calculator that you have to define the expressions for ahead of time in the most excruciatingly painful way. But we’ll need a couple for the memory usage graph.

SNMP stands for Simple Network Management Protocol, which naturally means that it’s the antithesis of simple and that it is mostly used for monitoring instead of management (though you can indeed use it for management, which is way beyond the scope here). The short of it is, you have devices that talk SNMP and you can get info about interesting things that you’d like to graph with Cacti over the network. If you have a linux box, it can be made to talk SNMP by installing Net-SNMP and configuring it.

SNMP version 3 is a complicated mess to configure because you have to have a PhD in network security to understand its authentication schemes (in which case you might conclude that it’s not secure enough). Versions 1 and 2c are both sufficient for my needs, and from our point of view they’re essentially identical and simple enough to explain. I’ll assume you use version 2c. There’s a cleartext password for read-only access and optionally one for read-write access (for that management thing that we don’t do). In order to keep things (anti)simple, they’re not called passwords but rather “community strings”. The default community strings for when you really can’t be bothered to change them are “public” and “private”, and most SNMP devices come with these defaults preset. What’s that? You didn’t realize you had several (dozens?) of devices on your network just waiting for some bored employee to start playing with its settings from the comfort of his workstation because you didn’t change the default read-write community string? Well, you do.

Here’s the snmpd config file I use, which I don’t mind sharing because the only way you can get to it is over my LAN or my VPN, and it’s read-only anyway and I have no secrets about my host stats.

rocommunity  yoursecrethere
syslocation  "Las Cruces"
syscontact  hans@fugal.net
sysservices 79

If you can’t figure out how to tweak the configuration file included with your distro (which is no doubt hundreds of lines long with loads of comments), you can replace it with something like that and you’ll be up and running with SNMP version 2c.

Ok, now you can install Cacti. Then create a device using the ucd/net SNMP device template for the host you want to monitor (you don’t technically have to do that with localhost but you’d have to modify my graphs to use the non-SNMP data sources). When the device is created and it says it was able to connect to it ok, then you can create graphs for the device. Go ahead and create the “ucd/net – Load Average” graph. Then you’ll no doubt dash over to the graphs “tab” and be totally dismayed that the graph seems broken. Fear not, it’ll show up once it’s had some time to gather data (check back in 5 minutes).

In the meantime we can go fix the load average graph template. Any changes we make will apply to the graph we just created as well as any new graphs we create with that template. Go to “Graph templates” on the left then find the graph of interest and click on its name. Take a moment familiarizing yourself with this page, then click on the 5 minute average item to edit it. Here you change the graph item type from STACK to LINE1. I also changed the color to 002ABF which shows up better. Do the same for the 15 minute average item (LINE1, I left the color alone). Now go refresh your graph and you’ll see the changes. Et voilà, you are a Cacti graph template hacker. At this point you may feel the irresistable urge to change the colors of some of the more ugly but functional graphs, and I won’t hinder you. I’ll wait right here.

Ok, the memory usage graph is a bit more work. I won’t take you through it step by step but I’ll point out a couple of gotchas that I encountered when creating it. First, I realize that others have made memory usage graphs and provided them on forums and such to download. After the third one failed to work I decided it was better to just make my own. Hopefully mine will work for you—I put a bit of effort into making sure it would import cleanly.

There’s actually a reason why the memory usage graphs are so backwards: because most devices provide total and free stats but not used stats. Obviously they expect you to calculate used yourself. So directly graphing the bits provided by SNMP was the easy way out.

We, on the other hand, have chosen the path of pain. We need to calculate memory used (which is total-(free+cache+buffers)). We could do this with a script but that’s sticky and not very portable (depending on the target distro, version of Cacti, etc.). The better thing is to use a CDEF. If you click on graph management the CDEFs link is revealed. We want a CDEF that calculates (total-free-cache-buffers)*1024 (the sources are kilobytes). Now, a CDEF uses a positional reference system. The first data source used by your graph is a, the second is b, and so on. So the CDEF string will look something like d,a,-,b,-,c,-,1024,*. But here’s where things get dodgy—it’s hard to know what order the data sources will settle on until after you’ve created the graph. If you create the graph in the right order (no shuffling) and you realize that the AVERAGE and MAX consolidation functions create separate data source (but not LAST), and who-knows-what other pitfalls, then you can be confident ahead of time. Or, you can just create the template, create a graph using the template, and look at the graph debug output to figure out which source is which.

So now you create a new graph template, and referring to a template similar to what you want you fill in all the right fields, leave most at their defaults, add graph items, tweak and refresh a sample graph using your template a gazillion times, go back and forth with the CDEFs getting things right, then create new (temporary) graphs to make sure it works.

Luckily for you, if all you want is a cool memory graph, I did all this for you. Download and import my memory usage graph template, create a graph, and in a day or so you’ll have a memory usage graph as pretty as mine. Oh, alright, I’ll provide a load average template for you as well.