|
|
c1a53c5 |
#!/bin/bash -
|
|
|
c1a53c5 |
############################################################################
|
|
|
c1a53c5 |
#
|
|
|
c1a53c5 |
# akmods - Rebuilds and install akmod RPMs
|
|
|
c1a53c5 |
# Copyright (c) 2007, 2008 Thorsten Leemhuis <fedora@leemhuis.info>
|
|
|
c1a53c5 |
#
|
|
|
c1a53c5 |
# Permission is hereby granted, free of charge, to any person obtaining
|
|
|
c1a53c5 |
# a copy of this software and associated documentation files (the
|
|
|
c1a53c5 |
# "Software"), to deal in the Software without restriction, including
|
|
|
c1a53c5 |
# without limitation the rights to use, copy, modify, merge, publish,
|
|
|
c1a53c5 |
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
c1a53c5 |
# permit persons to whom the Software is furnished to do so, subject to
|
|
|
c1a53c5 |
# the following conditions:
|
|
|
c1a53c5 |
#
|
|
|
c1a53c5 |
# The above copyright notice and this permission notice shall be
|
|
|
c1a53c5 |
# included in all copies or substantial portions of the Software.
|
|
|
c1a53c5 |
#
|
|
|
c1a53c5 |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
c1a53c5 |
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
c1a53c5 |
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
c1a53c5 |
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
|
c1a53c5 |
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
|
c1a53c5 |
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
c1a53c5 |
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
c1a53c5 |
#
|
|
|
c1a53c5 |
############################################################################
|
|
|
c1a53c5 |
#
|
|
|
c1a53c5 |
# ToDo:
|
|
|
c1a53c5 |
# - use yum/dnf to install required kernel-devel packages?
|
|
|
c1a53c5 |
# - better way to detect if a earlier build failed or succeeded
|
|
|
c1a53c5 |
# - special kernel "all" (all that are installed with a matching -devel package; could be called from posttrans in akmods packages)
|
|
|
c1a53c5 |
# - manpage
|
|
|
c1a53c5 |
# - make it configurable if kmod building is done with nohup
|
|
|
c1a53c5 |
# - check on shutdown if akmods is still running and let it finish before continuing
|
|
|
c1a53c5 |
# - make it configurable if kmods from the repo replace local ones
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# global vars
|
|
|
c1a53c5 |
myprog="akmods"
|
|
|
c1a53c5 |
myver="0.5.6"
|
|
|
c1a53c5 |
kmodlogfile=
|
|
|
c1a53c5 |
continue_line=""
|
|
|
c1a53c5 |
tmpdir=
|
|
|
c1a53c5 |
kernels=
|
|
|
c1a53c5 |
verboselevel=2
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
akmods_echo()
|
|
|
c1a53c5 |
{
|
|
|
c1a53c5 |
# where to output
|
|
|
c1a53c5 |
local this_fd=${1}
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# verboselevel
|
|
|
c1a53c5 |
local this_verbose=${1}
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# output to console
|
|
|
c1a53c5 |
if (( ${verboselevel} >= ${this_verbose} )) ; then
|
|
|
c1a53c5 |
if [[ "${1}" == "--success" ]] ; then
|
|
|
c1a53c5 |
echo_success
|
|
|
c1a53c5 |
continue_line=""
|
|
|
c1a53c5 |
echo
|
|
|
c1a53c5 |
return 0
|
|
|
c1a53c5 |
elif [[ "${1}" == "--failure" ]]; then
|
|
|
c1a53c5 |
echo_failure
|
|
|
c1a53c5 |
echo
|
|
|
c1a53c5 |
continue_line=""
|
|
|
c1a53c5 |
return 0
|
|
|
c1a53c5 |
elif [[ "${1}" == "--warning" ]]; then
|
|
|
c1a53c5 |
echo_warning
|
|
|
c1a53c5 |
echo
|
|
|
c1a53c5 |
continue_line=""
|
|
|
c1a53c5 |
return 0
|
|
|
c1a53c5 |
elif [[ "${1}" == "-n" ]]; then
|
|
|
c1a53c5 |
continue_line="true"
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
echo "$@" >&${this_fd}
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# no need to print the status flags in the logs
|
|
|
c1a53c5 |
if [[ "${1}" == "--success" ]] || [[ "${1}" == "--failure" ]] || [[ "${1}" == "--warning" ]]; then
|
|
|
c1a53c5 |
return 0
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# no need to continues in the log
|
|
|
c1a53c5 |
if [[ "${1}" == "-n" ]]; then
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# global logfile
|
|
|
c1a53c5 |
echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $@" >> "/var/cache/akmods/akmods.log"
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# the kmods logfile as well, if we work on a kmod
|
|
|
c1a53c5 |
if [[ "${kmodlogfile}" ]]; then
|
|
|
c1a53c5 |
echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $@" >> "${kmodlogfile}"
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
finally()
|
|
|
c1a53c5 |
{
|
|
|
c1a53c5 |
# remove tmpfiles
|
|
|
c1a53c5 |
remove_tmpdir
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# remove lockfile
|
|
|
c1a53c5 |
rm -f /var/cache/akmods/.lockfile
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
exit ${1:-128}
|
|
|
c1a53c5 |
}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# Make sure finally() is run regardless of reason for exiting.
|
|
|
c1a53c5 |
trap "finally" ABRT HUP INT QUIT
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
create_tmpdir()
|
|
|
c1a53c5 |
{
|
|
|
c1a53c5 |
if ! tmpdir="$(mktemp -d -p /tmp ${myprog}.XXXXXXXX)/" ; then
|
|
|
c1a53c5 |
akmods_echo 2 1 "ERROR: failed to create tmpdir."
|
|
|
c1a53c5 |
akmods_echo 2 1 --failure; return 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
if ! mkdir "${tmpdir}"results ; then
|
|
|
c1a53c5 |
akmods_echo 2 1 "ERROR: failed to create result tmpdir."
|
|
|
c1a53c5 |
akmods_echo 2 1 --failure; return 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
remove_tmpdir()
|
|
|
c1a53c5 |
{
|
|
|
c1a53c5 |
# remove tmpfiles
|
|
|
c1a53c5 |
if [[ "${tmpdir}" ]] && [[ -d "${tmpdir}" ]]; then
|
|
|
c1a53c5 |
rm -f "${tmpdir}"results/* "${tmpdir}"*.log
|
|
|
c1a53c5 |
rmdir "${tmpdir}"results/ "${tmpdir}"
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
cleanup_cachedir ()
|
|
|
c1a53c5 |
{
|
|
|
c1a53c5 |
create_tmpdir
|
|
|
c1a53c5 |
find /boot/ -maxdepth 1 -name 'vmlinuz*' | sed 's|/boot/vmlinuz-||' > "${tmpdir}"results/kernels
|
|
|
c1a53c5 |
find "/var/cache/akmods/" -maxdepth 2 -mtime +14 -type f \( -name '*.rpm' -or -name '*.log' \) | grep -v --file "${tmpdir}"results/kernels | xargs --no-run-if-empty rm
|
|
|
c1a53c5 |
remove_tmpdir
|
|
|
c1a53c5 |
}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
init ()
|
|
|
c1a53c5 |
{
|
|
|
c1a53c5 |
# some security provisions
|
|
|
c1a53c5 |
\export PATH='/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin'
|
|
|
c1a53c5 |
\unalias -a
|
|
|
c1a53c5 |
hash -r
|
|
|
c1a53c5 |
# https://bugzilla.rpmfusion.org/show_bug.cgi?id=4023
|
|
|
c1a53c5 |
#ulimit -H -c 0 --
|
|
|
c1a53c5 |
IFS=$' \t\n'
|
|
|
c1a53c5 |
UMASK=022
|
|
|
c1a53c5 |
umask ${UMASK}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# fall back to current kernel if user didn't provide one
|
|
|
c1a53c5 |
if [[ ! "${kernels}" ]]; then
|
|
|
c1a53c5 |
kernels="$(uname -r)"
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# we get the echo_{success,failure} stuff from there
|
|
|
c1a53c5 |
if [[ -r /etc/rc.d/init.d/functions ]]; then
|
|
|
c1a53c5 |
source /etc/rc.d/init.d/functions
|
|
|
c1a53c5 |
else
|
|
|
c1a53c5 |
echo "/etc/rc.d/init.d/functions not found" >&2
|
|
|
c1a53c5 |
exit 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# needs root permissions
|
|
|
7f8975a |
if [[ ! -w /var ]]; then
|
|
|
c1a53c5 |
echo -n "Needs to run as root to be able to install rpms." >&2
|
|
|
c1a53c5 |
echo_failure; echo; exit 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# no akmods
|
|
|
c1a53c5 |
if [[ ! -d "/usr/src/akmods/" ]] ; then
|
|
|
c1a53c5 |
echo -n "/usr/src/akmods/ not found." >&2
|
|
|
c1a53c5 |
echo_failure; echo; exit 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# if there are no akmod packages installed there is nothing to do for us
|
|
|
c1a53c5 |
if ! ls /usr/src/akmods/*-kmod.latest &> /dev/null ; then
|
|
|
c1a53c5 |
echo -n "No akmod packages found, nothing to do." >&2
|
|
|
3b4a499 |
echo_success; echo; exit 0
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# now that we know that we're root make sure our dir for logging and results is available
|
|
|
c1a53c5 |
if [[ ! -d "/var/cache/akmods/" ]] ; then
|
|
|
c1a53c5 |
if ! mkdir -p "/var/cache/akmods/" ; then
|
|
|
c1a53c5 |
echo -n "/var/cache/akmods/ not found and could not be created" >&2
|
|
|
c1a53c5 |
echo_failure; echo; exit 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
if [[ ! -w "/var/cache/akmods/" ]] ; then
|
|
|
c1a53c5 |
echo -n "${directory} not writable" >&2
|
|
|
c1a53c5 |
echo_failure; echo; exit 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# tools needed
|
|
|
c1a53c5 |
for tool in akmodsbuild chown flock sed rpmdev-vercmp; do
|
|
|
c1a53c5 |
if ! which "${tool}" &> /dev/null ; then
|
|
|
c1a53c5 |
echo -n "${tool} not found" >&2
|
|
|
c1a53c5 |
echo_failure; echo; exit 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
done
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# create lockfile and wait till we get it
|
|
|
c1a53c5 |
exec 99>/var/lock/subsys/akmods
|
|
|
c1a53c5 |
flock -w 900 99
|
|
|
c1a53c5 |
}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
buildinstall_kmod()
|
|
|
c1a53c5 |
{
|
|
|
c1a53c5 |
local this_kernelver=${1}
|
|
|
c1a53c5 |
local this_kmodname=${2}
|
|
|
c1a53c5 |
local this_kmodsrpm=${3}
|
|
|
c1a53c5 |
local this_kmodverrel=${4}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
if [[ ! -r "${this_kmodsrpm}" ]]; then
|
|
|
c1a53c5 |
akmods_echo 2 1 "ERROR: ${this_kmodsrpm} not found."
|
|
|
c1a53c5 |
akmods_echo 2 1 --failure; return 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# result and logdir
|
|
|
c1a53c5 |
if [[ ! -d "/var/cache/akmods/${this_kmodname}" ]]; then
|
|
|
c1a53c5 |
if ! mkdir "/var/cache/akmods/${this_kmodname}" ; then
|
|
|
c1a53c5 |
akmods_echo 2 1 "ERROR: could not create /var/cache/akmods/${this_kmodname}."
|
|
|
c1a53c5 |
akmods_echo 2 1 --failure; return 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
## preparations
|
|
|
c1a53c5 |
# tmpdir
|
|
|
c1a53c5 |
create_tmpdir
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# akmods needs to write there (and nobody else, but mktemp takes care of that!)
|
|
|
c1a53c5 |
chown akmods "${tmpdir}" "${tmpdir}"results
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# remove old logfiles if they exist
|
|
|
c1a53c5 |
rm -f "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.log" "/var/cache/akmods/${this_kmodname}/.last.log"
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# create a per kmod logfile
|
|
|
c1a53c5 |
if ! touch "/var/cache/akmods/${this_kmodname}/.last.log" ; then
|
|
|
c1a53c5 |
akmods_echo 2 1 "ERROR: failed to create kmod specific logfile."
|
|
|
c1a53c5 |
return 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# akmods_echo will log to this file from now on as well
|
|
|
c1a53c5 |
kmodlogfile="/var/cache/akmods/${this_kmodname}/.last.log"
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# Unset TMPDIR since it is misused by "runuser"
|
|
|
c1a53c5 |
# https://bugzilla.rpmfusion.org/show_bug.cgi?id=2596
|
|
|
c1a53c5 |
unset TMPDIR
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# build module using akmod
|
|
|
c1a53c5 |
akmods_echo 1 4 "Building RPM using the command '$(which akmodsbuild) --target $(uname -m) --kernels ${this_kernelver} ${this_kmodsrpm}'"
|
|
|
c1a53c5 |
/sbin/runuser -s /bin/bash -c "$(which akmodsbuild) --quiet --quiet --target $(uname -m) --kernels ${this_kernelver} --outputdir ${tmpdir}results --logfile ${tmpdir}/akmodsbuild.log ${this_kmodsrpm}" akmods >> "${kmodlogfile}" 2>&1
|
|
|
c1a53c5 |
local returncode=$?
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# copy rpmbuild log to kmod specific logfile
|
|
|
c1a53c5 |
if [[ -s "${tmpdir}"/akmodsbuild.log ]]; then
|
|
|
c1a53c5 |
while read line ; do
|
|
|
c1a53c5 |
echo "$(date +%Y/%m/%d\ %H:%M:%S) akmodsbuild: ${line}" >> "${kmodlogfile}"
|
|
|
c1a53c5 |
done < "${tmpdir}"/akmodsbuild.log
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# result
|
|
|
c1a53c5 |
if (( ! ${returncode} == 0 )); then
|
|
|
c1a53c5 |
if [[ "${continue_line}" ]]; then
|
|
|
c1a53c5 |
akmods_echo 1 2 --failure
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
akmods_echo 2 1 "Building rpms failed; see /var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log for details"
|
|
|
c1a53c5 |
cp -fl "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log"
|
|
|
c1a53c5 |
kmodlogfile=""
|
|
|
c1a53c5 |
remove_tmpdir
|
|
|
c1a53c5 |
return 4
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# dnf/yum install - repository disabled on purpose see rfbz#3350
|
|
|
c1a53c5 |
akmods_echo 1 4 "Installing newly built rpms"
|
|
|
c1a53c5 |
if [ -f /usr/bin/dnf ]; then
|
|
|
c1a53c5 |
akmods_echo 1 4 "DNF detected"
|
|
|
c1a53c5 |
dnf -y install --disablerepo='*' $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) >> "${kmodlogfile}" 2>&1
|
|
|
c1a53c5 |
else
|
|
|
c1a53c5 |
akmods_echo 1 4 "DNF not found, using YUM instead."
|
|
|
c1a53c5 |
yum -y install --disablerepo='*' $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) >> "${kmodlogfile}" 2>&1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
local returncode=$?
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# place the newly built rpms where user expects them
|
|
|
c1a53c5 |
cp "${tmpdir}results/"* "/var/cache/akmods/${this_kmodname}/"
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# everything fine?
|
|
|
c1a53c5 |
if (( ${returncode} != 0 )); then
|
|
|
c1a53c5 |
if [[ "${continue_line}" ]]; then
|
|
|
c1a53c5 |
akmods_echo 1 2 --failure
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
akmods_echo 2 1 "Could not install newly built RPMs. You can find them and the logfile"
|
|
|
c1a53c5 |
akmods_echo 2 1 "${this_kmodverrel}-for-${this_kernelver}.failed.log in /var/cache/akmods/${this_kmodname}/"
|
|
|
c1a53c5 |
cp -fl "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log"
|
|
|
c1a53c5 |
kmodlogfile=""
|
|
|
c1a53c5 |
remove_tmpdir
|
|
|
c1a53c5 |
return 8
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# finish
|
|
|
c1a53c5 |
akmods_echo 1 4 "Successful."
|
|
|
c1a53c5 |
cp -fl "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.log"
|
|
|
c1a53c5 |
kmodlogfile=""
|
|
|
c1a53c5 |
remove_tmpdir
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
return 0
|
|
|
c1a53c5 |
}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
check_kmod_up2date()
|
|
|
c1a53c5 |
{
|
|
|
c1a53c5 |
local this_kernelver=${1}
|
|
|
c1a53c5 |
local this_kmodname=${2}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# kmod present?
|
|
|
c1a53c5 |
if [[ ! -d /usr/lib/modules/${this_kernelver}/extra/${this_kmodname}/ ]] ; then
|
|
|
c1a53c5 |
# build it
|
|
|
c1a53c5 |
return 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# kmod up2date?
|
|
|
c1a53c5 |
local kmodpackage="$(rpm -qf /usr/lib/modules/${this_kernelver}/extra/${this_kmodname}/ 2> /dev/null)"
|
|
|
c1a53c5 |
if [[ ! "${kmodpackage}" ]]; then
|
|
|
c1a53c5 |
# seems we didn't get what we wanted
|
|
|
c1a53c5 |
# well, better to do nothing in this case
|
|
|
c1a53c5 |
akmods_echo 1 2 -n "Warning: Could not determine what package owns /usr/lib/modules/${this_kernelver}/extra/${this_kmodname}/"
|
|
|
c1a53c5 |
return 0
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
local kmodver=$(rpm -q --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' "${kmodpackage}" | sed 's|(none)|0|; s!\.\(fc\|lvn\)[0-9]*!!g')
|
|
|
c1a53c5 |
local akmodver=$(rpm -qp --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' /usr/src/akmods/"${this_kmodname}"-kmod.latest | sed 's|(none)|0|; s!\.\(fc\|lvn\)[0-9]*!!g')
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
rpmdev-vercmp "${kmodver}" "${akmodver}" &>/dev/null
|
|
|
c1a53c5 |
local retvalue=$?
|
|
|
c1a53c5 |
if [ "$retvalue" == 0 ]; then
|
|
|
c1a53c5 |
# Versions are the same. Nothing to do.
|
|
|
c1a53c5 |
return 0
|
|
|
c1a53c5 |
elif [ "$retvalue" == 11 ]; then
|
|
|
c1a53c5 |
# kmod is newer, nothing to do.
|
|
|
c1a53c5 |
return 0
|
|
|
c1a53c5 |
elif [ "$retvalue" == 12 ]; then
|
|
|
c1a53c5 |
# akmod is newer, need to build kmod.
|
|
|
c1a53c5 |
return 1
|
|
|
c1a53c5 |
else
|
|
|
c1a53c5 |
# Something went wrong
|
|
|
c1a53c5 |
akmods_echo 1 2 -n "Error: Could not determine if akmod is newer than the installed kmod"
|
|
|
c1a53c5 |
akmods_echo 1 2 --failure
|
|
|
c1a53c5 |
return 0
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
check_kmods()
|
|
|
c1a53c5 |
{
|
|
|
c1a53c5 |
local this_kernelver="${1}"
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
akmods_echo 1 2 -n "Checking kmods exist for ${this_kernelver}"
|
|
|
c1a53c5 |
for akmods_kmodfile in /usr/src/akmods/*-kmod.latest ; do
|
|
|
c1a53c5 |
local this_kmodname="$(basename ${akmods_kmodfile%%-kmod.latest})"
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# actually check this akmod?
|
|
|
c1a53c5 |
if [[ "${akmods}" ]]; then
|
|
|
c1a53c5 |
for akmod in ${akmods} ; do
|
|
|
c1a53c5 |
if [[ "${this_kmodname}" != "${akmod}" ]] ; then
|
|
|
c1a53c5 |
# ignore this one
|
|
|
c1a53c5 |
continue 2
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
done
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# go
|
|
|
c1a53c5 |
if ! check_kmod_up2date ${this_kernelver} ${this_kmodname} ; then
|
|
|
c1a53c5 |
# okay, kmod wasn't found or is not up2date
|
|
|
c1a53c5 |
if [[ "${continue_line}" ]]; then
|
|
|
c1a53c5 |
akmods_echo 1 2 --success
|
|
|
c1a53c5 |
# if the files for building modules are not available don't even try to build modules
|
|
|
c1a53c5 |
if [[ ! -r /usr/src/kernels/"${this_kernelver}"/Makefile ]] && \
|
|
|
c1a53c5 |
[[ ! -r /usr/lib/modules/${this_kernelver}/build/Makefile ]]; then
|
|
|
c1a53c5 |
akmods_echo 1 2 "Files needed for building modules against kernel"
|
|
|
c1a53c5 |
akmods_echo 1 2 "${this_kernelver} could not be found as the following"
|
|
|
c1a53c5 |
akmods_echo 1 2 "directories are missing:"
|
|
|
c1a53c5 |
akmods_echo 1 2 "/usr/src/kernels/${this_kernelver}/"
|
|
|
c1a53c5 |
akmods_echo 1 2 -n "/usr/lib/modules/${this_kernelver}/build/"
|
|
|
c1a53c5 |
akmods_echo 1 2 -n "Is the correct kernel-devel package installed?"
|
|
|
c1a53c5 |
akmods_echo 1 2 --failure
|
|
|
c1a53c5 |
return 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
local this_kmodverrel="$(rpm -qp --qf '%{VERSION}-%{RELEASE}' "${akmods_kmodfile}" | sed 's!\.\(fc\|lvn\)[0-9]*!!g' )"
|
|
|
c1a53c5 |
if [[ ! "${alwaystry}" ]] && [[ -e "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}".failed.log ]]; then
|
|
|
c1a53c5 |
akmods_echo 1 2 -n "Ignoring ${this_kmodname}-kmod as it failed earlier"
|
|
|
c1a53c5 |
akmods_echo 1 2 --warning
|
|
|
c1a53c5 |
local someignored="true"
|
|
|
c1a53c5 |
else
|
|
|
c1a53c5 |
akmods_echo 1 2 -n "Building and installing ${this_kmodname}-kmod"
|
|
|
c1a53c5 |
buildinstall_kmod ${this_kernelver} ${this_kmodname} ${akmods_kmodfile} ${this_kmodverrel}
|
|
|
c1a53c5 |
local returncode=$?
|
|
|
c1a53c5 |
if [[ "$returncode" == "0" ]]; then
|
|
|
c1a53c5 |
akmods_echo 1 2 --success
|
|
|
fd6e351 |
local somesucceeded="true"
|
|
|
c1a53c5 |
elif [[ "$returncode" == "8" ]]; then
|
|
|
c1a53c5 |
akmods_echo 1 2 --failure "New kmod RPM was built but could not be installed."
|
|
|
c1a53c5 |
else
|
|
|
c1a53c5 |
local somefailed="true"
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
done
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
if [[ "${continue_line}" ]]; then
|
|
|
c1a53c5 |
akmods_echo 1 2 --success
|
|
|
c1a53c5 |
elif [[ "${someignored}" ]] || [[ "${somefailed}" ]] ; then
|
|
|
c1a53c5 |
echo
|
|
|
c1a53c5 |
akmods_echo 1 2 "Hint: Some kmods were ignored or failed to build or install."
|
|
|
c1a53c5 |
akmods_echo 1 2 "You can try to rebuild and install them by by calling"
|
|
|
c1a53c5 |
akmods_echo 1 2 "'/usr/sbin/akmods --force' as root."
|
|
|
c1a53c5 |
echo
|
|
|
c1a53c5 |
sleep 2
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
|
|
|
fd6e351 |
# akmods for newly installed akmod rpms as wells as akmods.service run
|
|
|
fd6e351 |
# after udev and systemd-modules-load.service have tried to load modules
|
|
|
fd6e351 |
if [[ "${somesucceeded}" ]] && [ ${this_kernelver} = "$(uname -r)" ]; then
|
|
|
3b4a499 |
find /sys/devices -name modalias -print0 | xargs -0 cat | xargs modprobe -a -b -q
|
|
|
69ecb7f |
if [ -f /usr/bin/systemctl ] ; then
|
|
|
69ecb7f |
systemctl restart systemd-modules-load.service
|
|
|
69ecb7f |
fi
|
|
|
fd6e351 |
fi
|
|
|
c1a53c5 |
}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
myprog_help ()
|
|
|
c1a53c5 |
{
|
|
|
c1a53c5 |
echo "Checks the akmod packages and rebuilds them if needed"
|
|
|
c1a53c5 |
echo $'\n'"Usage: ${myprog} [OPTIONS]"
|
|
|
c1a53c5 |
echo $'\n'"Options:"
|
|
|
c1a53c5 |
echo " --force -- try all, even if they failed earlier"
|
|
|
c1a53c5 |
echo " --kernels <kernel> -- build and install only for kernel <kernel>"
|
|
|
c1a53c5 |
echo " (formatted the same as 'uname -r' would produce)"
|
|
|
c1a53c5 |
echo " --akmod <akmod> -- build and install only akmod <akmod>"
|
|
|
c1a53c5 |
}
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# first parse command line options
|
|
|
c1a53c5 |
while [ "${1}" ] ; do
|
|
|
c1a53c5 |
case "${1}" in
|
|
|
c1a53c5 |
--kernel|--kernels)
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
if [[ ! "${1}" ]] ; then
|
|
|
c1a53c5 |
echo "ERROR: Please provide the kernel-version to build for together with --kernel" >&2
|
|
|
c1a53c5 |
exit 1
|
|
|
c1a53c5 |
elif [[ ! -r /usr/src/kernels/"${1}"/Makefile ]] && \
|
|
|
c1a53c5 |
[[ ! -r /usr/lib/modules/${1}/build/Makefile ]]; then
|
|
|
c1a53c5 |
echo "Could not find files needed to compile modules for ${1}"
|
|
|
c1a53c5 |
echo "Are the development files for kernel ${1} or the appropriate kernel-devel package installed?"
|
|
|
c1a53c5 |
exit 1
|
|
|
c1a53c5 |
elif [[ -r /usr/src/kernels/"${1}"/Makefile ]] && \
|
|
|
c1a53c5 |
[[ ! -r /boot/vmlinuz-"${1}" ]]; then
|
|
|
c1a53c5 |
# this is a red hat / fedora kernel-devel package, but the kernel for it is not installed
|
|
|
c1a53c5 |
# kmodtool would add a dep on that kernel when building; thus when we'd try to install the
|
|
|
c1a53c5 |
# rpms we'd run into a missing-dep problem. Thus we prevent that case
|
|
|
c1a53c5 |
echo "Kernel ${1} not installed"
|
|
|
c1a53c5 |
exit 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
# overwrites the default:
|
|
|
c1a53c5 |
kernels="${kernels}${1}"
|
|
|
c1a53c5 |
# an try to build, even if we tried already
|
|
|
c1a53c5 |
alwaystry=true
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
;;
|
|
|
c1a53c5 |
--akmod|--kmod)
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
if [[ ! "${1}" ]] ; then
|
|
|
c1a53c5 |
echo "ERROR: Please provide a name of a akmod package together with --akmods" >&2
|
|
|
c1a53c5 |
exit 1
|
|
|
c1a53c5 |
elif [[ -r /usr/src/akmods/"${1}"-kmod.latest ]] ; then
|
|
|
c1a53c5 |
akmods="${akmods}${1} "
|
|
|
c1a53c5 |
elif [[ -r /usr/src/akmods/"${1}".latest ]] ; then
|
|
|
c1a53c5 |
akmods="${akmods}${1%%-kmod} "
|
|
|
c1a53c5 |
else
|
|
|
c1a53c5 |
echo "Could not find akmod ${1}"
|
|
|
c1a53c5 |
exit 1
|
|
|
c1a53c5 |
fi
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
;;
|
|
|
c1a53c5 |
--force)
|
|
|
c1a53c5 |
alwaystry=true
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
;;
|
|
|
c1a53c5 |
--from-init)
|
|
|
c1a53c5 |
# just in case: remove stale lockfile if it exists:
|
|
|
c1a53c5 |
rm -f /var/cache/akmods/.lockfile
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
;;
|
|
|
c1a53c5 |
--from-posttrans|--from-kernel-posttrans|--from-akmod-posttrans)
|
|
|
c1a53c5 |
# ignored
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
;;
|
|
|
c1a53c5 |
--verbose)
|
|
|
c1a53c5 |
let verboselevel++
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
;;
|
|
|
c1a53c5 |
--quiet)
|
|
|
c1a53c5 |
let verboselevel--
|
|
|
c1a53c5 |
shift
|
|
|
c1a53c5 |
;;
|
|
|
c1a53c5 |
--help)
|
|
|
c1a53c5 |
myprog_help
|
|
|
c1a53c5 |
exit 0
|
|
|
c1a53c5 |
;;
|
|
|
c1a53c5 |
--version)
|
|
|
c1a53c5 |
echo "${myprog} ${myver}"
|
|
|
c1a53c5 |
exit 0
|
|
|
c1a53c5 |
;;
|
|
|
c1a53c5 |
*)
|
|
|
c1a53c5 |
echo "Error: Unknown option '${1}'." >&2
|
|
|
c1a53c5 |
myprog_help >&2
|
|
|
c1a53c5 |
exit 2
|
|
|
c1a53c5 |
;;
|
|
|
c1a53c5 |
esac
|
|
|
c1a53c5 |
done
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# sanity checks
|
|
|
c1a53c5 |
init
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# go
|
|
|
c1a53c5 |
for kernel in ${kernels} ; do
|
|
|
c1a53c5 |
check_kmods ${kernel}
|
|
|
c1a53c5 |
done
|
|
|
c1a53c5 |
|
|
|
c1a53c5 |
# finished :)
|
|
|
c1a53c5 |
finally 0
|