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