Localpatch (Tutorial)
Contents |
Introduction
Localpatch (known in gentoo as epatch_user) is a feature that lets you, the user, add patches to official ebuilds without having to maintain the ebuild in question in a local overlay, thus avoiding the maintenance overhead associated with keeping your local overlay in sync with revision and version bumps.
Ebuilds can use this feature by calling epatch_user in their src_prepare () function (preferrably after their own patching).
For future reference, I'm going to document here how I used epatch_user to add a patch to sys-kernel/gentoo-sources.
Motivation
I use the Open Source AMD/ATi Radeon KMS drivers with my funtoo boxes and was seeing random kernel OOPSes with Xorg and 3D applications (the flurry 3D screensaver and games mainly).
I asked in #radeon on the FreeNode IRC network and Dave Airlie was kind enough to link me to a commit that was merged in linux-3.0. However, as I am using 2.6.39-r3 w/aufs2 (which was not available for 3.0 at the time of this writing), I decided to apply the patch myself.
UPDATE: The patch has landed upstream in the vanilla linux-2.6.39.4 kernel.
How it works
Reviewing the /usr/portdir/sys-kernel/gentoo-sources ebuilds reveals that they inherit the kernel-2.eclass. Looking at /usr/portage/eclass/kernel-2.eclass, I noticed that it included a reference to epatch_user in the function kernel-2_src_unpack().
/usr/portage/eclass # grep epatch_user * revealed that the epatch_user bash function is currently defined as follows in /usr/portage/eclass/eutils.eclass:
epatch_user() {
[[ $# -ne 0 ]] && die "epatch_user takes no options"
# don't clobber any EPATCH vars that the parent might want
local EPATCH_SOURCE check base=${PORTAGE_CONFIGROOT%/}/etc/portage/patches
for check in {${CATEGORY}/${PF},${CATEGORY}/${P},${CATEGORY}/${PN}}; do
EPATCH_SOURCE=${base}/${CTARGET}/${check}
[[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check}
[[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check}
if [[ -d ${EPATCH_SOURCE} ]] ; then
EPATCH_SOURCE=${EPATCH_SOURCE} \
EPATCH_SUFFIX="patch" \
EPATCH_FORCE="yes" \
EPATCH_MULTI_MSG="Applying user patches from ${EPATCH_SOURCE} ..." \
epatch
return 0
fi
done
return 1
}
From the Gentoo Development Guide we can deduce that the following paths are valid (using sys-kernel/gentoo-sources-2.6.39-r3 as an example):
/etc/portage/patches/sys-kernel/gentoo-sources-2.6.39-r3 # ${CATEGORY}/${PF}
/etc/portage/patches/sys-kernel/gentoo-sources-2.6.39 # ${CATEGORY}/${P}
/etc/portage/patches/sys-kernel/gentoo-sources # ${CATEGORY}/${PN}
For my particular use case, I added the radeon kms patch titled drm/radeon: fix oops in ttm reserve when pageflipping (v2):
/etc/portage/sys-kernel/gentoo-sources-2.6.39-r3/linux-2.6.git-498c555f56a02ec1059bc150cde84411ba0ac010.patch
Testing it
Let's test that it works as expected:
# cd /usr/portage/sys-kernel/gentoo-sources/ # ebuild gentoo-sources-2.6.39-r3.ebuild clean # ebuild gentoo-sources-2.6.39-r3.ebuild prepare * linux-2.6.39.tar.bz2 RMD160 SHA1 SHA256 size ;-) ... [ ok ] * genpatches-2.6.39-5.base.tar.bz2 RMD160 SHA1 SHA256 size ;-) ... [ ok ] * genpatches-2.6.39-5.extras.tar.bz2 RMD160 SHA1 SHA256 size ;-) ... [ ok ] * checking ebuild checksums ;-) ... [ ok ] * checking auxfile checksums ;-) ... [ ok ] * checking miscfile checksums ;-) ... [ ok ] * checking linux-2.6.39.tar.bz2 ;-) ... [ ok ] * checking genpatches-2.6.39-5.base.tar.bz2 ;-) ... [ ok ] * checking genpatches-2.6.39-5.extras.tar.bz2 ;-) ... [ ok ] * Package: sys-kernel/gentoo-sources-2.6.39-r3 * Repository: gentoo * Maintainer: kernel@gentoo.org * USE: amd64 elibc_glibc kernel_linux multilib userland_GNU * FEATURES: fakeroot installsources preserve-libs sandbox splitdebug userpriv usersandbox >>> Preparing to unpack ... >>> Unpacking source... >>> Unpacking linux-2.6.39.tar.bz2 to /home/portage/tmp/portage/sys-kernel/gentoo-sources-2.6.39-r3/work >>> Unpacking genpatches-2.6.39-5.base.tar.bz2 to /home/portage/tmp/portage/sys-kernel/gentoo-sources-2.6.39-r3/work/patches >>> Unpacking genpatches-2.6.39-5.extras.tar.bz2 to /home/portage/tmp/portage/sys-kernel/gentoo-sources-2.6.39-r3/work/patches * Applying 1000_linux-2.6.39.1.patch (-p0+) ... [ ok ] * Applying 1001_linux-2.6.39.2.patch (-p0+) ... [ ok ] * Applying 1002_linux-2.6.39.3.patch (-p0+) ... [ ok ] * Applying 2900_disable-wunused-but-set-var-gcc-4-6-0.patch (-p0+) ... [ ok ] * Applying 2910_gnu-make-3.80-compat-fix.patch (-p0+) ... [ ok ] * Applying 4200_fbcondecor-0.9.6.patch (-p0+) ... [ ok ] * Applying user patches from /etc/portage/patches/sys-kernel/gentoo-sources-2.6.39-r3 ... * linux-2.6.git-498c555f56a02ec1059bc150cde84411ba0ac010.patch ... [ ok ] * Done with patching >>> Source unpacked in /home/portage/tmp/portage/sys-kernel/gentoo-sources-2.6.39-r3/work >>> Preparing source in /home/portage/tmp/portage/sys-kernel/gentoo-sources-2.6.39-r3/work/linux-2.6.39-gentoo-r3 ... >>> Source prepared. #
Et voilà -- a cleanly patched kernel.