patch-kernel 7.43 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2
#! /bin/sh
# Script to apply kernel patches.
Linus Torvalds's avatar
Linus Torvalds committed
3
#   usage: patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
Linus Torvalds's avatar
Linus Torvalds committed
4 5
#     The source directory defaults to /usr/src/linux, and the patch
#     directory defaults to the current directory.
Linus Torvalds's avatar
Linus Torvalds committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19
# e.g.
#   scripts/patch-kernel . ..
#      Update the kernel tree in the current directory using patches in the
#      directory above to the latest Linus kernel
#   scripts/patch-kernel . .. -ac
#      Get the latest Linux kernel and patch it with the latest ac patch
#   scripts/patch-kernel . .. 2.4.9
#      Gets standard kernel 2.4.9
#   scripts/patch-kernel . .. 2.4.9 -ac
#      Gets 2.4.9 with latest ac patches
#   scripts/patch-kernel . .. 2.4.9 -ac11
#      Gets 2.4.9 with ac patch ac11
#   Note: It uses the patches relative to the Linus kernels, not the
#   ac to ac relative patches
Linus Torvalds's avatar
Linus Torvalds committed
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
#
# It determines the current kernel version from the top-level Makefile.
# It then looks for patches for the next sublevel in the patch directory.
# This is applied using "patch -p1 -s" from within the kernel directory.
# A check is then made for "*.rej" files to see if the patch was
# successful.  If it is, then all of the "*.orig" files are removed.
#
#       Nick Holloway <Nick.Holloway@alfie.demon.co.uk>, 2nd January 1995.
#
# Added support for handling multiple types of compression. What includes
# gzip, bzip, bzip2, zip, compress, and plaintext. 
#
#       Adam Sulmicki <adam@cfar.umd.edu>, 1st January 1997.
#
# Added ability to stop at a given version number
# Put the full version number (i.e. 2.3.31) as the last parameter
#       Dave Gilbert <linux@treblig.org>, 11th December 1999.

Linus Torvalds's avatar
Linus Torvalds committed
38 39 40 41 42
# Fixed previous patch so that if we are already at the correct version
# not to patch up.
#
# Added -ac option, use -ac or -ac9 (say) to stop at a particular version
#       Dave Gilbert <linux@treblig.org>, 29th September 2001.
43 44 45 46 47 48
#
# Add support for (use of) EXTRAVERSION (to support 2.6.8.x, e.g.);
# update usage message;
# fix some whitespace damage;
# be smarter about stopping when current version is larger than requested;
#	Randy Dunlap <rddunlap@osdl.org>, 2004-AUG-18.
Linus Torvalds's avatar
Linus Torvalds committed
49

Linus Torvalds's avatar
Linus Torvalds committed
50 51 52
# Set directories from arguments, or use defaults.
sourcedir=${1-/usr/src/linux}
patchdir=${2-.}
53
stopvers=${3-default}
Linus Torvalds's avatar
Linus Torvalds committed
54

55
if [ "$1" == -h -o "$1" == --help -o ! -r "$sourcedir/Makefile" ]; then
56 57
cat << USAGE
usage: patch-kernel [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ]
58 59 60
  source directory defaults to /usr/src/linux,
  patch directory defaults to the current directory,
  stopversion defaults to <all in patchdir>.
61 62 63 64
USAGE
exit 1
fi

Linus Torvalds's avatar
Linus Torvalds committed
65 66 67 68 69 70 71 72 73 74 75 76 77
# See if we have any -ac options
for PARM in $*
do
  case $PARM in
	  -ac*)
		  gotac=$PARM;

	esac;
done

# ---------------------------------------------------------------------------
# Find a file, first parameter is basename of file
# it tries many compression mechanisms and sets variables to say how to get it
78
findFile () {
Linus Torvalds's avatar
Linus Torvalds committed
79 80 81 82 83 84 85 86
  filebase=$1;

  if [ -r ${filebase}.gz ]; then
		ext=".gz"
		name="gzip"
		uncomp="gunzip -dc"
  elif [ -r ${filebase}.bz  ]; then
		ext=".bz"
87
		name="bzip"
Linus Torvalds's avatar
Linus Torvalds committed
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
		uncomp="bunzip -dc"
  elif [ -r ${filebase}.bz2 ]; then
		ext=".bz2"
		name="bzip2"
		uncomp="bunzip2 -dc"
  elif [ -r ${filebase}.zip ]; then
		ext=".zip"
		name="zip"
		uncomp="unzip -d"
  elif [ -r ${filebase}.Z ]; then
		ext=".Z"
		name="uncompress"
		uncomp="uncompress -c"
  elif [ -r ${filebase} ]; then
		ext=""
		name="plaintext"
		uncomp="cat"
  else
106 107
	return 1;
  fi
Linus Torvalds's avatar
Linus Torvalds committed
108 109 110 111 112 113 114 115

  return 0;
}

# ---------------------------------------------------------------------------
# Apply a patch and check it goes in cleanly
# First param is patch name (e.g. patch-2.4.9-ac5) - without path or extension

116
applyPatch () {
Linus Torvalds's avatar
Linus Torvalds committed
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
  echo -n "Applying $1 (${name})... "
  if $uncomp ${patchdir}/$1${ext} | patch -p1 -s -N -E -d $sourcedir
  then
    echo "done."
  else
    echo "failed.  Clean up yourself."
    return 1;
  fi
  if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ]
  then
    echo "Aborting.  Reject files found."
    return 1;
  fi
  # Remove backup files
  find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \;
 
  return 0;
}

136 137 138 139 140 141
# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
TMPFILE=`mktemp .tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; }
grep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE
tr -d [:blank:] < $TMPFILE > $TMPFILE.1
source $TMPFILE.1
rm -f $TMPFILE*
Linus Torvalds's avatar
Linus Torvalds committed
142 143 144 145 146 147
if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
then
    echo "unable to determine current kernel version" >&2
    exit 1
fi

148 149
NAME=`grep ^NAME $sourcedir/Makefile`
NAME=${NAME##*=}
Linus Torvalds's avatar
Linus Torvalds committed
150

151 152 153 154
echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} ($NAME)"

# strip EXTRAVERSION to just a number (drop leading '.' and trailing additions)
EXTRAVER=
Linus Torvalds's avatar
Linus Torvalds committed
155 156
if [ x$EXTRAVERSION != "x" ]
then
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
	if [ ${EXTRAVERSION:0:1} == "." ]; then
		EXTRAVER=${EXTRAVERSION:1}
	else
		EXTRAVER=$EXTRAVERSION
	fi
	EXTRAVER=${EXTRAVER%%[[:punct:]]*}
	#echo "patch-kernel: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER"
fi

#echo "stopvers=$stopvers"
if [ $stopvers != "default" ]; then
	STOPSUBLEVEL=`echo $stopvers | cut -d. -f3`
	STOPEXTRA=`echo $stopvers | cut -d. -f4`
	#echo "STOPSUBLEVEL=$STOPSUBLEVEL, STOPEXTRA=$STOPEXTRA"
else
	STOPSUBLEVEL=9999
	STOPEXTRA=9999
Linus Torvalds's avatar
Linus Torvalds committed
174
fi
Linus Torvalds's avatar
Linus Torvalds committed
175

176
while :				# incrementing SUBLEVEL (s in v.p.s)
Linus Torvalds's avatar
Linus Torvalds committed
177
do
178 179 180 181 182 183 184 185
    if [ x$EXTRAVER != "x" ]; then
	CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER"
    else
	CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
    fi

    if [ $stopvers == $CURRENTFULLVERSION ]; then
        echo "Stopping at $CURRENTFULLVERSION base as requested."
Linus Torvalds's avatar
Linus Torvalds committed
186 187 188
        break
    fi

189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
    while :			# incrementing EXTRAVER (x in v.p.s.x)
    do
	EXTRAVER=$((EXTRAVER + 1))
	FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER"
	#echo "... trying $FULLVERSION ..."

	patch=patch-$FULLVERSION

	# See if the file exists and find extension
	findFile $patchdir/${patch} || break

	# Apply the patch and check all is OK
	applyPatch $patch || break

	continue 2
    done

    EXTRAVER=
    SUBLEVEL=$((SUBLEVEL + 1))
Linus Torvalds's avatar
Linus Torvalds committed
208
    FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
209 210 211 212 213 214
    #echo "___ trying $FULLVERSION ___"

    if [ $((SUBLEVEL)) -gt $((STOPSUBLEVEL)) ]; then
	echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)"
	exit 1
    fi
Linus Torvalds's avatar
Linus Torvalds committed
215 216 217

    patch=patch-$FULLVERSION

218 219
    # See if the file exists and find extension
    findFile $patchdir/${patch} || break
Linus Torvalds's avatar
Linus Torvalds committed
220

Linus Torvalds's avatar
Linus Torvalds committed
221 222
    # Apply the patch and check all is OK
    applyPatch $patch || break
Linus Torvalds's avatar
Linus Torvalds committed
223
done
224
#echo "base all done"
Linus Torvalds's avatar
Linus Torvalds committed
225 226 227 228

if [ x$gotac != x ]; then
  # Out great user wants the -ac patches
	# They could have done -ac (get latest) or -acxx where xx=version they want
229
	if [ $gotac == "-ac" ]; then
Linus Torvalds's avatar
Linus Torvalds committed
230 231 232 233 234 235 236 237
	  # They want the latest version
		HIGHESTPATCH=0
		for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.*
		do
			ACVALUE=`echo $PATCHNAMES | sed -e 's/^.*patch-[0-9.]*-ac\([0-9]*\).*/\1/'`
			# Check it is actually a recognised patch type
			findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${ACVALUE} || break

238
		  if [ $ACVALUE -gt $HIGHESTPATCH ]; then
Linus Torvalds's avatar
Linus Torvalds committed
239 240 241 242
			  HIGHESTPATCH=$ACVALUE
		  fi
		done

243
		if [ $HIGHESTPATCH -ne 0 ]; then
Linus Torvalds's avatar
Linus Torvalds committed
244 245 246
			findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} || break
			applyPatch patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH}
		else
247
		  echo "No -ac patches found"
Linus Torvalds's avatar
Linus Torvalds committed
248 249 250 251 252 253 254 255 256 257
		fi
	else
	  # They want an exact version
		findFile $patchdir/patch-${CURRENTFULLVERSION}${gotac} || {
		  echo "Sorry, I couldn't find the $gotac patch for $CURRENTFULLVERSION.  Hohum."
			exit 1
		}
		applyPatch patch-${CURRENTFULLVERSION}${gotac}
	fi
fi