-
Notifications
You must be signed in to change notification settings - Fork 10
CentOS Build Instructions
This page contains information about building various components of the Toolkit in CentOS 6.
The Toolkit includes a custom version of the CentOS 6 RHEL (Red Hat Enterprise Linux) kernel.
To build this kernel, you will need a host with CentOS 6, and the 'rpm-build' package installed (optionally mock) with at least 15 GB of space available.
- Download the most recent kernel Source RPM for CentOS 6
- Navigate to the proper release, i.e. http://vault.centos.org/6.6/updates/Source/SPackages/
- Unpack the kernel source RPM (eg.
rpm -ivh kernel-2.6.32-279.2.1.el6.src.rpm
) by doing:- rpm2cpio kernel-2.6.32-279.2.1.el6.src.rpm | cpio -id
- This will unpack the kernel source RPM into the same directory you are in
- Download web100_changes.patch from https://perfsonar-ps.googlecode.com/git/Toolkit_Building/software/kernel/web100_changes.patch to the same directory where the kernel sources were unpacked.
- Apply the patch with "patch -i web100_changes.patch -p1". This will likely leave a few .rej files around. You will need to edit those files, and manually apply the changes.
- Unpack the kernel source RPM (eg.
- To build the kernel SRPM run:
rpmbuild --define "_sourcedir ." --define "_srcrpmdir ." --nodeps -bs *spec
- If the above commands executed properly you should see a kernel SRPM file
- If not look through the output to determine what went wrong
- To build the kernel run mock (make sure your user is in the "mock" group):
- x86_64: mock -r epel-6-x86_64 --resultdir=$HOME/mock-results/epel-6-x86_64/ --arch=x86_64 --without=debug --without=kabichk kernel_file.src.rpm
- i386: mock -r epel-6-i386 --resultdir=$HOME/mock-results/epel-6-i386 --arch=i386 --target=i686 --without=debug --without=kabichk kernel_file.src.rpm
- You also need to run a third command to build the firmware as noarch:
- mock -r epel-6-i386 --resultdir=$HOME/mock-results/epel-6-i386 --arch=i386 --target=noarch --without=debug --without=kabichk --with=firmware kernel_file.src.rpm
- If new patches have been added, these commands may error out due to patches that don't apply cleanly. If so, these patches will need modified as appropriate and the command rerun (look here)
Every release requires you to rebuild the aufs and sk98lin modules as well as the kernel. The process for both is as follows.
- Download the latest aufs and sk98lin RPMS found in http://software.internet2.edu/web100_kernel/rpms/el6/SRPMS/
- You might need to create the mockbuild user on your system: # useradd -s /sbin/nologin mockbuild
- On you build host install both Source RPMS
rpm -iv aufs-kmod-file.src.rpm
rpm -iv sk98lin-kmod-file.src.rpm
- Update the installed SPEC file (in ~/rpmbuild/SPECS) with the following changes:
- Update the kversion to match the kernel you are building against
- Increase the Release by 1
- Rebuild the source RPM using the new SPEC file, which resides in ~/rpmbuild/SPECS
rpmbuild -bs SPECS/aufs-kmod.spec
rpmbuild -bs SPECS/sk98lin-kmod.spec
- If using mock, copy the kernel rpms to your holding repo (see below) and then start the build. This should complete the build process.
- mock -r epel-6-x86_64 --resultdir=$HOME/mock-results/epel-6-x86_64/ --arch=x86_64 --without=debug --without=kabichk aufs_file.src.rpm
- mock -r epel-6-x86_64 --resultdir=$HOME/mock-results/epel-6-x86_64/ --arch=x86_64 --without=debug --without=kabichk sk98_file.src.rpm
- mock -r epel-6-i386 --resultdir=$HOME/mock-results/epel-6-i386/ --arch=i386 --target=i686 --without=debug aufs_file.src.rpm
- mock -r epel-6-i386 --resultdir=$HOME/mock-results/epel-6-i386/ --arch=i386 --target=i686 --without=debug --without=kabichk sk98_file.src.rpm
In /etc/mock/epel-6-i386.cfg:
holding name=holding baseurl=file:///home/mock/holding/epel-6/i386/
Create a corresponding entry in /etc/mock/epel-6-x86_64.cfg.
The directories /home/mock/holding/[epel-5|epel-6]/[i386|x86_64] are yum repositories created using createrepo. You can copy the kernel RPMs in, and then do this:
createrepo -u /home/mock/holding/epel-6/i386 createrepo -u /home/mock/holding/epel-6/x86_64
For more details about mock, see this page.
When compiling on a remote host, it is common to see an error like this:
Not enough random bytes available. Please do some other work to give
the OS a chance to collect more entropy! (Need 266 more bytes)
There are a number of ways to generate random bytes on a remote machine, but the easiest way that we've found is to perform parallel 'hdparm' tests. The following script can be run one or more times in the event that the error above is seen.
#!/bin/bash
NUM_TESTS=20
if [ -n "$1" ]; then
NUM_TESTS=$1
fi
for i in `seq 1 $NUM_TESTS`; do
/sbin/hdparm -t /dev/sda1 &
done
Unfortunately all of the kernel patches the Toolkit utilizes are intended for the mainstream kernel releases and not the RHEL version that CentOS 6 uses. The RHEL kernel often backports fixes from newer kernel versions essentially creating a hybrid. This presents many issues when applying a patch to the RHEL kernel.
Most patches must first be applied manually (by hand) and then regenerated by running a diff between the vanilla RHEL kernel and the patched one: eg. diff -ur kernel.old/ kernel.new/ > kernel.patch
. In the case of the Toolkit we incorporate two custom patches to the kernel described above: aufs and web100. Likely within the same major kernel version (ie. 2.6.32) the existing patches will apply successfully but when a new kernel is released they may have to be recreated or modified.
Aufs represents a unique problem with using the RHEL kernel. Many of the methods it utilizes are rewritten between the mainstream and the RHEL kernel (the RHEL kernel often includes updates applied to later versions of the mainstream kernel). For this reason, creating a successful and stable aufs patch is quite difficult. To minimize the impacts of patching the kernel there are two patches involved: one patch contains completely necessary and unavoidable patches that must be applied to the kernel, and the other contains patches for the aufs kernel module itself to make it work with the RHEL kernel. Both patches must be created with extreme care as there must be integrity maintained between the kernel, the aufs kernel module, and the aufs user utilites.
To create a new aufs patch will require some understanding of how the kernel operates and experience in programming, as parts of it will likely have to be modified or rewritten by hand. Because we want to use the CentOS RHEL kernel we must use the aufs standalone branch and not the one with full kernel sources. Aufs utilities are also necessary to use aufs but those are a separate package and for the most part can be ignored throughout this process. To patch a new kernel, it is recommended to download several versions of aufs (eg. if your kernel version is 2.6.32 then download aufs intended for mainline kernel versions 2.6.30 through 2.6.36).
Aufs standalone comes with several patches, however the only necessary ones are: aufs2-base.patch
, aufs2-standalone.patch
, and proc_map.patch
. Try patching the CentOS RHEL kernel with these three patches from all the aufs versions you downloaded, each in turn. Determine which group of patches applies the cleanest (has the least errors). Do not delete the extra aufs versions as they may be used later. Start applying the cleanest patches by hand, and if there are issues or references to missing blocks of code consult with the other versions of aufs while taking careful note of what was changed (you may wish to download the full kernel source files from aufs to accomplish this).
After this you are ready to build the kernel using the steps listed above. If the kernel fails to build consult the build logs to find the issue(s).
The final step in this process is making the aufs kernel module. The initial kernel patch may need to be modified to work with aufs and most likely the aufs sources will have to be patched as well. Try building the kernel module against your patched kernel sources and read though the output logs to address any errors. Likely this process will have to be repeated several times until all the issues are resolved. This part is by far the most difficult, so consult the existing aufs patches for older CentOS RHEL kernel versions.
When this is done you should have a working aufs compatible RHEL kernel and the aufs kernel module.
Aufs kernel patches for various kernel versions can be found here.
Fortunately the web100 kernel patch seems to be much a much smoother process as it requires less modification. Manual patching is highly recommended to make sure that things end up where they need to be. Through experience, I have found that lines of code can be inserted where they don't belong which will cause major issues when building and using a kernel. After manual patching is completed simply run a diff between the vanilla kernel and the modified one to produce a patch that will be applied at RPM build time.
Web100 kernel patches for various kernel versions can be found here.
The pS-Performance Toolkit, as the LiveCD, LiveUSB, and NetInstall, are built using custom CentOS kickstart files. You can read more about kickstart installations here. The kickstart file defines the set of software repositories to use, the set of software to install, and a script that performs some system configuration once the software has been installed. Customizing the toolkit will involve changing one or more of those elements in the kickstart files.
The build procedures here assume that the toolkit ISOs are being built on CentOS 6. The steps may work on other systems, but have only been tested on CentOS 6.
For building custom versions of the LiveCD, LiveUSB, or NetInstall, you'll need a copy of ImageMagick installed on the host. This should be available via yum.
For building custom versions of the NetInstall, you will need a copy of mkisofs installed on the host. This should be available via yum.
For building custom versions of the LiveCD and LiveUSB, you will need the livecd-tools package installed on CentOS 6. This should also be available via yum. You can find more installation information here.
You can download the kickstarts, images and scripts needed to build the toolkit by doing a git checkout of http://perfsonar-ps.googlecode.com/git/Toolkit_Building/
There are 6 directories in this git repository. The ones of importance for customization are kickstarts
, images
, and scripts
. The kickstarts
directory contains the files used for generating the kickstarts used by the LiveCD and NetInstall setups. The scripts
directory contains 3 scripts used for building the toolkit, one for the LiveCD, one for the LiveUSB, and one for the NetInstall as well as a script used to deploy the LiveUSB. The images
directory contains the image displayed when the CD is first booted.
If you run the script build_livecd.sh
or build_liveusb.sh
as root, it should download all the necessary RPMs, and build an ISO of the LiveCD/USB and place it in the resources directory. Similarly, if you run the script build_netinstall.sh
as root, it should build an ISO of the NetInstall.
As of the CentOS 6 release, there is an option to specify whether to build a 32-bit or 64-bit version. If the script is executed without any parameters it will automatically build a 32-bit version of the Toolkit, however if you wish to build a 64-bit version you must supply the script with an architecture parameter. For example, to build a 64-bit version of the LiveCD you would run build_livecd.sh --arch x86_64
as root. Note that this requires all Toolkit software to be rebuilt for 64-bit compatibility.
The general build process of the LiveCD/USB proceeds as follows:
- Patches the 'generic' kickstart file (
centos6-base.cfg
) with LiveCD-specific modifications (centos6-livecd/usb.patch
) - Calls livecd-creator to build the LiveCD/USB from the kickstart file
- Modifies the generated LiveCD/USB to use the proper boot image
The general build process of the NetInstall roceeds as follows:
- Patches the 'generic' kickstart file (
centos6-base.cfg
) with NetInstall-specific modifications (centos6-netinstall.patch
) - Modifies the generic CentOS netinstall CD (in the
resources
directory) to include the kickstart and to boot using it - Modifies the generic CentOS netinstall CD to use the proper boot image
To customize the toolkit, you will need to modify the kickstart file. The centos6-base.cfg
file in the kickstarts directory is the 'generic' kickstart file. There are 3 patches: centos6-livecd.patch
, centos6-liveusb.patch
, and centos6-netinstall.patch
, that modify this kickstart file.
There are a large number of directives inside the kickstart. The meaning of most of these is outside the scope of this document, but should be available here.
The set of repositories that will be used to retrieve RPMs from can be customized. This allows you to use a local mirror to speed up builds as well as to include new or customized RPMs. Note, however, that when changing the repositories, you must make sure that the software to be installed (either directly or to satisfy dependencies) must still be available in the set of repositories.
The 'repo' lines specify the set of repositories to use:
repo --name=a-Internet2 --baseurl=http://software.internet2.edu/rpms/i386/main/
The above line tells the kickstart to use the Internet2 repository and gives the URL of the yum repository.
Note: the repositories here are only used for installation. They will not be available after installation. If you want to make these software repositories available after installation, you must either have the kickstart install an appropriate repository package (see here for an example of the repository package), or have the post installation script add the appropriate .repo and key files.
In the %packages
section, there are a list of packages to install or not install. Any packages that start with "@" are package groups (e.g. @core
is the set of core packages). Any packages that start with "-" are packages that should not be installed (e.g. -sysreport
says to not install the sysreport package). All other packages are normal packages to install like you might do with yum.
You can add any packages here that you might want installed.
The toolkit system environment can be configured using the %post script
. This script is run after the software packages have been installed, and allow for modifications to be made to the installed system before it is booted for the first time (or, in the case of the LiveCD/USB, before it is turned into an unmodifiable ISO).
There is an existing %post
script that performs a number of tasks needed by the toolkit. However, this script can be modified to include any desired configuration for the toolkit system. For example, users could be added, or configuration files could be modified. The existing post installation script includes a wide variety of methods for configuring aspects of the installed system.
The thing to remember when making changes is that the patch files expect to patch the centos6-base.cfg
file. There are a few ways to go about making changes. One way is to make changes to the centos6-base.cfg
in such a way that they don't conflict with the patches. This is generally the path of least resistance. Another option, if you only plan on making one of the LiveCD/USBs or NetInstalls, is to patch the centos6-base.cfg
before making your changes, and then edit the build_livecd.sh
, build_liveusb.sh
, or build_netinstall.sh
and set the KICKSTART_PATCH=...
line to be KICKSTART_PATCH=
. This will stop the script from trying to patch the centos6-base.cfg
file. Lastly, you can edit the build_netinstall.sh
, and the regenerate or edit the patch files to account for the changes.
This page contains background information on mock. The latter sections assume basic knowledge of mock and 'holding' repositories, and that the holding repository has been configured as described.
This page contains information on creating and building source RPMs. The latter sections assume basic knowledge of building source RPMs.
To ease the use of mock, we built a simple wrapper script over the mock command which simply sets some default values:
- The uniqueext value will be set to the callers username
- The architecture is set to "i386"
- The default build environment is set to "epel-6" (RedHat6 + the EPEL repositories)
- The output directory is set to /home/username/holding/environment/architecture/name
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
Getopt::Long::Configure("pass_through");
Getopt::Long::Configure("no_ignore_case");
my $uniqueext;
my $resultdir;
my $arch;
my $distro;
my $result = GetOptions("uniqueext=s", \$uniqueext, "resultdir=s", \$resultdir, "arch=s", \$arch, "distro=s", \$distro);
my @remaining_args = @ARGV;
my $srpm = $ARGV[$#ARGV];
unless ($srpm)
{
print "No source RPM specified.\n";
exit(-1);
}
unless (`rpm -qp $srpm 2>/dev/null`)
{
print "Invalid SRPM: $srpm";
exit(-1);
}
my ($name, $pass, $uid, $gid, $quota, $comment, $gcos, $dir, $shell, $expire) = getpwuid($>);
$arch = "i386" unless ($arch);
$distro = "epel-6" unless ($distro);
$uniqueext = $name unless ($uniqueext);
$resultdir = "/home/$name/holding/$distro/$arch/" . `rpm -qp $srpm 2>/dev/null` unless ($resultdir);
chomp($resultdir);
my $mycfg = "$distro-$arch";
$mycfg = "$distro-i386" if ( ! -e "/etc/mock/$mycfg" and $arch eq "i686" and -e "/etc/mock/$distro-i386.cfg");
my @args = ();
push @args, ("/usr/bin/mock");
push @args, ("-r", $mycfg);
push @args, ("--resultdir", $resultdir);
push @args, ("--uniqueext", $uniqueext);
push @args, ("--arch", $arch);
push @args, @remaining_args;
print join(" ", @args) . "\n";
system(@args);
- Build a source RPM of I2utils (e.g. I2util-1.1-1.el6.src.rpm)
- A copy of the source/spec file is available at http://i2util.perfsonar-ps.googlecode.com/git/
- Run:
i2_mock [I2utils SRPM]
(e.g.i2_mock I2util-1.1-1.el6.src.rpm
)
- Build a source RPM of web100_userland (e.g. web100_userland-1.8-1.el6.src.rpm)
- A copy of the source/spec file is available at http://perfsonar-ps.googlecode.com/git/Toolkit_Building/software/web100-userland/
- Run:
i2_mock [web100_userland SRPM]
(e.g.web100_userland-1.8-1.el6.src.rpm
)
- Place a built RPM of I2utils into the 'holding' repository
- Build a source RPM of bwctl (e.g. bwctl-1.4rc1-1.el6.src.rpm)
- A copy of the source/spec file is available at http://anonsvn.internet2.edu/svn/nptoolkit/trunk/software/bwctl/
- Run:
i2_mock [bwctl SRPM]
(e.g.i2_mock bwctl-1.4rc1-1.el6.src.rpm
)
- Place a built RPM of I2utils into the 'holding' repository
- Build a source RPM of owamp (e.g. owamp-3.3rc1-1.el6.src.rpm)
- A copy of the source/spec file is available at http://anonsvn.internet2.edu/svn/nptoolkit/trunk/software/owamp/
- Run:
i2_mock [owamp SRPM]
(e.g.i2_mock owamp-3.3rc1-1.el6.src.rpm
)
- Place a built RPM of I2utils into the 'holding' repository
- Place a built RPM of web100_userland into the 'holding' repository
- Build a source RPM of ndt (e.g. ndt-3.6.4-3.el6.src.rpm)
- A copy of the sources/spec file is available at http://anonsvn.internet2.edu/svn/nptoolkit/trunk/software/ndt/
- Run:
i2_mock [ndt SRPM]
(e.g.ndt-3.6.4-3.el6.src.rpm
)
- Place a built RPM of web100_userland into the 'holding' repository
- Build a source RPM of npad (e.g. npad-1.5.6-2.el6.src.rpm)
- A copy of the sources/spec file is available at http://anonsvn.internet2.edu/svn/nptoolkit/trunk/software/npad/
- Run:
i2_mock [npad SRPM]
(e.g.i2_mock npad-1.5.6-2.el6.src.rpm
)
- Build a source RPM of nuttcp (e.g. nuttcp-6.1.2-1.el6.src.rpm)
- A copy of the sources/spec file is available at http://anonsvn.internet2.edu/svn/nptoolkit/trunk/software/nuttcp/
- Run:
i2_mock [nuttcp SRPM]
(e.g.i2_mock nuttcp-6.1.2-1.el6.src.rpm
)
- Build a source RPM of dbxml (e.g. dbxml-2.5.16-1.el6.src.rpm)
- A copy of the source/spec file is available at http://anonsvn.internet2.edu/svn/nptoolkit/trunk/software/dbxml/
- Run:
i2_mock [dbxml SRPM]
(e.g.i2_mock dbxml-2.5.16-1.el6.src.rpm
)
- Place a built RPM of dbxml into the 'holding' repository
- Build a source RPM of perl-dbxml (e.g. perl-dbxml-2.5.16-1.el6.src.rpm)
- A copy of the source/spec file is available at http://anonsvn.internet2.edu/svn/nptoolkit/trunk/software/dbxml/
- Run:
i2_mock [perl-dbxml SRPM]
(e.g.i2_mock perl-dbxml-2.5.16-1.el6.src.rpm
)
- Build a source RPM of the kernel. This will involve steps described above. (e.g. kernel-2.6.32-279.2.1.el6.aufs.web100.src.rpm)
- Run
i2_mock --arch i686 --without debug --without kabichk [kernel SRPM]
(e.g.i2_mock --arch i686 --without debug --without kabichk kernel-2.6.32-279.2.1.el6.aufs.web100.src.rpm
)- NOTE: make sure you have at least 5 GB of available disk space for building the set of kernels
- Copy the kernel development RPMS (kernel-devel) into the 'holding' repository
- Make note of the kernel version number (e.g. 2.6.32-279.2.1.el6.aufs.web100)
- Build a source RPM of the aufs module (e.g. aufs-kmod-2.2-1.el6.src.rpm)
- A copy of the sources/spec file is available at http://perfsonar-ps.googlecode.com/git/Toolkit_Building/software/aufs/
- Run
i2_mock --arch i686 -D "kversion [kernel version number]" [aufs-kmod SRPM]
(e.g.i2_mock --arch i686 -D "kversion 2.6.32-279.2.1.el6.aufs.web100" aufs-kmod-2.2-1.el6.src.rpm
)
- Copy the aufs-kmod RPMS into the 'holding' repository
- Build a source RPM of the aufs utilities (e.g. aufs-util-2.2-1.el6.src.rpm)
- A copy of the sources/spec file is available at http://perfsonar-ps.googlecode.com/git/Toolkit_Building/software/aufs/
- Run
i2_mock [aufs-util SRPM]
(e.g.i2_mock aufs-util-2.2-1.el6.src.rpm
)
- Copy the kernel development RPMS (kernel-devel) into the 'holding' repository
- Make note of the kernel version number (e.g. 2.6.32-279.2.1.el6.aufs.web100)
- Build a source RPM of the sk98lin module (e.g. sk98lin-kmod-10.92.1.3-1.el6.src.rpm)
- A copy of the sources/spec file is available at http://anonsvn.internet2.edu/svn/nptoolkit/trunk/software/sk98lin/
- Run
i2_mock --arch i686 -D "kversion [kernel version number]" [sk98lin-kmod SRPM]
(e.g.i2_mock --arch i686 -D "kversion 2.6.32-279.2.1.el6.aufs.web100" sk98lin-kmod-10.92.1.3-1.el6.src.rpm
)