Why kernel packaging is so bad in Debian and Ubuntu
I've written before about Ubuntu's substandard kernel update management; what I didn't say then (partly because I didn't fully understand it) is that this is just a manifestation of a general problem with kernel packaging in Ubuntu (and Debian, which it inherits from).
The fundamental problem for packaging kernels on Debian and Ubuntu is
that there are two unfortunate design choices in
dpkg, the Debian
package system: you can only every have one version of a package
installed at once, and there is no support for 'multi-arch' packages.
That you can only install a single version of a package at once means that if you want to have multiple kernels installed at once, they must have different package names, not just be different versions of the same package; hence the Debian and Ubuntu necessity of having the kernel version embedded in the package name. This then creates the temptation to do 'minor' kernel updates without changing the package name, and in turn this creates the situation where such a 'minor' change can introduce a bug but leave you with no easy way to reboot to the old kernel.
That packages cannot be multi-arch precludes having kernel packages
with the same name but that are for different sub-architectures, so
Debian and Ubuntu have to put the sub-architecture into the package
name (creating '
linux-image-<blah>-i386' package names and so
on). This means that it is impossible to have a generic package
name that winds up installing the right kernel-related bit under all
circumstances; you cannot have, say, a
linux-headers package that
installs the correct set of headers for whatever kernel variant you
are actually running. Instead you need a different generic package for each kernel sub-architecture variant, and
then users have to keep it all straight.
(With multi-arch, a generic
linux-headers package would depend on
linux-headers-<kver>, there would be various sub-architecture versions
of the latter package, and the package system would sort out which
sub-architecture was the right one. Without multi-arch (or conditional
dependencies), this can't work.)