Localpatch (Tutorial)

From Funtoo
This is the approved revision of this page, as well as being the most recent.
Jump to: navigation, search


[edit] 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.

[edit] 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- kernel.

[edit] How it works

Important: localpatch feature removed form recent portage, available in foobashrc.
# emerge foobashrc

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
                [[ -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} ..." \
                        return 0
        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):


[edit] 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- (-p0+) ...                                             [ ok ]
 * Applying 1001_linux- (-p0+) ...                                             [ ok ]
 * Applying 1002_linux- (-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.

[edit] References

localpatch feature announcement on the funtoo forum