Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Automating kernel update process (script)
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
crys0000
n00b
n00b


Joined: 11 Jan 2006
Posts: 44
Location: Todi, Italy

PostPosted: Tue Feb 28, 2006 7:06 pm    Post subject: Automating kernel update process (script) Reply with quote

I have written a bash script that aims to automate the kernel update process, which is usually made up of several steps:

1) emerge gentoo-sources
2) run make menuconfig or copy the .config file from an older kernel
3) compile the kernel and its modules
4) copy the kernel image to the boot directory
5) optionally copy the .config file to the boot directory
6) update the grub.conf file
7) emerge packages that need to be installed on every kernel recompilation (eg. drivers)


Well, this is more or less what my script does... It's only version 0.1, but it works fine to me.

Before you can run the script, you need to:

1) have kernel sources installed
2) have a .config file either in your kernel source directory or in /boot

Finally, you have to be root in order to run the script.


You can customize the script behaviour by editing the SOURCE_DIR and the EMERGE variables. SOURCE_DIR must contain the path to the directory that contains all kernel sources and it is set by default to /usr/src. EMERGE contains the names of the packages you need to re-emerge everytime you update or recompile your kernel; the names must be separated by spaces.


Here is the script:

Code:
#! /bin/bash
# kernel-update.sh  version 0.1
# Copyright (c)2006 Cristiano Chiucchiolo <cristiano.chiucchiolo@gmail.com>
# This program is licensed under the terms of the GPL version 2.

# This script compiles the kernel version you choose, installs the kernel's
# modules, copies the kernel image to, updates the grub configuration file
# and automatically re-emerges the packets that need to be installed
# after every kernel recompilation (eg. drivers).

# Edit the following two lines according to your system specs and needs.
SOURCE_DIR="/usr/src" # Usually "/usr/src"
EMERGE="" # In the form "nvidia-glx nvidia-kernel qc-usb"
# Edit the line above and type the names of all the packages you need to re-emerge
# everytime you recompile your kernel, separated by spaces.

SD=$SOURCE_DIR
NOT_FOUND_ERR=1
NON_ROOT_ERR=2
ARCH=$(uname -m)
PORTAGE="/usr/portage"
export `cat /etc/make.conf | grep PORTDIR_OVERLAY`
TEST1=$(echo $PORTDIR_OVERLAY | grep \")
TEST2=$(echo $PORTDIR_OVERLAY | grep \')

kernel_compile() {
cd ${SD}/linux-${KV}
if [ -e .config ]
then
   echo
   echo "Compiling the kernel, this can take some minutes..."
   echo
   make && make modules_install
else
   echo
   echo 'Config file not found.'
   echo
   if [ -e /boot/.config ]
   then
      until [ "$ansk" = "y" -o "$ansk" = "n" ]
      do
         echo
         echo -en 'Do you want to use the .config file in /boot? (y/n) '
         read ansk
         echo
      done
      if [ "$ansk" = "y" ]
      then
         cp /boot/.config ${SD}/linux-${KV}
         kernel-compile
      else
         echo
         echo 'Run "make menuconfig" in /usr/src/linux before running this script.'
         echo
         exit $NOT_FOUND_ERR
      fi
   else
      echo 'Run "make menuconfig" in /usr/src/linux before running this script.'
      echo
      exit $NOT_FOUND_ERR
   fi
fi
}

kernel_install() {
cd /boot
if [ -e kernel-* ]
then
   until [ "$ans" = "y" -o "$ans" = "n" ]
   do
      echo
      echo 'There are already one or more kernel images in /boot.'
      echo -en 'Do you want to delete them? (y/n) '
      read ans
      echo
   done
   if [ "$ans" = "y" ]
   then
      rm kernel-*
      echo
      echo 'All kernel images in /boot have been deleted.'
      echo
   fi
fi
cp ${SD}/linux/arch/${ARCH}/boot/bzImage /boot/kernel-${ARCH}-${KV}
echo
echo 'The new kernel image has been copied to /boot.'
echo
cd /boot/grub
sed s/boot[[:graph:]]*/"boot\/kernel-${ARCH}-${KV}"/ grub.conf > grub1.conf
mv grub1.conf grub.conf
echo
echo 'grub.conf has been updated'
echo

until [ "$ansconf" = "y" -o "$ansconf" = "n" ]
do
   echo
   echo -en "Do you want to copy the new kernel config file to /boot? (y/n) "
   read ansconf
   echo
done
if [ "$ansconf" = "y" ]
then
   if [ -e /boot/.config ]
   then
      until [ "$ansovw" = "y" -o "$ansovw" = "n" ]
      do
         echo
         echo "There is already a kernel config file in /boot."
         echo -en "Do you want to overwrite it? (y/n) "
         read ansovw
         echo
      done
      if [ "$ansovw" = "y" ]
      then
         rm /boot/.config
         echo
         echo "The old config file has been deleted."
         echo
         cp ${SD}/linux-${KV}/.config /boot
         echo
         echo "The new kernel config file has been copied succesfully."
         echo
      else
         echo
         echo "Copy aborted."
         echo
      fi
   else
      cp ${SD}/linux-${KV}/.config /boot
      echo
      echo "The new kernel config file has been copied succesfully."
   fi
fi
}

echo_emerge() {
echo
echo "${packet} is not a valid portage package."
echo
echo "Check the name and type again the full list of the packages to emerge."
echo "Eg. nvidia-glx qc-usb"
echo
echo "If you don't want to emerge anything, just press Enter."
read EMERGE
echo
emerge_loop
}

choose_packs() {
echo
echo 'Type the names of the packages you need to re-emerge.'
echo 'Eg.. nvidia-glx qc-usb'
echo
echo "If you don't want to emerge anything, just press Enter."
read EMERGE
echo
}

emerge_loop() {
if [ -n "${EMERGE}" ]
then
   if [ -n "${PORTDIR_OVERLAY}" ]
   then
      for packet in $EMERGE
      do
         until [ -z "${EMERGE}" -o -d "${PORTAGE}"/*/"${packet}" -o \
         -d "${PORTDIR_OVERLAY}"/*/"${packet}" ]
         do
            echo_emerge
         done
      done
   else
      for pacchetto in $EMERGE
      do
         until [ -z "${EMERGE}" -o -d "${PORTAGE}"/*/"${packet}" ]
         do
            echo_emerge
         done
      done
   fi
fi   
}

if [ "${UID}" != 0 ]
then
   echo
   echo 'This script must be run as root.'
   echo
   exit $NON_ROOT_ERR
fi

if [ -n "$TEST1" -o -n "$TEST2" ]
then
   LENGHT=$(expr length ${PORTDIR_OVERLAY})
   NLENGHT=$(($LENGHT-2))
   PORTDIR=$(expr substr ${PORTDIR_OVERLAY} 2 ${NLENGHT})
   PORTDIR_OVERLAY=$PORTDIR
fi

echo
echo "Type the path of the directory where all kernel sources are."
echo
echo "Otherwise, the default setting will be used."
echo -en "[${SD}] "
read src
echo
if [ -n "${src}" ]
then
   SD=$src
fi
cd $SD 2>/dev/null
while [ -z "${SD}" -o "${PWD}" != "${SD}" ]
do
   echo
   echo "Type the path of the directory where all kernel sources are."
   echo -en '(usually /usr/src) '
   read SD
   echo
   cd $SD 2>/dev/null
   if [ "${PWD}" != "${SD}" ]
   then
      echo "The specified directory doesn't exist."
      echo
   fi
done

while [ -z "${KV}" -o "${PWD}" != "${SD}"/linux-"${KV}" ]
do
   echo 'Type the version of the kernel you want to install.'
   echo -en '(eg. "2.6.15-gentoo-r5") '
   read KV
   echo
   cd ${SD}/linux-${KV} 2>/dev/null
   if [ "${PWD}" != "${SD}"/linux-"${KV}" ]
   then
      echo
      echo "The specified version is incorrect, or the kernel sources"
      echo "haven't been installed."
      echo
   fi
done

if [ -z "${EMERGE}" ]
then
   choose_packs
else
   until [ "$ansem" = "y" -o "$ansem" = "n" ]
   do
      echo
      echo "Do you want to emerge the packages set by default?"
      echo -en "[${EMERGE}] (y/n) "
      read ansem
      echo
   done
   if [ "$ansem" = "n" ]
   then
      choose_packs
   fi
fi
emerge_loop

cd ${SD}
if [ -h linux ]
then
   cd linux 2>/dev/null
   if [ "$PWD" != "${SD}"/linux-"${KV}" ]
   then
      echo
      echo "The symlink ${SD}/linux doesn't point to the kernel version"
      echo "you want to install."
      echo
      cd ${SD}
      rm linux
      ln -s linux-${KV} linux
      cd linux
      echo
      echo "The symlink has been corrected."
      echo
   fi
   kernel_compile
   kernel_install
else
   ln -s linux-${KV} linux
   cd linux
   kernel_compile
   kernel_install
fi

if [ -n "${EMERGE}" ]
then
   echo
   echo "Now I will emerge the specified packages..."
   echo
   echo
   emerge ${EMERGE}
fi

echo
echo "The kernel update has been completed succesfully."
echo
echo

exit 0



Please try it, report any bugs you find and suggest any features you'd like to have in the next versions.
I hope you'll find it useful!!! :D

8)
Back to top
View user's profile Send private message
drwook
Veteran
Veteran


Joined: 30 Mar 2005
Posts: 1322
Location: London

PostPosted: Tue Feb 28, 2006 9:54 pm    Post subject: Reply with quote

Ouch, this script has just given me a few grey hairs....

Don't mean to discourage you, but please think about the following

1/ with 1 application of 'just say yes', someone can delete all of their working kernels from /boot. Are you sure you want this to be possible?
2/ There's no 'make oldconfig' or equivalent step in case of changes to kconfig between versions. (perhaps if you really want no interactivity 'make defconfig' and some sed/grep use?)
3/ What arch is this aimed at? I think most (I rarely play with hardware that isn't x86, x86_64 or ppc) if not all arches now have the install make target, so perhaps using this would have saved you some time and room for error (such as your script leaving lilo, syslinux or other more exotic bootloader people with an unbootable machine after saying yes to deleting old kernels)
4/ no checking that major/minor versions are the same (I wouldn't blindly use any .config with another kernel, but going from e.g. 2.4.x to 2.6.x is likely suicidal with no way of checking and no safeguard)
5/ Still need to mount /boot manually anyway... perhaps 'mount /boot' & 'umount /boot' at either end of the kernel installation?
6/ Only thing that should require root is the kernel installation - shouldn't be a big deal, but there was a problem with /dev/null being trashed when building as root with one of the git versions a week or two back. gcc's fault not the kernels, but still ;)
7/ Prompting for kernel version requested seems redundant and likely to cause issues, as re-emerging out of tree modules will build them against whatever the /usr/src/linux symlink points to.

[edit] 8/ You might consider taking a look at sys-kernel/module-rebuild to determine what needs rebuilding to avoid expecting everyone to know ;) [/edit]
Back to top
View user's profile Send private message
Zarhan
l33t
l33t


Joined: 27 Feb 2004
Posts: 921

PostPosted: Tue Feb 28, 2006 10:00 pm    Post subject: Re: Automating kernel update process (script) Reply with quote

crys0000 wrote:

3) compile the kernel and its modules
4) copy the kernel image to the boot directory
5) optionally copy the .config file to the boot directory
6) update the grub.conf file


You are aware that these steps can be done with
Code:
make all modules_install install
- altough, it does not update grub.conf, instead it updates a symlink called vmlinuz.
Back to top
View user's profile Send private message
drwook
Veteran
Veteran


Joined: 30 Mar 2005
Posts: 1322
Location: London

PostPosted: Tue Feb 28, 2006 10:07 pm    Post subject: Reply with quote

Code:
cp /usr/src/<previous kernel>/.config /usr/src/linux/ && make oldconfig && make all modules_install && mount /boot && make install && umount /boot && emerge -1 <out of tree modules>
for example? possibly using sudo for the mount / make (modules_)install / unmount to allow building as non-root.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum