#!/bin/bash ############################################################################ # # Copyright (C) 2008-2009 Bart Van Assche # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation, version 2 # of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ############################################################################ ############################################################################ # # The recommended way to use this script is as follows: # - Create an additional user, e.g. builder # - Add a line to the sudoers file that allows that user to invoke yum and # yum-builddep. One way to do that is by invoking the following shell # commands as root: # useradd builder # echo 'builder ALL=(ALL) NOPASSWD: /usr/bin/yum, /usr/bin/yum-builddep' >>/etc/sudoers # visudo -sc # # For more information about building a custom RHEL / CentOS / Scientific Linux # kernel RPM, see also: # * CentOS wiki, "I Need to Build a Custom Kernel" # (http://wiki.centos.org/HowTos/Custom_Kernel). # * Fedora wiki, "Building a custom kernel" # (http://fedoraproject.org/wiki/Building_a_custom_kernel). # ############################################################################ scst_dir="$(dirname "$(dirname "$0")")" if [ ${scst_dir:0:1} != "/" ]; then scst_dir="$PWD/${scst_dir}" fi downloaddir=$HOME/software/downloads rpmbuild_dir=$HOME/rpmbuild if [ "$1" = "" ]; then if echo "$(uname -r)" | grep -q uek; then kernel="kernel-uek-$(uname -r)" else kernel="kernel-$(uname -r)" fi else kernel="$1" fi arch="$(uname -m)" kernel="${kernel%.${arch}}" kernel_src_rpm="${kernel}.src.rpm" kver="${kernel#kernel-}" distro="$(sed -n -e 's/^\(.*\) release .*$/\1/p' /etc/issue)" if [ -n "$2" ]; then releasever="$2" else releasever="$(sed -n -e 's/^.* release \([0-9.]*\).*$/\1/p' /etc/issue)" fi releasevermajor="$(echo $releasever | cut -f1 -d.)" releaseverminor="$(echo $releasever | cut -f2 -d.)" case "$distro" in "CentOS"*) case $releasever in 5.*|6.[01]) srpm_url=("http://vault.centos.org/${releasever}/os/SRPMS" "http://vault.centos.org/${releasever}/updates/SRPMS");; *) srpm_url=("http://vault.centos.org/${releasever}/os/Source/SPackages" "http://vault.centos.org/${releasever}/updates/Source/SPackages");; esac ;; "Red Hat Enterprise Linux"*) srpm_url=("http://ftp.redhat.com/pub/redhat/linux/enterprise/${releasevermajor}Server/en/os/SRPMS") ;; "Oracle Linux Server") srpm_url=("http://public-yum.oracle.com/repo/OracleLinux/OL${releasevermajor}/${releaseverminor}/base/x86_64/getPackageSource" "http://public-yum.oracle.com/repo/OracleLinux/OL${releasevermajor}/latest/x86_64/getPackageSource" "http://public-yum.oracle.com/repo/OracleLinux/OL${releasevermajor}/UEK/latest/x86_64/getPackageSource") ;; "Scientific Linux") if [ "$releasevermajor" = 6 ]; then srpm_url=("http://ftp.scientificlinux.org/linux/scientific/$releasever/SRPMS/vendor") else srpm_url=("http://ftp.scientificlinux.org/linux/scientific/$releasevermajor$releaseverminor/SRPMS/vendor") fi ;; "Fedora") srpm_url="http://ftp.redhat.com/redhat/rhel/rc/7/Server/source/tree/Packages" ;; *) echo "Unknown type of distribution: $distro" exit 1 ;; esac function log { echo printf "$@" echo } function copy_patch { local p="$1" while [ ! -e "$p" ] do local q="$(echo "$p" | sed 's/[.-][a-z0-9]*\.patch$/.patch/')" if [ "$q" = "$p" ]; then break; fi p="$q" done if [ ! -e "$p" ]; then echo "Error: patch $1 not found" echo "Please report this on the scst-devel mailing list" exit 1 fi ln -s "$p" "$2" } function rpmbuild { /usr/bin/rpmbuild \ --define="%_topdir ${rpmbuild_dir}" \ --define="%buildid .scst" \ "$@" } if [ -e ${rpmbuild_dir} ]; then echo "You have to remove the ${rpmbuild_dir} directory before starting $0" exit 1 fi if [ ! -e "${scst_dir}" ]; then echo "Error: directory ${scst_dir} not found. Please modify scst_dir in $0." exit 1 fi log "Installing prerequisites" sudo yum install -y -q asciidoc binutils-devel elfutils-libelf-devel hmaccalc ncurses-devel newt-devel patchutils 'perl(ExtUtils::Embed)' python-devel redhat-rpm-config rpmdevtools rng-tools rpm-build unifdef xmlto yum-utils zlib-devel rc=$?; if [ $rc != 0 ]; then exit $rc; fi log "Creating directory ${rpmbuild_dir}" mkdir -p ${rpmbuild_dir}/{BUILD,RPMS,SOURCES,SPECS,SRPMS} log "Installing, unpacking and preparing kernel source files" mkdir -p ${downloaddir} if [ ! -e ${downloaddir}/${kernel_src_rpm} ]; then cd ${downloaddir} for dir in ${srpm_url[@]} do url="$dir/${kernel_src_rpm}" echo "Trying $url ..." if wget -q "$url"; then break fi done if [ ! -e ${downloaddir}/${kernel_src_rpm} ]; then echo "Downloading kernel source RPM ${kernel_src_rpm} failed." exit 1 fi fi log "Installing kernel build prerequisites" sudo yum-builddep -q -y ${downloaddir}/${kernel_src_rpm} log "Installing kernel sources in ${rpmbuild_dir}" cd ${rpmbuild_dir} rpm --define="%_topdir ${rpmbuild_dir}" -i ${downloaddir}/${kernel_src_rpm} 2>&1 \ | grep -v ' does not exist' cd SPECS { rpmbuild -bp --target=${arch} kernel*.spec rc=$? if [ rc != 0 ]; then exit $rc fi } 2>&1 | tee prep-err.log log "Copying SCST patches to the SOURCES directory" cd ${rpmbuild_dir}/SOURCES copy_patch $scst_dir/scst/kernel/rhel/scst_exec_req_fifo-${kver}.patch scst_exec_req_fifo.patch f="$scst_dir/iscsi-scst/kernel/patches/rhel/put_page_callback-${kver}.patch" if [ -e "$f" ]; then copy_patch "$f" put_page_callback.patch fi log "Adding SCST patches in kernel.spec" if [ ${kver#2.6.18} != $kver ]; then if [ -e ${rpmbuild_dir}/SPECS/kernel-2.6.spec ]; then # RHEL/CentOS/SL 5.6 patch -p1 ${rpmbuild_dir}/SPECS/kernel-2.6.spec <<'EOF' || exit $? diff -u SPECS/kernel-2.6.spec{.orig,} --- SPECS/kernel-2.6.spec.orig +++ SPECS/kernel-2.6.spec @@ -6386,6 +6386,9 @@ # empty final patch file to facilitate testing of kernel patches Patch99999: linux-kernel-test.patch +Patch200: scst_exec_req_fifo.patch +Patch201: put_page_callback.patch + # END OF PATCH DEFINITIONS BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root @@ -12593,6 +12596,10 @@ rm -f kernel-%{kversion}-*-debug.config %endif +%patch200 -p1 +%patch201 -p1 +sed -i.tmp -e 's/^CONFIG_SCSI_QLA_FC=.*/CONFIG_SCSI_QLA_FC=n/' *.config + # now run oldconfig over all the config files for i in *.config do EOF else # RHEL/CentOS/SL 5.7 patch -p1 ${rpmbuild_dir}/SPECS/kernel.spec <<'EOF' || exit $? --- SPECS/kernel.spec.orig +++ SPECS/kernel.spec @@ -425,6 +425,9 @@ Patch2: xen-config-2.6.18-redhat.patch Patch3: xen-2.6.18-redhat.patch +Patch200: scst_exec_req_fifo.patch +Patch201: put_page_callback.patch + # empty final patch file to facilitate testing of kernel patches Patch99999: linux-kernel-test.patch @@ -733,6 +736,10 @@ rm -f kernel-%{version}-*-debug.config %endif +%patch200 -p1 +%patch201 -p1 +sed -i.tmp -e 's/^CONFIG_SCSI_QLA_FC=.*/CONFIG_SCSI_QLA_FC=n/' *.config + # now run oldconfig over all the config files for i in *.config do EOF fi elif [ ${kver#2.6.32-71} != $kver ]; then # RHEL/CentOS/SL 6.0 patch -p1 ${rpmbuild_dir}/SPECS/kernel.spec <<'EOF' || exit $? diff -u SPECS/kernel.spec{.orig,} --- SPECS/kernel.spec.orig +++ SPECS/kernel.spec @@ -601,6 +601,9 @@ Source82: config-s390x-debug Source83: config-s390x-debug-rhel +Patch200: scst_exec_req_fifo.patch +Patch201: put_page_callback.patch + # empty final patch file to facilitate testing of kernel patches Patch999999: linux-kernel-test.patch @@ -891,6 +894,9 @@ # Dynamically generate kernel .config files from config-* files make -f %{SOURCE20} VERSION=%{version} configs +ApplyPatch scst_exec_req_fifo.patch +ApplyPatch put_page_callback.patch + ApplyOptionalPatch linux-kernel-test.patch # Any further pre-build tree manipulations happen here. @@ -917,6 +923,8 @@ for i in *.config do mv $i .config + echo "CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION=y" >> .config + sed -i.tmp -e 's/^CONFIG_SCSI_QLA_FC=.*/CONFIG_SCSI_QLA_FC=n/' .config Arch=`head -1 .config | cut -b 3-` make ARCH=$Arch %{oldconfig_target} > /dev/null echo "# $Arch" > configs/$i EOF elif [ ${kver#2.6.32-131} != $kver -o ${kver#2.6.32-220} != $kver \ -o ${kver#2.6.32-279} != $kver -o ${kver#2.6.32-358} != $kver \ -o ${kver#2.6.32-431} != $kver ]; then # RHEL/CentOS/SL 6.1, 6.2, 6.3, 6.4 or 6.5 patch -p1 ${rpmbuild_dir}/SPECS/kernel.spec <<'EOF' || exit $? # RHEL/CentOS/SL 6.x diff -u SPECS/kernel.spec{.orig,} --- SPECS/kernel.spec.orig +++ SPECS/kernel.spec @@ -601,6 +601,9 @@ Source82: config-generic Source83: config-x86_64-debug-rhel +Patch200: scst_exec_req_fifo.patch +Patch201: put_page_callback.patch + # empty final patch file to facilitate testing of kernel patches Patch999999: linux-kernel-test.patch @@ -891,6 +894,9 @@ # Dynamically generate kernel .config files from config-* files make -f %{SOURCE20} VERSION=%{version} configs +ApplyPatch scst_exec_req_fifo.patch +ApplyPatch put_page_callback.patch + ApplyOptionalPatch linux-kernel-test.patch # Any further pre-build tree manipulations happen here. @@ -917,6 +923,8 @@ for i in *.config do mv $i .config + echo "CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION=y" >> .config + sed -i.tmp -e 's/^CONFIG_SCSI_QLA_FC=.*/CONFIG_SCSI_QLA_FC=n/' .config Arch=`head -1 .config | cut -b 3-` make ARCH=$Arch %{oldconfig_target} > /dev/null echo "# $Arch" > configs/$i EOF elif [ ${kver#3.10.0-121} != $kver ]; then # RHEL/CentOS/SL 7.0 patch -p1 ${rpmbuild_dir}/SPECS/kernel.spec <<'EOF' || exit $? --- kernel.spec.orig 2014-05-23 10:09:17.707202148 +0200 +++ kernel.spec 2014-05-23 10:15:50.883937952 +0200 @@ -4,6 +4,7 @@ Summary: The Linux kernel # % define buildid .local +%define buildid .scst # For a stable, released kernel, released_kernel should be 1. For rawhide # and/or a kernel built from an rc or git snapshot, released_kernel should @@ -367,6 +368,9 @@ Source2000: cpupower.service Source2001: cpupower.config +Patch200: scst_exec_req_fifo.patch +#Patch201: put_page_callback.patch + # empty final patch to facilitate testing of kernel patches Patch999999: linux-kernel-test.patch @@ -668,6 +672,9 @@ # Drop some necessary files from the source dir into the buildroot cp $RPM_SOURCE_DIR/kernel-%{version}-*.config . +ApplyPatch scst_exec_req_fifo.patch +#ApplyPatch put_page_callback.patch + ApplyOptionalPatch linux-kernel-test.patch # Any further pre-build tree manipulations happen here. @@ -700,6 +707,8 @@ for i in *.config do mv $i .config + echo "CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION=y" >> .config + sed -i.tmp -e 's/^CONFIG_SCSI_QLA_FC=.*/CONFIG_SCSI_QLA_FC=n/' .config Arch=`head -1 .config | cut -b 3-` make %{?cross_opts} ARCH=$Arch listnewconfig | grep -E '^CONFIG_' >.newoptions || true %if %{listnewconfig_fail} EOF else log "Unrecognized kernel version ${kver}" fi log "Rebuilding kernel" cd ${rpmbuild_dir}/SPECS { rpmbuild -bb --target=${arch} --nodeps --with baseonly --with firmware --without kabichk kernel*.spec rc=$? if [ $rc != 0 ]; then exit $rc fi } 2>&1 | tee build.log log "Ready. You can now install the freshly built kernel RPM as follows:\nsudo rpm -ivh --force $HOME/rpmbuild/RPMS/${arch}/kernel-*.rpm"