Sept. 8, 2006, 12:17 a.m.

Lighttpd on an Old IRIX

I know way more about porting stuff to IRIX than anyone should. I finished getting lighttpd running on my oldest running computer. As horrible as it sounds, and probably is, this machine is still running the same install of the same OS it had when I bought it. Sure, I've applied patches when I've got around to it, but nothing beneficial to porting modern software to it.

Let me start with a brief description of the machine:

bleu:~ 823> hinv
Iris Audio Processor: version A2 revision 4.1.0
1 133 MHZ IP22 Processor
FPU: MIPS R4600 Floating Point Coprocessor Revision: 2.0
CPU: MIPS R4600 Processor Chip Revision: 2.0
On-board serial ports: 2
On-board bi-directional parallel port
Data cache size: 16 Kbytes
Instruction cache size: 16 Kbytes
Secondary unified instruction/data cache size: 512 Kbytes on Processor 0
Main memory size: 64 Mbytes
Vino video: unit 0, revision 0, IndyCam not connected
Integral ISDN: Basic Rate Interface unit 0, revision 1.0
Integral Ethernet: ec0, version 1
Integral SCSI controller 0: Version WD33C93B, revision D
  Disk drive: unit 1 on SCSI controller 0
Graphics board: Indy 24-bit

As far as the parts that actually matter, that's roughly the same hardware that's in my embedded router. bleu was the first computer I ever bought, though. There's sentimental value there. It sucks to make stuff on it, though. To contrast, either of my laptops contains 32 times more memory and dual cores at 16 times the clock speed. That and old software means that anything I want to do over there takes a really long time.

The first thing I ran into was a reference to snprintf. Nope, this vintage of IRIX doesn't have it. It turns out it's not necessary for this particular application. I usually just implement it myself (poorly), but an assertion and sprintf fit this particular task just fine -- probably even better because there was an assumption in the code stated in comments, and I don't think good things would come to those who didn't meet that assumption.

The next problem was IDO wouldn't compile the following code:

 struct { char *x; int y; } stuff[] = {
      { "blah", "blah" ? sizeof("blah") : 0 } };

It looks a little odd, but that's an approximation of what it looked like in there (due to macro expansion). The macro would work when not trying to create the struct instance, but would otherwise. IDO's complaint was Invalid constant expression. Apparently it thought it inappropriate to check a literal string for null. I guess that's reasonable. Redefined the macro.

With some more playing, I got it to build. However, there was a pretty nasty problem at runtime. I was getting an EINVAL from writev. I added a bunch of asserts for the documented reasons it claimed to error, and added giant piles of logging to visually inspect it.

To cut out the long part of trying to figure out what was going on in there, let me just quote the writev man page:

iovcnt was less than or equal to 0, or greater than IOV_MAX.

Now, here's the problem... IOV_MAX is just not defined anywhere. I think the spec requires it not be implemented just to mess with people. I looked up writev in Advanced Programming in the UNIX Environment only to find the following:

4.3BSD and SVR4 limit iovcnt to 16. 4.3+BSD defines the constant UIO_MAXIOV, which is currently 1024. The SVID claims the constant IOV_MAX provides the System V limit, but it's not defined in any of the SVR4 header files.

Well, that's consistent with my experience. The author of lighttpd had apparently worked with a later version of IRIX and discovered the value to be 512, so hard-coded it accordingly. It's 16 on mine. If you happen to have a working IRIX machine, sysconf IOV_MAX will tell you what it is on yours.

After I sort of barely had it working again, I still needed to get SSL running. I ended up upgrading my OpenSSL, which isn't a bad idea, but took at least an hour. It ended up being built with -n32. Now, I wouldn't expect you to know what that means if you're not someone who ports a lot of code to IRIX, but it means Make this code incompatible with lots of other stuff. So, I had a build of lighttpd with -n32 and a build of OpenSSL with -n32, but PCRE had been built without -n32, so I needed to do a new build of that. It was that or rebuild OpenSSL and lighttpd.

I've still got pieces that aren't working, but overall, I've changed web servers on bleu for the first time in about ten years. I still need to figure out how to actually use that SSL I've enabled myself. I've worked around most of the feature mismatch coming from Apache. I'm sure finishing this up will require writing some more code.

I'm currently using mod_proxy as a connector to JBoss. While not necessarily as nice as AJP from the point of view of the typical application, I've at least written a servlet filter that will create a wrapper HttpServletRequest using the information passed in headers from trusted proxy servers so my IP addresses and generated URLs and stuff are at least correct I'll have to see how long I can tolerate the proxy+filter mechanism.

blog comments powered by Disqus