Rebuilding the DICE kernel
This page is intended to document the entire process for rebuilding kernels on SL6 and SL7. It is rare to need to rebuild a kernel these days, most likely it will be to apply a security patch.
There are some useful guides on the Centos wiki:
Your Build Environment
You will need to build the packages locally, doing this over AFS will take a very long time and might well thrash the fileserver. Here's how I configure my rpmbuild environment.
My
~/.rpmmacros
file contains:
%_topdir /afs/inf.ed.ac.uk/user/s/squinney/rpmbuild
and the
~/rpmbuild
location is a symlink to
/disk/scratch/squinney/rpmbuild
The build process can take a stupidly long time so if you are in a hurry you should consider asking RAT kindly if you can use a machine with a large number of processors. You will then need to tweak the parallelisation level for make like this:
%_smp_mflags -j32
Where the 32 should be replaced with the largest number you can get away with. This can shave hours off the build time so it's well worthwhile.
On the build machine you will need to create the link and the various sub-directories for the rpmbuild tree:
mkdir -p /disk/scratch/$USER/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
ln -s /disk/scratch/$USER/rpmbuild ~/rpmbuild
Obviously, this requires that the kernel builds are done on a machine with scratch disk space. Your desktop will have this but so will the various build hosts (e.g.
buildsl7). It's definitely slower on a build host because they are virtual machines but that can still be preferable to having your desktop chugging away for ages if you want to get on with other things.
If you already have the rpmbuild tree configured the way you want then I suggest it is cleaned out before you start the build. The kernel SRPMs contain a
LOT of stuff and it is definitely easier to deal with the various files if you have cleaned out the tree first. This will do the trick:
rm -rf ~/rpmbuild/*/*
Building the Kernel Packages
The process for all platforms boils down to something along these lines:
- Fetch and install the required kernel SRPM
- Install build-dependencies
- Apply patches
- Edit the specfile.
- Build
- Submit
- Build any other kernel module packages we need (e.g. openafs)
- Test
The modifications for the specfiles are similar on all platforms. The
%changelog
section should also be modified to include a statement of what you have done to the kernel.
Fetching the source
The easiest way to fetch the source for a kernel is to use the
yumdownloader
tool:
yumdownloader --source kernel
If you need a specific version then that can be made explicit, e.g.
kernel-3.10.0-229.11.1.el7
The SRPM file will be downloaded into the current directory and can be then be installed using
rpm -i
as usual.
Build-dependencies
The simplest and easiest way to install any additional build-dependency packages required for the kernel is to use yum as root:
yum-builddep kernel
This does, of course, mean that they will be removed at the next run of updaterpms.
Creating a patch
If you do not already have a patch to apply then it will have to be created by editing the relevant source files and using diff.
First unpack the package:
rpmbuild -bp rpmbuild/SPECS/kernel.spec
Note that it is
-bp
for
prepare, and
not -ba
for
build all.
Next go into the BUILD directory for the kernel and create a copy of the original against which you can later run diff:
cd rpmbuild/BUILD/kernel-3.10.0-229.20.1.el7/
cp -r linux-3.10.0-229.20.1.el7.x86_64{,.orig}
When editting the files please try to stick to the standard whitespace rules for the kernel source, if in doubt copy from the surrounding lines.
Once the source files are editted ensure you delete any editor backup files which have been created (e.g.
*~
for emacs) so they do not appear in the diff.
To generate a patch do this:
diff -ruNp linux-3.10.0-229.20.1.el7.x86_64{.orig,} > ~/rpmbuild/SOURCES/linux-join_session_keyring.patch
The
-p
flag is useful as it will show which C function each change is in.
Ensure the patch file is well-named so the purpose is obvious.
It is important that the diff is created at the correct directory level since patches are always applied with
-p1
in the specfile.
Specfile changes
Here is a rough outline of the changes which must be made to the specfile.
This block should go at the top of the specfile. It should go after the comment block which demonstrates how to spin your own kernel.
%define DICE 1
%if %{DICE}
%define buildid .inf
%endif
You will need to add the patch(es) above to the list of patches, please put a explanatory comment before each patch. Adding just before the "empty final patch file" is probably the best place, eg.
%if %{DICE}
# Informatics patch for CVE-2016-0728
Patch1: linux-join_session_keyring.patch
%endif
Be careful, there should be
exactly one single space between the colon character and the start of the patch file name.
You will then need to add
ApplyPatch rules. Again, best add this just before the call to
ApplyOptionalPath linux-kernel-test.patch. eg.
%if %{DICE}
ApplyPatch linux-join_session_keyring.patch
%endif
ApplyOptionalPath linux-kernel-test.patch
The final thing to do is to add the changelog entry:
%changelog
* Wed Jan 20 2016 Stephen Quinney <squinney@inf.ed.ac.uk>
- Fixed CVE-2016-0728
Package Building
Once this has all been done the next step is to build the kernel packages:
rpmbuild -ba ~/rpmbuild/SPECS/kernel.spec
Once the main packages are done you will want to also build the documentation and firmware packages. On both architectures this is done by setting the target to
noarch
rpmbuild -ba --target noarch ~/rpmbuild/SPECS/kernel.spec
Once that is complete you can use pkgsubmit to submit all the generated kernel packages which are in the RPMS directory.
--
StephenQuinney - 22 Jan 2016
--
AlastairScobie - 26 Aug 2011