One of the largest problems you might have with Enterprise Grade Code is that it often isn’t.

Case in point: Program A and Program Module B does not know which hand is washing the other, or, indeed, which side it should be on… is it the top, or is it the bottom?

Module B was working, er, somewhat. All logging was failing, and any user stats were being bitswapped, but authentication features were functional.

Module A and B were running on the same platform, on the same hardware, with the same architecture. All IA32. All Apache 2.2.x with MySQL 5. All the same endian, even for the headers in the DB and Apache… Oh, yes, they’ve thought about these things, those desighers.

However, Module B was swapping things.

The authors of Module B evidently knew of this, and created a MODULEB_IP_REVERSED variable. This is a global variable, despite appearing otherwise.

Yes, it swapped the bytes for EVERYTHING that dealt with IP functions. Locally, externally, from Module B. Everything.

So, a user using Module B would be “1.2.3.4”, but once they were out of it, they’d be “4.3.2.1”. Lovely. At least they didn’t screw up the octets, just the storage, thereof.

I looked at the database (oh dear please don’t ask). It stores the IP as an unsigned int. Goody. This will be fun to fix.

So, I had to wrap all of the local functions, which, oddly enough, took an actual dotted quad syntax. Enter ‘nasty shim’ (product, of course, was written in PHP and Zend Encoded):

function ip_swap_addr($ip) {
  $Addr = ereg(":", $ip) ? array_reverse(explode(":", $ip)) \
  : array_reverse(explode(".", $ip));
  return (count($Addr) > 4) ? implode(":", $Addr) : \
    implode(".", $Addr);
}

So, now everything that passes an IP (has been wrapped by a little page which parses $_GET/$_POST, and searches for this, rewrites it, then passes it back to the original function in another page, before transparently posting back the results.

Yes, I made it fully IPV6 capable, because, damn it, I like to be safe with my “Enterprise Code.”

Today had to be a day with one of the more annoying sequences of everyday life that Administrators deal with.

  • To start off the day, I managed to get my new remote machines. Great! Er, why is everything dropping off every few minutes, and arp shows really odd things happening.. where are the machines going?
  • Oh, good. The new systems have a 4 minute watchdog in hardware that is resetting it because Linux is not talking to it.
  • Now someone disabled ACPI on my new remote machines during the ‘watchdog reboot’, so it killed the second CPU. I managed to fix that after wasting time, believing that it was my custom kernel configuration with some new security patches that may have caused an issue – after all, remote hands technicians never lie (or forget) what they were doing. (The CPUs would show, but be inaccessible with the stock SMP kernels, with a rather generic ACPI error, they they’d show in the scheduler and in /proc/cpuinfo. Yay for inconsistencies within Linux!)
  • So, I finally get a KVM installed so I can fix ACPI and the watchdog timeout for good (and see what other BIOS settings are incorrect), to FINALLY have the new Debian Security Update released, so I can revert to semi-stock configurations before these go live. I prefer to have more support, than less, after all.
  • The machines are once again running with all CPUs, and not rebooting themselves fifteen times an hour, and I was presented with the joy of recompiling the custom kernels all over again.
  • Finally manage get every machine globally updated, fixing PAE extensions for machines with over 4GB of data (this was implied, before, and mentioned nowhere in the config, of course), and during the test run, the system refuses to come back. Finally get Java shoehorned on a local Linux system so I can test it. The machine’s rebooted a total of 30 times, so it’s forcing itself to test the full drive for errors, but, no, everything’s fine. Finally.

...how was YOUR day?

Yes, I know. It’s been a long time coming. I’ve been thinking about it, but every time I considered building it, I opted to find real work to do, instead.

However, ImagePup has Automatic Thumbnails!. I’ve added code to resize the image and create a thumbnail for your specific image, with the dimensions of that image embedded within the image, itself.

I’ll eventually work on the ‘multiple file upload’ system, as well.

Eventually.

Debian Etch (the current stable distribution) is bundled with MySQL 5.0.32. While it works, there is a problem with replcating that data to other MySQL servers. This is fine for most users, however, I’ve built in a highly fault-tolerant enterprise.

As you’ll find, MySQL prior to 5.0.38 has a nasty problem: it will most likely mangle any AUTO_INCREMENT field’s value.

This is bad. People who write for MySQL use this almost extensively for an index key, and many rely on these numbers for sub-indexes. Something as simple as a ‘comment on this page’ form can be broken.

Fret not, though, for we can make our life easier (for now) by utilizing the 5.0.38 source package available within Sid’s repository, however, keep in mind that you should audit this to ensure it will work properly for you, as it has not completed regression tests:

First, make sure we’ve got adequate support software, libraries and headers to build our software (the below is somewhat cheating, but there are currently no major library changes required between Etch, and Sid):

# apt-get build-dep mysql-server wget dpkg-source
# wget http://ftp.debian.org/debian/pool/main/m/\
  mysql-dfsg-5.0/mysql-dfsg-5.0_5.0.38-3.dsc
# dpkg-source -x mysql-dfsg-5.0_5.0.38-3.dsc
# cd mysql-dfsg-5.0_5.0.38
# (fakeroot) debian/rules binary

You may now install the built binary packages.

I’ve seen this happen a few times, and it’s incredibly simple as to why: Somebody screwed up.

No. Really.

What’s happening about 90% of the time, is that there is a colission between installations. PHP usually uses a dynamic mysql library. Apache auth modules such as 2.2’s internal auth_dbd, and mod_auth_mysql also usually link against a dynamic mysql library.

If you happen to change your development mid-stream and don’t recompile everything, here’s where problems can occur.

To put it as non-geeky as possible: If the MySQL client is v5, and PHP uses this v5, but mod_auth_mysql is using v4, they both are asked to load, end up with with the same functions, and BAM.

It’s kind of like shouting “Hey, Steve!”, and having two guys answer “Yes?” The only difference is, UNIX doesn’t know how to act embarrassed and politely wave over the one that was intended.

Although, this analogy isn’t entirely true. It just makes it easier to understand. PHP wanted Steve v5, and mod_auth_mysql wanted Steve v4. So, when they both tried to call for Steve, both of them ended up in the same place.. which made bad things happen.

You can use ‘ldd’ to see which dynamic libraries are used by which programs, and other libraries.

# ldd /usr/lib/php4/20050606+lfs/mysql.so | grep mysql
        libmysqlclient.so.15 => /usr/lib/libmysqlclient.so.15 (0xb7d6e000)
# ldd /usr/lib/libaprutil-1.so | grep mysql
        libmysqlclient.so.15 => /usr/lib/libmysqlclient.so.15 (0xb7c56000)