parent-kernel.eclass

- Mike Nerone

Introduction

Among the many advantages of using Gentoo Linux is the selection of kernel source packages available. There are gentoo-sources (which includes an extremely useful patchset lovingly maintained by the Gentoo developers), hardened-sources and rsbac-sources (many of the same enhancements, but specifically targeted at tightening security), vanilla-sources (for those who like to run the straight kernel exactly as the Linux kernel developers released it), and a host of other more niche choices (ck-sources, mm-sources, usermod-sources, xen-sources, etc). However, many system adminstrators have a common need not filled by those choices: "I just need patch XYZ for my application!!!"

The usual solution is to install the sources as provided by Gentoo and patch them manually before compiling - but that's not the Gentoo Way. The Gentoo Way is to create your own Portage overlay and write an ebuild to make your own, customized source package that integrates the patches you need. Start with a copy of one of the official ones if you like, and add in your changes. This works fine, but it has some problems:
  1. It's one-shot. If you base your ebuild off of the current version of gentoo-sources, then when a new version stabilizes, you have to remake your ebuild. Maybe it's just a few version numbers that need changing. But maybe not.
  2. It's error-prone. Sure, it's doable, but you'll likely have to go through a mini-development cycle to get it done.
  3. Not everyone feels comfortable diving into the internals of an ebuild.
  4. It's simply too manual. These are computers - can't they do it for us?
The answer to that last question is, of course, yes, and this eclass attempts to address all of these problems. You still make your own ebuild, but it's ridiculously simple (relatively-speaking), it can automatically advance versions with that of the official Gentoo ebuild you base it on if you want it to.

Download

parent-kernel.eclass (Use your browser's Save Link feature to download it).

Installation

Just put it in the eclass directory of your Portage overlay.

A few real-world examples

I want the vanilla-sources, except with support for my Iriver iFP MP3 player:
# /path/to/your/overlay/sys-kernel/vanilla+iriverfs-sources/vanilla+irivers-sources-2.6.x.ebuild

inherit parent-kernel

IRIVERFS_VER="r0.1.0.1"
IRIVERFS_HOMEPAGE='http://www.kign.org/iriver/'

add_kernel_patch                                                            \
    "${IRIVERFS_HOMEPAGE}iriverfs-${IRIVERFS_VER}-linux-${PV}.patch.gz"     \
    "riverfs"                                                               \
    "${IRIVERFS_HOMEPAGE}"
Good ole' gentoo-sources, except I also need the FN key to work in my Powerbook:
# /path/to/your/overlay/sys-kernel/gentoo+fnkey-sources/gentoo+fnkey-sources-2.6.x.ebuild

inherit parent-kernel
add_kernel_patch 'http://seehuhn.de/comp/powerbook/011-fnkey.patch'
Or, here's a nod to the poor souls in bug #76016 - I want hardened-sources with working PPTP (i.e. the MPPE-MPPC patch). Note: I'm told that this patch is now included in kernel 2.6.15, so this will no longer be needed if you're there already, but I'll leave the example for now:
# /path/to/your/overlay/sys-kernel/hardened+mppemppc-sources/hardened+mppemppc-sources-2.6.x.ebuild

inherit parent-kernel

# Add MPPE/MPPC patch
MPPEMPPC_VER="1.3"
MPPEMPPC_KV="${PV}"
MPPEMPPC_HOMEPAGE='http://mppe-mppc.alphacron.de/'
# No new patch for 2.6.14 because the one for 2.6.13 applies cleanly:
[[ ${MPPEMPPC_KV} == "2.6.14" ]] && MPPEMPPC_KV=2.6.13
add_kernel_patch                                                                  \
  "${MPPEMPPC_HOMEPAGE}linux-${MPPEMPPC_KV}-mppe-mppc-${MPPEMPPC_VER}.patch.gz"   \
  "MPPE/MPPC"                                                                     \
  "${MPPEMPPC_HOMEPAGE}"
By the way, it's fine to call add_kernel_patch more than once.

Documentation (also included in the eclass)

This eclass makes it easy to make a custom-patched kernel ebuild that is based on an existing kernel ebuild in the portage tree. It inherits pretty much everything from this parent ebuild (if it exists, that is - otherwise, it does the best it can by simply subclassing kernel-2).

There are two ways to specify the parent ebuild:
  1. The intended way: it is automatically determined from the name of the child ebuild (i.e. your customized one). This is best explained with an example: if you name your customized package "hardened+somename-sources", then this eclass will remove the "+somename" part and automatically use "hardened-sources" as its parent. The "somename" part is completely arbitrary (you can even use multiple +'s and just list all your custom patch names if you don't mind the lengths of the resulting filenames ;D).
  2. You can specify a parent package name in the PARENT_KERNEL_PN environment variable before inheriting this eclass. This is simply a package name (e.g. "gentoo-sources").
The version of the parent package is assumed to be the same as that of the child. It's not possible to override this because there is too much magic in kernel-2.eclass that depends upon it.

By default, the category of the parent package is assumed to be "sys-kernel" and the ebuild is assumed to be in your main portage tree (PORTDIR). You can override those assumptions with PARENT_KERNEL_CATEGORY and PARENT_KERNEL_PORTDIR in the very rare instance that that's necessary. In any case, if the resulting ebuild does not exist, any operations other than an unmerge will fail.

If the parent ebuild needs any files from the parent package's FILESDIR, they must be linked or copied into the child's (and the child ebuild digested afterward). The easiest way to do this is with something like:
# cd /path/to/your/overlay/sys-kernel/<child-package>/files
# for file in `ls /usr/portage/sys-kernel/<parent-package>/files/* | grep -v '\/digest-'`; do ln -s $file; done
# ebuild ../<child-ebuild> digest
Please be aware that using this eclass bypasses checks of all source files (i.e. SRC_URI and FILESDIR files) against the parent's digests. I don't see a way around this (short of ugly kludges), but it is very unlikely to cause a problem because of 1) the QA used by the Gentoo devs to make sure such inconsistencies don't get into the tree/mirrors; and 2) for any such mismatch, the error is very likely to be a non-updated digest, not a bad source file.

This eclass's whole purpose is to provide a single useful function:

add_kernel_patch PATCH_LOCATION [PATCH_NAME [HOMEPAGE]] Example ebuild (yes, it really does something useful with just two commands):inherit parent-kernel
add_kernel_patch                                                        \
'http://www.ultramegakernelpatch.com/ultramegakernelpatch-${PV}.tar.gz' \
'UltraMega'                                                             \
'http://www.ultramegakernelpatch.com/'
Note: you can actually pre-populate future versions/revisions of your ebuild, all identical (dont't create too many, lest it slow down your portage operations too much). Since each inherits everything, including KEYWORDS, from the parent ebuild, each will stabilize automatically when the corresponding parent ebuild does. As long as you utilize ${PV} in the patch location, this should never get you in trouble because the attempt to apply the missing patch (and therefore the whole build) will fail if the patch for a new kernel version is not yet available (or you have not put it in place if you're using a file path). Also note that the build will fail if a patch file is found but fails to apply cleanly (thanks to kernel-2.eclass, inheritance of which is enforced, by the way).