Last week we looked at Ubuntu Server's documentation, discussed hardware requirements, tried to figure out what sets Ubuntu Server apart from Ubuntu Desktop, and what's included in the current release, 7.10 (Gutsy Gibbon). Ubuntu itself is not very helpful with these things, and I don't like to write reviews that complain without also offering some answers, so today we're going to learn how to dig into Ubuntu without installing it and find out these things for ourselves. We still need the installation .iso image, but at least we won't have to install it or even burn it to a CD to learn some useful information.
We're taking such a deep dive into the very bowels of Ubuntu Server that this is expanding into a three-parter, so hold on to your hats and enjoy the ride.
What Is a "Server" Kernel?
We're going to compare the /boot/config-2.6.22-14-server and /boot/config-2.6.22-14-generic files and find out exactly what Ubuntu thinks a server kernel is, and what a desktop kernel is. We'll do this by mounting the installation .iso in a temporary directory, and then extract and compare the two files:
# mkdir temp
# mount -o loop ubuntu-7.10-server-i386.iso
# cd temp
# find temp -name linux-image*
Check it out, we get both desktop and server kernels in one location, so this is going to be easy. We want the last two, as those are the real kernel packages, which the linux-meta packages are not. Copy them into separate directories for unpacking. .deb packages are special archives that contain ordinary tar archives, and these two packages contain files with the same names: control.tar.gz, data.tar.bz2, and debian-binary. So you can't unpack them in the same directory.
Use the ar and tar commands to unpack the .debs, and then to unpack their data.tar.gz files:
# ar -x linux-image-2.6.22-14-server_2.6.22-14.46_i386.deb
# tar jxvf data.tar.bz2
Now you can pluck out the boot/config-2.6.22-14-server and boot/config-2.6.22-14-generic files, copy them into the same directory for convenience, and diff them:
# diff --suppress-common-lines -y config-2.6.22-14-server
This gives us some nice manageable output — around 50 lines, rather than ~3100 lines per file. So let's take a look at diff's output to see what's different.
There are four different types of I/O scheduling: CFQ (Completely Fair Queuing), Deadline, NOOP, and Anticipatory. Ubuntu makes CFQ the default for desktop kernels, and Deadline for server kernels. The goal is the same for all of them: to optimize hard disk bandwidth for different classes of workloads. In your configuration file this is the CONFIG_DEFAULT_IOSCHED option, plus the CONFIG_IOSCHED_CFQ, _DEADLINE, _AS, and _NOOP options.
- CFQ tries to balance all read/write requests equally.
- Deadline gives a higher priority to read requests, and will re-order read/write requests aggressively to meet the goal of completing read requests within a specified time, without "starving" write requests, which are not given deadlines.
- Anticipatory aims to reduce latency by giving priority to already-running applications. It is supposed to be suitable for smaller systems with one or two hard disks, and single or dual-core CPUs.
- NOOP is a minimal scheduler for systems with hardware that handles I/O scheduling, like large SCSI RAID arrays.
The question of which one is appropriate depends on your systems and how you use them: how many CPUs, how many hard disks and controllers, what types of applications, and the loads your systems have to handle. You can run benchmarks, and then tune your systems accordingly. You can pass scheduler options in as boot-time options, or you can even enable different schedulers per block device and change them on-the-fly (see Resources). The Ubuntu defaults are good starting points, and if you need to tweak the settings they're just as tweakable as on any Linux.