Reblog: Building a new home NAS/home server, Part I

This is a reblog of my “building a home NAS server” series on my old blog. The server still exists, still works but I’m about to embark on an overhaul so I wanted to consolidate all the articles on the same blog.

Up to now I’ve mostly been using recycled workstations as my home mail, SVN and storage server. Nothing really wrong with that as most workstations are fast enough but I’m running into disk space issues again after I started backing up all the important machines onto my server. That’s especially annoying as I started using Time Machine on my iMac and now haven’t got enough space left on the server to also back up the MacBook. Time Machine is great as a backup solution simply because it is so unobtrusive and it appears to just work.

Inspired by an article in the German magazine c’t, I decided that instead of finding another used desktop machine to recycle, I was going to build a proper home server with a few additional bells and whistles. I’m still using mostly desktop parts as I can’t really justify the expense and noise of “proper” server components but I tried to select decent quality parts. Here’s the hardware list:

1 x Antec NSK 6580B Black Mid Tower Case – With 430W Earthwatts PSU
1 x ASROCK A780LM AMD 760G Socket AM2+ VGA DVI 6 Channel Audio Mini-ATX Motherboard
1 x AMD Athlon X2 5050e Socket AM2 45W Energy Efficient Retail Boxed Processor
4 x Samsung EcoGreen F2 1TB Hard Drive SATAII 32MB Cache – OEM
4 x Startech Serial ATA Cable (1 End Right Angled) 18″
1 x Crucial 2GB kit (2x1GB) DDR2 800MHz/PC2-6400 Ballistix Memory Non-ECC Unbuffered CL4 Lifetime Warranty
1 x Startech Right Angle Serial ATA Cable (1 end) 24 Inch

This little lot cost me around £450 including shipping so it’s a relatively inexpensive machine and will hopefully be more powerful than you average, similarly priced NAS. It should also be reasonably quiet and energy efficient, at least for something that’s got a regular processor and five HDDs in it.

First impressions of the Antec case are good. I like buying Antec cases because they’re usually pretty high quality and this one certain doesn’t disappoint. The nice touches like the disk mounting trays with gel feet are great, there is enough space in there – well, more than enough for my uses – and it’s got an 80plus PSU.

disk-carrier-2 disk-carrier-1

The only downside I noticed when opening the case was that the 120mm chassis fan plugs into a HDD power supply and has a ‘speed switch’. Not that impressive but if the rest of the machine turns out to work well I’ll probably replace it with a high-throughput fan that is hooked up to the chassis fan connector. I also like the removable disk carrier that leaves enough space between the disks for some decent airflow. If I had some front mount fans that is.

disk-carrier-3

I’ll skip the buildup stuff. It’s not that hard anyway, plus there are plenty of howtos on the web already. Everything went together very smoothly. I noticed that there is a well designed space for two front-mounted fans right in front of the HDD bays. Given the number of HDDs I’m running in this box, I’ll put a couple more fans on the shopping list (edit: which I never did and it didn’t seem to have any detrimental effects on the longevity of the disks). As you can see, the case is nice and spacious (it was a relief working in there instead of the Mini-ATX cases I tend to prefer for desktops) and yes, I know that it needs a visit from the cable tie fairy. In addition to the components above, I used a fifth HDD for the OS alone, plus on the heap of bits that no self-respecting geek can be without, I found a DVD drive so I didn’t have to hook up the external USB DVD drive that I keep for such cases.

case-sideview

My first choice of OS for this box was OpenSolaris 2009.06. An older version had achieved very good performance scores in the above mentioned article so I thought it was worth a try. I also hoped to be able to try zfs on the ‘data’ disks. While setting up the machine with OpenSolaris was fine, I ran into the problem that I do require a lot more features than “just” a plain NAS – which was the reason to build the server myself in the first place. In addition to playing file and DHCP server, this machine would need to handle all incoming mail (that’ll be postfix, amavisd-new and policyd-weight then), run an IMAP server (dovecot), an NNTP server (leafnode) and a bunch of other small tools that are necessary but unfortunately not available as packages on OpenSolaris yet. While I wouldn’t mind building all these packages from source, keeping them up to date might turn into a problem as I don’t want to have to manually maintain these packages. While the list of packages seems to be fairly small, with the number of dependencies that amavisd and especially SpamAssassin have, this would be almost impossible for someone like me who doesn’t have a lot of time to spend on server maintenance.

For this reason I went with plan B, which was to keep the OS I’m currently using on my server (FreeBSD). FreeBSD has support for zfs – albeit still labelled as experimental so I’m not sure if it’s a good idea, but I’ll try it anyway – and I can set up a FreeBSD box almost in my sleep. Plus, with cron jobs updating the local ports collection it should be fairly straightforward to keep everything up to date. One change I will be making though is to switch from the regular x86 version of the OS to the 64 bit version. Partially because I can but mostly because zfs does seem to be working better on 64 bit systems. Oh, and I’m beginning to wonder if using only 2GB of RAM was a smart idea as zfs does appear to like loadsamemory. I guess we’ll find out in part II…

The joy of using outdated C++ compiler versions

Thud, thud, thud…

The sound of the developer’s head banging on the desk late at night.

What happened? Well, I had a requirement to make use of some smart pointers to handle a somewhat complicated resource management issue that was mostly being ignored in the current implementation, mainly on the grounds of it being slightly to complicated to handle successfully using manual pointer management. The result – not entirely unexpected – was a not so nice memory leak.

No smart pointer implementation was found lurking behind the sofa, so I bravely went where other people had gone before (and failed) – I bravely ignored the status of the Sun CC support in the boost library and downloaded the latest version (1.32.0 at the time of me orginially writing this). The compiler I’m using is marked as ‘horribly broken’ in the context of boost, but hey, I only wanted to use smart pointers so it can’t be that bad, right?

First attempts with a newer compiler (WS8/5.5) proved to be encouraging. The smart_ptr tests compiled, but a lot of them failed. After an extended printf debugging session it appears that the temporaries generated by the compiler got destroyed rather later than both the writers of the C++ standard and the boost developers expected. Employing some advanced google skillz soon brought to light that by default, the SUN compiler destroys temporaries not at the end of the statement as the standard suggests but rather when it encounters the end of the scope.

Great. In fact this shouldn’t have come as that much of a surprise as SUN makes a big song and dance about the compiler’s backward compatility – they state that code which has compiled on previous versions of the compiler will definitely still compile on the newer versions. This I found true almost all the time. Unfortunately in this particular case the feature turned into a stumbling block as the backward-compatible behaviour pretty much sabotaged the expected behaviour.

Fortunately the cure is at hand – the compiler supports a command line option (-feature=tmplife) that makes it behave like every other modern C++ compiler on the face of the earth. And hey presto, the tests suddenly pass. Well, obviously those that are supposed to pass!

Unfortunately the current compiler used in the production environment is 5.3/WS6.2, not 5.5/WS8. At least it also does support the tmplife feature, so I’m obviously only a stone’s throw away from getting working smart pointers, right?

Wrong. The smart pointer’d code did compile, but did it link? Of course not, that would be too easy. So back to the tests, but this time armed with the old compiler. The older SUN compilers use a template instantiation database (the infamous SunWS_cache direcotry) to store the object code resulting of the compiler instantiating templates. For some reason, the compiler or linker fail to pull in the necessary object code for the smart pointer externals and all that. Grrr. Closer inspection of the compiler’s man page suggested that the compiler can be convinced to put this information into the object file instead (using -instances=static instead of the default behaviour). This behaviour is the default on the 5.5 compiler, but optional in the 5.3 compiler…

So finally, the smart_ptr test successfully complete using the Sun 5.3 C++ compiler. And the application – with a bit more tweaking – is leaking considerably less memory. The joy of small victories.

Playing with SunStudio 11

This is by no means a review of SunStudio 11, even though I’ve used it for production software. There’s an awful lot of power in the IDE but I’m one of those old-skool guys who’s spent a lot of time learning and customising XEmacs and it’s still the editor I’m most comfortable with, so why change? For that reason, I’ve only ever used the IDE for debugging, for which it seems to be decent enough. As it’s written in Java as so many IDEs are these days (cue Eclipse) it’s not exactly the fastest IDE I’ve ever worked with but once it’s loaded up and running it appears to be decent enough.

The compiler is however a big step forward from just about any of the older SUN compilers I’ve used. It still has some quirks but there is comparative small number of them, so for most applications it now really looks like a proper standard C++ compiler, which is a big improvement over the previous efforts. Yes, there are still some quirks (a couple of them still show up in Boost) but it’s more unlikely that you stumble across those.

Overall I’d say that whichever compiler version you’re currently using, you should probably upgrade to this one. At least if you’re interested in writing reasonably modern C++, that is.