Friday, September 25, 2015

illumos pureboot

In my previous article, I discussed an experiment in illumos minimization.

Interestingly, there was a discussion on IRC that wandered off into realms afar, but it got me thinking about making oddball illumos images.

So then I thought - how would you build something that was pure illumos. As in illumos, the whole of illumos, and nothing but illumos.

Somewhat surprisingly, this works. For some definition of works, anyway.

The idea is pretty simple. After building illumos, you end up with the artefacts that are created by the build populating a proto area. This has the same structure as a regular system, so you can find usr/bin/ls under there, for example.

So all I do is create a bootable image that is the proto area from a build.

The script is here.

What does this do?
  • Copies the proto area to a staging area, so it can be manipulated
  • Modifies inittab
  • Sets up grub for boot
  • Copies the kernel state files from the running system (otherwise, they're blank and the kernel is clueless)
  • Creates a block device and builds a ufs file system on it
  • Copies the staging area to it
  • Compresses the block device
  • Copies it back to the platform staging area
  • Creates a bootable iso
There's a bit more detail, but those are the salient points.

My (non-debug) proto area seems to be around 464MB, so a 512MB ramdisk works just fine. You could start deleting (or, indeed, adding) stuff to tune the image you create. The ISO image is 166MB, ready for VirtualBox.

The important thing to realise is that illumos, of itself, does not create a complete operating system. Even core OS functionality requires additional third-party components, which will not be present in the image you create. In particular, libxml2, zlib, and openssl are missing. What this means is that anything depending on these will not function. The list of things that won't work includes SMF, which is an integral part of the normal boot and operations.

So instead of init launching SMF, I have it run a shell instead. (I actually do this via a script rather than directly from init, this allows me to put up a message, and also allows me to run other startup commands if so desired.)

This is what it looks like:

A surprising amount of stuff actually works in this environment. Certainly most of the standard unix commands that I've tried are just fine. Although it has to be appreciated that none of the normal boot processing has been done at this point, so almost nothing has been set up. (And / won't budge from being read-only which is a little confusing.)


Josef "Jeff" Sipek said...

I have two observations:

(1) It looks like your script forces everything to be root:root. I suppose this works since you get a root shell, however other metadata like setuid bit, etc. are lost since they are only expressed in the pkg manifests.

(2) Similarly, the driver_aliases, etc. files are assembled from the package manifests, so you could grep the driver lines out of those. Just taking them from the build system sounds just fine given that this isn't supposed to be a "production" build script.

Regardless, thanks for posting this. This will end up being useful.

Peter Tribble said...

Well yes, it's completely unpackaged, that's partly the point and leads to the two hacks you mention.

I could do the same with Tribblix, properly packaged, and probably will do so at some point, it's not that much harder but does make it more distro-specific.

More generally, it should be easy for someone to use this as a starting point if they wanted to build something a bit more specific. You could even make a fully functional image if you had a populated adjunct to drop into place.

Josef "Jeff" Sipek said...

FWIW, I finally got around to trying out your script. It worked great. Thanks!