11da177e4SLinus Torvalds#! /bin/sh 2*b2441318SGreg Kroah-Hartman# SPDX-License-Identifier: GPL-2.0 31da177e4SLinus Torvalds# Script to apply kernel patches. 41da177e4SLinus Torvalds# usage: patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] 51da177e4SLinus Torvalds# The source directory defaults to /usr/src/linux, and the patch 61da177e4SLinus Torvalds# directory defaults to the current directory. 71da177e4SLinus Torvalds# e.g. 81da177e4SLinus Torvalds# scripts/patch-kernel . .. 91da177e4SLinus Torvalds# Update the kernel tree in the current directory using patches in the 101da177e4SLinus Torvalds# directory above to the latest Linus kernel 111da177e4SLinus Torvalds# scripts/patch-kernel . .. -ac 121da177e4SLinus Torvalds# Get the latest Linux kernel and patch it with the latest ac patch 131da177e4SLinus Torvalds# scripts/patch-kernel . .. 2.4.9 141da177e4SLinus Torvalds# Gets standard kernel 2.4.9 151da177e4SLinus Torvalds# scripts/patch-kernel . .. 2.4.9 -ac 161da177e4SLinus Torvalds# Gets 2.4.9 with latest ac patches 171da177e4SLinus Torvalds# scripts/patch-kernel . .. 2.4.9 -ac11 181da177e4SLinus Torvalds# Gets 2.4.9 with ac patch ac11 191da177e4SLinus Torvalds# Note: It uses the patches relative to the Linus kernels, not the 201da177e4SLinus Torvalds# ac to ac relative patches 211da177e4SLinus Torvalds# 221da177e4SLinus Torvalds# It determines the current kernel version from the top-level Makefile. 231da177e4SLinus Torvalds# It then looks for patches for the next sublevel in the patch directory. 241da177e4SLinus Torvalds# This is applied using "patch -p1 -s" from within the kernel directory. 251da177e4SLinus Torvalds# A check is then made for "*.rej" files to see if the patch was 261da177e4SLinus Torvalds# successful. If it is, then all of the "*.orig" files are removed. 271da177e4SLinus Torvalds# 281da177e4SLinus Torvalds# Nick Holloway <Nick.Holloway@alfie.demon.co.uk>, 2nd January 1995. 291da177e4SLinus Torvalds# 301da177e4SLinus Torvalds# Added support for handling multiple types of compression. What includes 311da177e4SLinus Torvalds# gzip, bzip, bzip2, zip, compress, and plaintext. 321da177e4SLinus Torvalds# 331da177e4SLinus Torvalds# Adam Sulmicki <adam@cfar.umd.edu>, 1st January 1997. 341da177e4SLinus Torvalds# 351da177e4SLinus Torvalds# Added ability to stop at a given version number 361da177e4SLinus Torvalds# Put the full version number (i.e. 2.3.31) as the last parameter 371da177e4SLinus Torvalds# Dave Gilbert <linux@treblig.org>, 11th December 1999. 381da177e4SLinus Torvalds 391da177e4SLinus Torvalds# Fixed previous patch so that if we are already at the correct version 401da177e4SLinus Torvalds# not to patch up. 411da177e4SLinus Torvalds# 421da177e4SLinus Torvalds# Added -ac option, use -ac or -ac9 (say) to stop at a particular version 431da177e4SLinus Torvalds# Dave Gilbert <linux@treblig.org>, 29th September 2001. 441da177e4SLinus Torvalds# 451da177e4SLinus Torvalds# Add support for (use of) EXTRAVERSION (to support 2.6.8.x, e.g.); 461da177e4SLinus Torvalds# update usage message; 471da177e4SLinus Torvalds# fix some whitespace damage; 481da177e4SLinus Torvalds# be smarter about stopping when current version is larger than requested; 49f4b09ebcSAdrian Bunk# Randy Dunlap <rdunlap@xenotime.net>, 2004-AUG-18. 501922163cSRandy.Dunlap# 511922163cSRandy.Dunlap# Add better support for (non-incremental) 2.6.x.y patches; 521922163cSRandy.Dunlap# If an ending version number if not specified, the script automatically 531922163cSRandy.Dunlap# increments the SUBLEVEL (x in 2.6.x.y) until no more patch files are found; 541922163cSRandy.Dunlap# however, EXTRAVERSION (y in 2.6.x.y) is never automatically incremented 551922163cSRandy.Dunlap# but must be specified fully. 561922163cSRandy.Dunlap# 571922163cSRandy.Dunlap# patch-kernel does not normally support reverse patching, but does so when 581922163cSRandy.Dunlap# applying EXTRAVERSION (x.y) patches, so that moving from 2.6.11.y to 2.6.11.z 591922163cSRandy.Dunlap# is easy and handled by the script (reverse 2.6.11.y and apply 2.6.11.z). 60f4b09ebcSAdrian Bunk# Randy Dunlap <rdunlap@xenotime.net>, 2005-APR-08. 611922163cSRandy.Dunlap 621922163cSRandy.DunlapPNAME=patch-kernel 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds# Set directories from arguments, or use defaults. 651da177e4SLinus Torvaldssourcedir=${1-/usr/src/linux} 661da177e4SLinus Torvaldspatchdir=${2-.} 671da177e4SLinus Torvaldsstopvers=${3-default} 681da177e4SLinus Torvalds 6922d6a6a0SAndreas Mohrif [ "$1" = -h -o "$1" = --help -o ! -r "$sourcedir/Makefile" ]; then 701da177e4SLinus Torvaldscat << USAGE 711922163cSRandy.Dunlapusage: $PNAME [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] 721da177e4SLinus Torvalds source directory defaults to /usr/src/linux, 731da177e4SLinus Torvalds patch directory defaults to the current directory, 741da177e4SLinus Torvalds stopversion defaults to <all in patchdir>. 751da177e4SLinus TorvaldsUSAGE 761da177e4SLinus Torvaldsexit 1 771da177e4SLinus Torvaldsfi 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds# See if we have any -ac options 801da177e4SLinus Torvaldsfor PARM in $* 811da177e4SLinus Torvaldsdo 821da177e4SLinus Torvalds case $PARM in 831da177e4SLinus Torvalds -ac*) 841da177e4SLinus Torvalds gotac=$PARM; 851da177e4SLinus Torvalds 861da177e4SLinus Torvalds esac; 871da177e4SLinus Torvaldsdone 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds# --------------------------------------------------------------------------- 901922163cSRandy.Dunlap# arg1 is filename 911922163cSRandy.DunlapnoFile () { 921922163cSRandy.Dunlap echo "cannot find patch file: ${patch}" 931922163cSRandy.Dunlap exit 1 941922163cSRandy.Dunlap} 951922163cSRandy.Dunlap 961922163cSRandy.Dunlap# --------------------------------------------------------------------------- 971922163cSRandy.Dunlapbackwards () { 981922163cSRandy.Dunlap echo "$PNAME does not support reverse patching" 991922163cSRandy.Dunlap exit 1 1001922163cSRandy.Dunlap} 1011922163cSRandy.Dunlap 1021922163cSRandy.Dunlap# --------------------------------------------------------------------------- 1031da177e4SLinus Torvalds# Find a file, first parameter is basename of file 1041da177e4SLinus Torvalds# it tries many compression mechanisms and sets variables to say how to get it 1051da177e4SLinus TorvaldsfindFile () { 1061da177e4SLinus Torvalds filebase=$1; 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds if [ -r ${filebase}.gz ]; then 1091da177e4SLinus Torvalds ext=".gz" 1101da177e4SLinus Torvalds name="gzip" 1111da177e4SLinus Torvalds uncomp="gunzip -dc" 1121da177e4SLinus Torvalds elif [ -r ${filebase}.bz ]; then 1131da177e4SLinus Torvalds ext=".bz" 1141da177e4SLinus Torvalds name="bzip" 1151da177e4SLinus Torvalds uncomp="bunzip -dc" 1161da177e4SLinus Torvalds elif [ -r ${filebase}.bz2 ]; then 1171da177e4SLinus Torvalds ext=".bz2" 1181da177e4SLinus Torvalds name="bzip2" 1191da177e4SLinus Torvalds uncomp="bunzip2 -dc" 120354fa22fSShawn Landden elif [ -r ${filebase}.xz ]; then 121354fa22fSShawn Landden ext=".xz" 122354fa22fSShawn Landden name="xz" 123354fa22fSShawn Landden uncomp="xz -dc" 1241da177e4SLinus Torvalds elif [ -r ${filebase}.zip ]; then 1251da177e4SLinus Torvalds ext=".zip" 1261da177e4SLinus Torvalds name="zip" 1271da177e4SLinus Torvalds uncomp="unzip -d" 1281da177e4SLinus Torvalds elif [ -r ${filebase}.Z ]; then 1291da177e4SLinus Torvalds ext=".Z" 1301da177e4SLinus Torvalds name="uncompress" 1311da177e4SLinus Torvalds uncomp="uncompress -c" 1321da177e4SLinus Torvalds elif [ -r ${filebase} ]; then 1331da177e4SLinus Torvalds ext="" 1341da177e4SLinus Torvalds name="plaintext" 1351da177e4SLinus Torvalds uncomp="cat" 1361da177e4SLinus Torvalds else 1371da177e4SLinus Torvalds return 1; 1381da177e4SLinus Torvalds fi 1391da177e4SLinus Torvalds 1401da177e4SLinus Torvalds return 0; 1411da177e4SLinus Torvalds} 1421da177e4SLinus Torvalds 1431da177e4SLinus Torvalds# --------------------------------------------------------------------------- 1441da177e4SLinus Torvalds# Apply a patch and check it goes in cleanly 1451da177e4SLinus Torvalds# First param is patch name (e.g. patch-2.4.9-ac5) - without path or extension 1461da177e4SLinus Torvalds 1471da177e4SLinus TorvaldsapplyPatch () { 1481da177e4SLinus Torvalds echo -n "Applying $1 (${name})... " 1491da177e4SLinus Torvalds if $uncomp ${patchdir}/$1${ext} | patch -p1 -s -N -E -d $sourcedir 1501da177e4SLinus Torvalds then 1511da177e4SLinus Torvalds echo "done." 1521da177e4SLinus Torvalds else 1531da177e4SLinus Torvalds echo "failed. Clean up yourself." 1541da177e4SLinus Torvalds return 1; 1551da177e4SLinus Torvalds fi 1561da177e4SLinus Torvalds if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] 1571da177e4SLinus Torvalds then 1581da177e4SLinus Torvalds echo "Aborting. Reject files found." 1591da177e4SLinus Torvalds return 1; 1601da177e4SLinus Torvalds fi 1611da177e4SLinus Torvalds # Remove backup files 1621da177e4SLinus Torvalds find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \; 1631da177e4SLinus Torvalds 1641da177e4SLinus Torvalds return 0; 1651da177e4SLinus Torvalds} 1661da177e4SLinus Torvalds 1671922163cSRandy.Dunlap# --------------------------------------------------------------------------- 1681922163cSRandy.Dunlap# arg1 is patch filename 1691922163cSRandy.DunlapreversePatch () { 1701922163cSRandy.Dunlap echo -n "Reversing $1 (${name}) ... " 1711922163cSRandy.Dunlap if $uncomp ${patchdir}/"$1"${ext} | patch -p1 -Rs -N -E -d $sourcedir 1721922163cSRandy.Dunlap then 1731922163cSRandy.Dunlap echo "done." 1741922163cSRandy.Dunlap else 1751922163cSRandy.Dunlap echo "failed. Clean it up." 1761922163cSRandy.Dunlap exit 1 1771922163cSRandy.Dunlap fi 1781922163cSRandy.Dunlap if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] 1791922163cSRandy.Dunlap then 1801922163cSRandy.Dunlap echo "Aborting. Reject files found." 1811922163cSRandy.Dunlap return 1 1821922163cSRandy.Dunlap fi 1831922163cSRandy.Dunlap # Remove backup files 1841922163cSRandy.Dunlap find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \; 1851922163cSRandy.Dunlap 1861922163cSRandy.Dunlap return 0 1871922163cSRandy.Dunlap} 1881922163cSRandy.Dunlap 1891da177e4SLinus Torvalds# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION 19022d6a6a0SAndreas Mohr# force $TMPFILEs below to be in local directory: a slash character prevents 19122d6a6a0SAndreas Mohr# the dot command from using the search path. 19222d6a6a0SAndreas MohrTMPFILE=`mktemp ./.tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; } 1931da177e4SLinus Torvaldsgrep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE 1941da177e4SLinus Torvaldstr -d [:blank:] < $TMPFILE > $TMPFILE.1 19522d6a6a0SAndreas Mohr. $TMPFILE.1 1961da177e4SLinus Torvaldsrm -f $TMPFILE* 1971da177e4SLinus Torvaldsif [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ] 1981da177e4SLinus Torvaldsthen 1991da177e4SLinus Torvalds echo "unable to determine current kernel version" >&2 2001da177e4SLinus Torvalds exit 1 2011da177e4SLinus Torvaldsfi 2021da177e4SLinus Torvalds 2031da177e4SLinus TorvaldsNAME=`grep ^NAME $sourcedir/Makefile` 2041da177e4SLinus TorvaldsNAME=${NAME##*=} 2051da177e4SLinus Torvalds 2061da177e4SLinus Torvaldsecho "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} ($NAME)" 2071da177e4SLinus Torvalds 2081da177e4SLinus Torvalds# strip EXTRAVERSION to just a number (drop leading '.' and trailing additions) 2091da177e4SLinus TorvaldsEXTRAVER= 2101da177e4SLinus Torvaldsif [ x$EXTRAVERSION != "x" ] 2111da177e4SLinus Torvaldsthen 21222d6a6a0SAndreas Mohr EXTRAVER=${EXTRAVERSION#.} 2131da177e4SLinus Torvalds EXTRAVER=${EXTRAVER%%[[:punct:]]*} 2141922163cSRandy.Dunlap #echo "$PNAME: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER" 2151da177e4SLinus Torvaldsfi 2161da177e4SLinus Torvalds 2171da177e4SLinus Torvalds#echo "stopvers=$stopvers" 2181da177e4SLinus Torvaldsif [ $stopvers != "default" ]; then 2191da177e4SLinus Torvalds STOPSUBLEVEL=`echo $stopvers | cut -d. -f3` 2201da177e4SLinus Torvalds STOPEXTRA=`echo $stopvers | cut -d. -f4` 22107584163SErkki Lintunen STOPFULLVERSION=${stopvers%%.$STOPEXTRA} 2221922163cSRandy.Dunlap #echo "#___STOPSUBLEVEL=/$STOPSUBLEVEL/, STOPEXTRA=/$STOPEXTRA/" 2231da177e4SLinus Torvaldselse 2241da177e4SLinus Torvalds STOPSUBLEVEL=9999 2251da177e4SLinus Torvalds STOPEXTRA=9999 2261da177e4SLinus Torvaldsfi 2271da177e4SLinus Torvalds 2281922163cSRandy.Dunlap# This all assumes a 2.6.x[.y] kernel tree. 2291922163cSRandy.Dunlap# Don't allow backwards/reverse patching. 2301922163cSRandy.Dunlapif [ $STOPSUBLEVEL -lt $SUBLEVEL ]; then 2311922163cSRandy.Dunlap backwards 2321922163cSRandy.Dunlapfi 2331922163cSRandy.Dunlap 2341da177e4SLinus Torvaldsif [ x$EXTRAVER != "x" ]; then 2351da177e4SLinus Torvalds CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER" 2361da177e4SLinus Torvaldselse 2371da177e4SLinus Torvalds CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" 2381da177e4SLinus Torvaldsfi 2391da177e4SLinus Torvalds 2401922163cSRandy.Dunlapif [ x$EXTRAVER != "x" ]; then 2411922163cSRandy.Dunlap echo "backing up to: $VERSION.$PATCHLEVEL.$SUBLEVEL" 2421922163cSRandy.Dunlap patch="patch-${CURRENTFULLVERSION}" 2431922163cSRandy.Dunlap findFile $patchdir/${patch} || noFile ${patch} 2441922163cSRandy.Dunlap reversePatch ${patch} || exit 1 2451922163cSRandy.Dunlapfi 2461922163cSRandy.Dunlap 2471922163cSRandy.Dunlap# now current is 2.6.x, with no EXTRA applied, 2481922163cSRandy.Dunlap# so update to target SUBLEVEL (2.6.SUBLEVEL) 2491922163cSRandy.Dunlap# and then to target EXTRAVER (2.6.SUB.EXTRAVER) if requested. 2501922163cSRandy.Dunlap# If not ending sublevel is specified, it is incremented until 2511922163cSRandy.Dunlap# no further sublevels are found. 2521922163cSRandy.Dunlap 2531922163cSRandy.Dunlapif [ $STOPSUBLEVEL -gt $SUBLEVEL ]; then 2541922163cSRandy.Dunlapwhile : # incrementing SUBLEVEL (s in v.p.s) 2551922163cSRandy.Dunlapdo 2561922163cSRandy.Dunlap CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" 2571922163cSRandy.Dunlap EXTRAVER= 258177525d2SAndreas Mohr if [ x$STOPFULLVERSION = x$CURRENTFULLVERSION ]; then 2591da177e4SLinus Torvalds echo "Stopping at $CURRENTFULLVERSION base as requested." 2601da177e4SLinus Torvalds break 2611da177e4SLinus Torvalds fi 2621da177e4SLinus Torvalds 26322d6a6a0SAndreas Mohr SUBLEVEL=$(($SUBLEVEL + 1)) 2641da177e4SLinus Torvalds FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" 2651922163cSRandy.Dunlap #echo "#___ trying $FULLVERSION ___" 2661da177e4SLinus Torvalds 26722d6a6a0SAndreas Mohr if [ $(($SUBLEVEL)) -gt $(($STOPSUBLEVEL)) ]; then 2681da177e4SLinus Torvalds echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)" 2691da177e4SLinus Torvalds exit 1 2701da177e4SLinus Torvalds fi 2711da177e4SLinus Torvalds 2721da177e4SLinus Torvalds patch=patch-$FULLVERSION 2731da177e4SLinus Torvalds # See if the file exists and find extension 2741922163cSRandy.Dunlap findFile $patchdir/${patch} || noFile ${patch} 2751da177e4SLinus Torvalds 2761da177e4SLinus Torvalds # Apply the patch and check all is OK 2771da177e4SLinus Torvalds applyPatch $patch || break 2781da177e4SLinus Torvaldsdone 2791922163cSRandy.Dunlap#echo "#___sublevel all done" 2801922163cSRandy.Dunlapfi 2811922163cSRandy.Dunlap 2821922163cSRandy.Dunlap# There is no incremental searching for extraversion... 2831922163cSRandy.Dunlapif [ "$STOPEXTRA" != "" ]; then 2841922163cSRandy.Dunlapwhile : # just to allow break 2851922163cSRandy.Dunlapdo 2861922163cSRandy.Dunlap# apply STOPEXTRA directly (not incrementally) (x in v.p.s.x) 2871922163cSRandy.Dunlap FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$STOPEXTRA" 2881922163cSRandy.Dunlap #echo "#... trying $FULLVERSION ..." 2891922163cSRandy.Dunlap patch=patch-$FULLVERSION 2901922163cSRandy.Dunlap 2911922163cSRandy.Dunlap # See if the file exists and find extension 2921922163cSRandy.Dunlap findFile $patchdir/${patch} || noFile ${patch} 2931922163cSRandy.Dunlap 2941922163cSRandy.Dunlap # Apply the patch and check all is OK 2951922163cSRandy.Dunlap applyPatch $patch || break 2961922163cSRandy.Dunlap #echo "#___extraver all done" 2971922163cSRandy.Dunlap break 2981922163cSRandy.Dunlapdone 2991922163cSRandy.Dunlapfi 3001da177e4SLinus Torvalds 3011da177e4SLinus Torvaldsif [ x$gotac != x ]; then 3021da177e4SLinus Torvalds # Out great user wants the -ac patches 3031da177e4SLinus Torvalds # They could have done -ac (get latest) or -acxx where xx=version they want 30422d6a6a0SAndreas Mohr if [ $gotac = "-ac" ]; then 3051da177e4SLinus Torvalds # They want the latest version 3061da177e4SLinus Torvalds HIGHESTPATCH=0 3071da177e4SLinus Torvalds for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.* 3081da177e4SLinus Torvalds do 3091da177e4SLinus Torvalds ACVALUE=`echo $PATCHNAMES | sed -e 's/^.*patch-[0-9.]*-ac\([0-9]*\).*/\1/'` 3101da177e4SLinus Torvalds # Check it is actually a recognised patch type 3111da177e4SLinus Torvalds findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${ACVALUE} || break 3121da177e4SLinus Torvalds 3131da177e4SLinus Torvalds if [ $ACVALUE -gt $HIGHESTPATCH ]; then 3141da177e4SLinus Torvalds HIGHESTPATCH=$ACVALUE 3151da177e4SLinus Torvalds fi 3161da177e4SLinus Torvalds done 3171da177e4SLinus Torvalds 3181da177e4SLinus Torvalds if [ $HIGHESTPATCH -ne 0 ]; then 3191da177e4SLinus Torvalds findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} || break 3201da177e4SLinus Torvalds applyPatch patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} 3211da177e4SLinus Torvalds else 3221da177e4SLinus Torvalds echo "No -ac patches found" 3231da177e4SLinus Torvalds fi 3241da177e4SLinus Torvalds else 3251da177e4SLinus Torvalds # They want an exact version 3261da177e4SLinus Torvalds findFile $patchdir/patch-${CURRENTFULLVERSION}${gotac} || { 3271da177e4SLinus Torvalds echo "Sorry, I couldn't find the $gotac patch for $CURRENTFULLVERSION. Hohum." 3281da177e4SLinus Torvalds exit 1 3291da177e4SLinus Torvalds } 3301da177e4SLinus Torvalds applyPatch patch-${CURRENTFULLVERSION}${gotac} 3311da177e4SLinus Torvalds fi 3321da177e4SLinus Torvaldsfi 333