Tips & Tricks for small setups

Swap space

It's often the case with small setups that you either have relatively small amount of RAM, and/or you don't have the swap space at all.

I think it's obvious that if you can't possibly increase the amount of physical memory installed in machine, you should set up enough swap space for system to flush rarely used pages from RAM to disk. If this process becomes too excessive, the system performance is greatly degraded, but sometimes it's better than not running at all...

If you don't have any swap space at all, see the section on sysctl's below for other tips.

As for the amount of swap space: people have varying opinions on this matter, but for heavily loaded machine with insufficient RAM the swap space should be at least twice the size of physical memory.


Kzip'ped kernels and MFS

Kzip(8)

As you probably know, there is a program called kzip(8) which can significantly reduce kernel size by applying to it an LZW compression method. Such kernel is combined with special stubs, which are called right after loading the kernel image. Their purpose is to uncompress the rest of the data and to pass control there.

However, there are unpleasant side-effects of this: such prepared kernel is stripped of symbols, and consequently every program which uses them stops working. This includes all programs which make use of libkvm (such as ps, netstat, vmstat, systat etc).

As a side note: even when you can use libkvm procedures, in case of space shortage you wouldn't want it, because these procedures require relatively big (ca. 350kB) database to be built and stored in /var/db/kvm_kernel.db.

So it would be great if there were any means of getting this info some other way. Some of it (like the data that 'ps' needs) can be partially obtained from /proc (see 'aps' in PicoBSD for example how to do this). Some others can be extracted via sysctl mechanism. Some of them are still unavailable when running kernel without symbols...


MFS - inside the kernel and outside of the kernel.

(under construction)

For now let it simply suffice that FreeBSD offers something what other OSes call "ramdisk", i.e. using part of available memory as disk space. Currently such ramdisk uses all semantics (and complication) of FFS, and MFS can only be of FFS type. Such filesystem can also be put inside the kernel, if it was compiled with enough space left inside ('options"MFS_ROOT=nnn"'), presumably in order to start system binaries from it (e.g. init(8)). The process of patching involves some dirty hacks you wouldn't like to know, but it works...


Crunched binaries.

crunchgen(1) is a very useful, small program, which can combine several programs into one statically linked binary, thus saving considerable amount of disk space.

After producing the one huge binary, you must hardlink it to every name of the program it contains. Otherwise it wouldn't know what part of itself to execute.

For detailed description see the manpage. Here are only the most frequent caveats:

You can sometimes be tempted to gzip the resulting binary, and on the first look it greatly reduces its size - by 1.5 to 2. But there's a price to be paid for this: when you execute it, the whole binary must first be unpacked to memory and then the relevant part will be run. Thus, you need much more memory to start it, and you always have to load the whole binary into memory. In case of executing ungzipped crunch, the system loads only these parts of the file which will be soon executed (this read-ahead behaviour is tunable to some extent via sysctl's).


DEVFS/SLICE code (3.0 only)

(Well, not exactly 3.0-only, but to make it usable under 2.2.x requires significant amount of work to be done...)

I won't attempt to fully describe here the whole concept of DEVFS, but in simple words it means that you don't have to manually create the nodes in /dev hierarchy in order to make use of specific devices - the kernel probes all compiled-in devices at startup, and creates all necessary nodes by itself, including device nodes needed to access specific slices and partitions (based on the disklabel which it reads).

What are the consequences for small setups? You can remove all nodes below the /dev (you have to leave the /dev itself, though), compile the kernel with "options DEVFS" and "options SLICE", and it should work ok.

Then, you can save some space reducing the number of inodes on the filesystem, and thus gain significant amount of space.

Be warned, though: DEVFS is still somewhat fragile... :-)


Biosboot, dosboot, rawboot, kzipboot.

(under construction)

(Look in /usr/src/sys/i386/boot, and read the READMEs there...)


Tuning parameters with sysctl.

The sysctl interface in FreeBSD is often an unnoticed or underestimated feature by many users. It is a powerful, but poorly documented way to tune various aspects of a running system.

And even if you know it and use it, you are perhaps unaware that some of very interesting data doesn't have it's own specific display handlers in /sbin/sysctl, and thus remains unnoticed. You can see it for yourself:

	sysctl -a|awk '{print $1}'>a
	sysctl -A|awk '{print $1}'>A
	diff a A|more

It's relatively easy to write your own code which makes use of these data. PicoBSD contains a small utility called 'vm' which does exactly this... See its sources for an example how it could be done. It's even now quite possible to write small and simple replacements for vmstat, netstat etc. which don't use libkvm and can be used with kzip'ped kernels...


Useful sysctl's: