#!/bin/sh
# Copyright (C) 2002-2005 Flavio Stanchina
# Copyright (C) 2005-2006 Aric Cyr
# Copyright (C) 2007 Mario Limonciello
# Copyright (C) 2009 Alberto Milone
set -e
MODDIR="/lib/modules"
_get_kernel_dir() {
KVER=$1
DIR="$MODDIR/$KVER/build"
echo "$DIR"
}
_check_kernel_dir() {
DIR=$(_get_kernel_dir "$1")
test -e "$DIR/include"
return $?
}
# Check the existence of a kernel named as $1
_is_kernel_name_correct() {
if [ -e "$MODDIR/$1" ]; then
echo yes
else
echo no
fi
}
# Get the most recent kernel on Debian based systems. This keeps
# into account both the version and the ABI. If the current kernel
# is the most recent kernel then the function will print a null string.
_get_newest_kernel_debian() {
NEWEST_KERNEL=
NEWEST_VERSION=
NEWEST_ABI=
for kernel in /boot/config-*; do
[ -f "$kernel" ] || continue
KERNEL=${kernel#*-}
KERNEL_VERSION=${KERNEL%%-*}
ABI=${KERNEL#*-}
ABI=${ABI%%-*}
if [ -z "$NEWEST_KERNEL" ]; then
# The 1st time get a version which is bigger than $1
COMPARE_TO=$1
else
# Get the biggest version
COMPARE_TO="$NEWEST_VERSION-$NEWEST_ABI"
fi
# if $kernel is greater than $COMPARE_TO
if [ "$(dpkg --compare-versions "$KERNEL_VERSION-$ABI" ge "$COMPARE_TO" && echo "yes" || \
echo "no")" = "yes" ]; then
NEWEST_KERNEL=$KERNEL
NEWEST_VERSION=$KERNEL_VERSION
NEWEST_ABI=$ABI
fi
done
echo "$NEWEST_KERNEL"
}
# Get the most recent kernel in Rhel based systems.
_get_newest_kernel_rhel() {
rpm -q --qf="%{VERSION}-%{RELEASE}.%{ARCH}\n" --whatprovides kernel | tail -n 1
}
# Get the newest kernel on Debian and Rhel based systems.
get_newest_kernel() {
NEWEST_KERNEL=
# Try Debian first as rpm can be installed in Debian based distros
if [ -e /usr/bin/dpkg ]; then
# If DEB based
CURRENT_VERSION=${CURRENT_KERNEL%%-*}
CURRENT_ABI=${CURRENT_KERNEL#*-}
# shellcheck disable=SC2034
# not used now, might use it later
CURRENT_FLAVOUR=${CURRENT_ABI#*-}
CURRENT_ABI=${CURRENT_ABI%%-*}
NEWEST_KERNEL=$(_get_newest_kernel_debian "$CURRENT_VERSION-$CURRENT_ABI")
elif command -v rpm >/dev/null 2>&1; then
# If RPM based
NEWEST_KERNEL=$(_get_newest_kernel_rhel)
fi
# Make sure that kernel name that we extracted corresponds to an installed
# kernel
if [ -n "$NEWEST_KERNEL" ] && [ "$(_is_kernel_name_correct "$NEWEST_KERNEL")" = "no" ]; then
NEWEST_KERNEL=
fi
echo "$NEWEST_KERNEL"
}
NAME=$1
VERSION=$2
TARBALL_ROOT=$3
ARCH=$4
UPGRADE=$5
if [ -z "$NAME" ] || [ -z "$VERSION" ]; then
echo "Need NAME, and VERSION defined"
echo "ARCH is optional"
exit 1
fi
if [ -f /etc/dkms/no-autoinstall ]; then
echo "autoinstall for dkms modules has been disabled."
exit 0
fi
# read framework configuration options
for fwcf in /etc/dkms/framework.conf /etc/dkms/framework.conf.d/*.conf ; do
if [ -f "$fwcf" ] && [ -r "$fwcf" ]; then
# shellcheck disable=SC1090
. "$fwcf"
fi
done
# shellcheck disable=SC2012
# suggests to use find here instead, but that is not equivalent
KERNELS=$(ls -dv "$MODDIR"/*/build 2>/dev/null | sed 's|'"$MODDIR"'/\(.*\)/build|\1|' || true)
CURRENT_KERNEL=$(uname -r)
#We never want to keep an older version side by side to prevent conflicts
if [ -e "/var/lib/dkms/$NAME/$VERSION" ]; then
echo "Removing old $NAME/$VERSION DKMS files..."
dkms remove -m "$NAME" -v "$VERSION" --all
fi
#Load new files, by source package and by tarball
if [ -f "$TARBALL_ROOT/$NAME-$VERSION.dkms.tar.gz" ]; then
if ! dkms ldtarball --archive "$TARBALL_ROOT/$NAME-$VERSION.dkms.tar.gz"; then
echo ""
echo ""
echo "Unable to load DKMS tarball $TARBALL_ROOT/$NAME-$VERSION.dkms.tar.gz."
echo "Common causes include: "
echo " - You must be using DKMS 2.1.0.0 or later to support binaries only"
echo " distribution specific archives."
echo " - Corrupt distribution specific archive"
echo ""
echo ""
exit 2
fi
elif [ -d "/usr/src/$NAME-$VERSION" ]; then
echo "Loading new $NAME/$VERSION DKMS files..."
dkms add -m "$NAME" -v "$VERSION" > /dev/null
fi
dkms_conf="/var/lib/dkms/$NAME/$VERSION/source/dkms.conf"
autoinstall=$(bash -c 'AUTOINSTALL=; . "'"$dkms_conf"'" >/dev/null 2>&1; echo $AUTOINSTALL')
if [ -z "$autoinstall" ]; then
echo "Not building the $NAME module which does not have AUTOINSTALL enabled."
exit 0
fi
dkms_conf="/var/lib/dkms/$NAME/$VERSION/source/dkms.conf"
autoinstall=$(bash -c 'AUTOINSTALL=; . "'"$dkms_conf"'" >/dev/null 2>&1; echo $AUTOINSTALL')
if [ -z "$autoinstall" ]; then
echo "Not building the $NAME module which does not have AUTOINSTALL enabled."
exit 0
fi
# On 1st installation, let us look for a directory
# in $MODDIR which matches $(uname -r). If none
# is found it is possible that buildd is being used
# and that uname -r is giving us the name of the
# kernel used by the buildd machine.
#
# If this is the case we try to build the kernel
# module for each kernel which has a directory in
# $MODDIR. Furthermore we will have to tell
# DKMS which architecture it should build the module
# for (e.g. if the buildd machine is using a
# 2.6.24-23-xen 64bit kernel).
#
# NOTE: if the headers are not installed then the
# module won't be built, as usual
# Here we look for the most recent kernel so that we can
# build the module for it (in addition to doing it for the
# current kernel).
NEWEST_KERNEL=$(get_newest_kernel)
if [ -z "$autoinstall_all_kernels" ]; then
# If the current kernel is installed on the system or chroot
if [ "$(_is_kernel_name_correct "$CURRENT_KERNEL")" = "yes" ]; then
if [ -n "$NEWEST_KERNEL" ] && [ "${CURRENT_KERNEL}" != "${NEWEST_KERNEL}" ]; then
KERNELS="$CURRENT_KERNEL $NEWEST_KERNEL"
else
KERNELS=$CURRENT_KERNEL
fi
# The current kernel is not useful as it's not installed
else
echo "It is likely that $CURRENT_KERNEL belongs to a chroot's host"
# Let's use only the newest kernel if this is not a first installation
# otherwise build for all kernels
if [ -n "$NEWEST_KERNEL" ] && [ -n "$UPGRADE" ]; then
KERNELS="$NEWEST_KERNEL"
fi
fi
fi
# Take care of displaying newline separated list
echo "Building for $KERNELS" | tr '\n' ',' \
| sed -e 's/,/, /g; s/, $/\n/; s/, \([^,]\+\)$/ and \1/'
if [ -n "$ARCH" ]; then
echo "Building for architecture $ARCH"
fi
for KERNEL in $KERNELS; do
echo ""
dkms_status=$(dkms status -m "$NAME" -v "$VERSION" -k "$KERNEL" ${ARCH:+-a "$ARCH"})
if [ "$(echo "$KERNEL" | grep -c "BOOT")" -gt 0 ]; then
echo "Module build and install for $KERNEL was skipped as "
echo "it is a BOOT variant"
continue
fi
#if the module isn't yet built, try to build it
if [ "$(echo "$dkms_status" | grep -c ": built")" -eq 0 ]; then
if [ ! -L "/var/lib/dkms/$NAME/$VERSION/source" ]; then
echo "This package appears to be a binaries-only package"
echo " you will not be able to build against kernel $KERNEL"
echo " since the package source was not provided"
continue
fi
if _check_kernel_dir "$KERNEL"; then
echo "Building initial module $NAME/$VERSION for $KERNEL"
res=0
dkms build -m "$NAME" -v "$VERSION" -k "$KERNEL" ${ARCH:+-a "$ARCH"} || res=$?
case "$res" in
77)
# skipped due to BUILD_EXCLUSIVE
continue
;;
0)
;;
*)
exit $res
;;
esac
dkms_status=$(dkms status -m "$NAME" -v "$VERSION" -k "$KERNEL" ${ARCH:+-a "$ARCH"})
else
echo "Module build for kernel $KERNEL was skipped since the"
echo "kernel headers for this kernel do not seem to be installed."
fi
fi
#if the module is built (either pre-built or just now), install it
if [ "$(echo "$dkms_status" | grep -c ": built")" -eq 1 ] &&
[ "$(echo "$dkms_status" | grep -c ": installed")" -eq 0 ]; then
dkms install -m "$NAME" -v "$VERSION" -k "$KERNEL" ${ARCH:+-a "$ARCH"}
fi
done
# vim: et:ts=4:sw=4
|