Sunday, May 30, 2010

My /boot kernel management (2)

In the last post I described my /boot kernel scheme and eselect-based management tool. Another piece of that is the script to actually install a new kernel to that fancy structure.

Here it is:


#!/bin/sh

#
# "make install" script for i386 architecture
#
# Arguments:
# $1 - kernel version
# $2 - kernel image file
# $3 - kernel map file
# $4 - default install path (blank if root directory)
#

KERNEL_VERSION="$1"
KERNEL_IMAGE="$2"
KERNEL_MAP="$3"
BASE_INSTALL_PATH="$4"
KERNEL_BASE="$BASE_INSTALL_PATH/installkernel"

die () {
ERR="$1"
shift

if [ -z "$1" ]
then
echo Aborting 1>&2
else
echo $* 1>&2
fi

exit $ERR
}


verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
die 1
fi
}

# Make sure the files actually exist
verify "$KERNEL_IMAGE"
verify "$KERNEL_MAP"

# check if the version already exists in /boot and find the appropriate p-level
KERNEL_BASE_DIR="$KERNEL_BASE/$KERNEL_VERSION"
KERNEL_PLEVEL="0"

while [ -e "$KERNEL_BASE_DIR/p$KERNEL_PLEVEL" ]
do
KERNEL_PLEVEL="$(expr $KERNEL_PLEVEL + 1)"
done

INSTALL_PATH="$KERNEL_BASE_DIR/p$KERNEL_PLEVEL"

# backup old modules if needed
#TODO warn before overwriting existing backup?
#TODO check if the previous plevel is identical?

if [ $KERNEL_PLEVEL != 0 ]
then
OLD_PLEVEL="$(expr $KERNEL_PLEVEL - 1)"
MODULES_BACKUP_FILE="/lib/modules/$KERNEL_VERSION-p$OLD_PLEVEL.tgz"
echo "Creating modules backup for previous kernel: $MODULES_BACKUP_FILE"
tar czf "$MODULES_BACKUP_FILE" -C /lib/modules $KERNEL_VERSION || die 4
fi


# make the new kernel dir
echo "Creating new kernel dir: $INSTALL_PATH"
mkdir -p $INSTALL_PATH || die 2

# copy the file to the new kernel dir
echo "Copying kernel files"
cp "$KERNEL_IMAGE" $INSTALL_PATH/ || die 3
cp "$KERNEL_MAP" $INSTALL_PATH/ || die 3
cp .config $INSTALL_PATH/ || die 3

#TODO run eselect and make modules_install?
echo ""
echo "Done. You should probably do the following now:"
echo "1. eselect the new kernel"
echo "2. run make modules_install"
echo "3. run modules-rebuild"
echo "4. update the ChangeLog"
echo ""


In order to hook this to the standard make install command run at kernel build, this needs to be placed in /sbin/installkernel.
Alas, that position is already taken by a file belonging to the debianutils package. Arrgghhh!!
I opened a bug (and provided a patch) to make this optional.

For now the ebuild for installing the script (myinstallkernel-0.1.ebuild) must block debianutils:

EAPI="2"

LICENSE="GPL"
SLOT="0"
KEYWORDS="x86"
IUSE="+symlink"

DEPEND="symlink? ( sys-apps/debianutils[-installkernel] )"

src_install() {
newsbin ${FILESDIR}/${P} ${PN}

if use symlink; then
dosym /usr/sbin/${PN} /sbin/installkernel
fi

insinto /usr/share/eselect/modules
newins ${FILESDIR}/mykernel.eselect-${PV} mykernel.eselect
}


Update 03-Jun-2010:
1. Updated myinstallkernel script to version 0.3.
2. The bug wasn't accepted by gentoo, but they suggested using CONFIG_PROTECT="/sbin/installkernel" in /etc/make.conf. This kinda works, so I've removed the block from the ebuild.

No comments:

Post a Comment