[akmods] Revert back to RPM Fusion SCM for akmods sources.

Richard Shaw hobbes1069 at rpmfusion.org
Tue Oct 18 17:28:05 CEST 2016


commit 2887e910916671dd4885fc57fa793b0541aefbf4
Author: Richard Shaw <hobbes1069 at gmail.com>
Date:   Tue Oct 18 10:27:48 2016 -0500

    Revert back to RPM Fusion SCM for akmods sources.

 README                  |   9 +
 akmods                  | 525 ++++++++++++++++++++++++++++++++++++++++++++++++
 akmods-shutdown         |  31 +++
 akmods-shutdown.service |  14 ++
 akmods.h2m              |  12 ++
 akmods.service.in       |  11 +
 akmods.spec             |  38 ++--
 akmodsbuild             | 358 +++++++++++++++++++++++++++++++++
 akmodsinit              |  47 +++++
 akmodsposttrans         |  37 ++++
 sources                 |   1 -
 11 files changed, 1070 insertions(+), 13 deletions(-)
---
diff --git a/README b/README
new file mode 100644
index 0000000..45e311f
--- /dev/null
+++ b/README
@@ -0,0 +1,9 @@
+Akmods startup script will rebuild akmod packages during system
+boot while its background daemon will build them for kernels right
+after they were installed.
+
+The akmods systemd service it enabled by default.
+
+The akmods-shutdown service is disabled by default but can, in some
+circumstantes, provide an additional chance to build and install a kernel
+module.
diff --git a/akmods b/akmods
new file mode 100755
index 0000000..7d8d24a
--- /dev/null
+++ b/akmods
@@ -0,0 +1,525 @@
+#!/bin/bash -
+############################################################################
+#
+# akmods - Rebuilds and install akmod RPMs
+# Copyright (c) 2007, 2008 Thorsten Leemhuis <fedora at leemhuis.info>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+############################################################################
+#
+# ToDo:
+# - use yum/dnf to install required kernel-devel packages?
+# - better way to detect if a earlier build failed or succeeded
+# - special kernel "all" (all that are installed with a matching -devel package; could be called from posttrans in akmods packages)
+# - manpage
+# - make it configurable if kmod building is done with nohup
+# - check on shutdown if akmods is still running and let it finish before continuing
+# - make it configurable if kmods from the repo replace local ones
+
+# global vars
+myprog="akmods"
+myver="0.5.6"
+kmodlogfile=
+continue_line=""
+tmpdir=
+kernels=
+verboselevel=2
+
+akmods_echo()
+{
+	# where to output
+	local this_fd=${1}
+	shift
+
+	# verboselevel
+	local this_verbose=${1}
+	shift
+
+	# output to console
+	if (( ${verboselevel} >= ${this_verbose} )) ; then
+		if [[ "${1}" == "--success" ]] ; then
+			echo_success
+			continue_line=""
+			echo
+			return 0
+		elif [[ "${1}" == "--failure" ]]; then
+			echo_failure
+			echo
+			continue_line=""
+			return 0
+		elif [[ "${1}" == "--warning" ]]; then
+			echo_warning
+			echo
+			continue_line=""
+			return 0
+		elif [[ "${1}" == "-n" ]]; then
+			continue_line="true"
+		fi
+		echo "$@" >&${this_fd}
+	fi
+
+	# no need to print the status flags in the logs
+	if [[ "${1}" == "--success" ]] || [[ "${1}" == "--failure" ]] || [[ "${1}" == "--warning" ]]; then
+		return 0
+	fi
+
+	# no need to continues in the log
+	if [[ "${1}" == "-n" ]]; then
+		shift
+	fi
+
+	# global logfile
+	echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $@" >> "/var/cache/akmods/akmods.log"
+
+	# the kmods logfile as well, if we work on a kmod
+	if [[ "${kmodlogfile}" ]]; then
+		echo "$(date +%Y/%m/%d\ %H:%M:%S) akmods: $@" >> "${kmodlogfile}"
+	fi
+}
+
+finally()
+{
+	# remove tmpfiles
+	remove_tmpdir
+
+	# remove lockfile
+	rm -f /var/cache/akmods/.lockfile
+
+	exit ${1:-128}
+}
+
+# Make sure finally() is run regardless of reason for exiting.
+trap "finally" ABRT HUP INT QUIT
+
+create_tmpdir()
+{
+	if ! tmpdir="$(mktemp -d -p /tmp ${myprog}.XXXXXXXX)/" ; then
+		akmods_echo 2 1  "ERROR: failed to create tmpdir."
+		akmods_echo 2 1 --failure; return 1
+	fi
+	if ! mkdir "${tmpdir}"results ; then
+		akmods_echo 2 1  "ERROR: failed to create result tmpdir."
+		akmods_echo 2 1 --failure; return 1
+	fi
+}
+
+remove_tmpdir()
+{
+	# remove tmpfiles
+	if [[ "${tmpdir}" ]] && [[ -d "${tmpdir}" ]]; then
+		rm -f "${tmpdir}"results/* "${tmpdir}"*.log
+		rmdir "${tmpdir}"results/ "${tmpdir}"
+	fi
+}
+
+cleanup_cachedir ()
+{
+	create_tmpdir
+	find /boot/ -maxdepth 1 -name 'vmlinuz*' | sed 's|/boot/vmlinuz-||' > "${tmpdir}"results/kernels
+	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
+	remove_tmpdir
+}
+
+init ()
+{
+	# some security provisions
+	\export PATH='/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin'
+	\unalias -a
+	hash -r
+	# https://bugzilla.rpmfusion.org/show_bug.cgi?id=4023
+	#ulimit -H -c 0 --
+	IFS=$' \t\n'
+	UMASK=022
+	umask ${UMASK}
+
+	# fall back to current kernel if user didn't provide one
+	if [[ ! "${kernels}" ]]; then
+		kernels="$(uname -r)"
+	fi
+
+	# we get the echo_{success,failure} stuff from there
+	if [[ -r /etc/rc.d/init.d/functions ]]; then
+		source /etc/rc.d/init.d/functions
+	else
+		echo "/etc/rc.d/init.d/functions not found" >&2
+		exit 1
+	fi
+
+	# needs root permissions
+	if [[ ! -w / ]]; then
+		echo -n "Needs to run as root to be able to install rpms." >&2
+		echo_failure; echo; exit 1
+	fi
+
+	# no akmods
+	if [[ ! -d "/usr/src/akmods/" ]] ; then
+		echo -n "/usr/src/akmods/ not found." >&2
+		echo_failure; echo; exit 1
+	fi
+
+	# if there are no akmod packages installed there is nothing to do for us
+	if ! ls /usr/src/akmods/*-kmod.latest &> /dev/null ; then
+		echo -n "No akmod packages found, nothing to do." >&2
+		echo_success; echo; exit 1
+	fi
+
+
+	# now that we know that we're root make sure our dir for logging and results is available
+	if [[ ! -d "/var/cache/akmods/" ]] ; then
+		if ! mkdir -p "/var/cache/akmods/" ; then
+			echo -n "/var/cache/akmods/ not found and could not be created" >&2
+			echo_failure; echo; exit 1
+		fi
+	fi
+	if [[ ! -w "/var/cache/akmods/" ]] ; then
+		echo -n "${directory} not writable" >&2
+		echo_failure; echo; exit 1
+	fi
+
+	# tools needed
+	for tool in akmodsbuild chown flock sed rpmdev-vercmp; do
+		if ! which "${tool}" &> /dev/null ; then
+			echo -n "${tool} not found" >&2
+			echo_failure; echo; exit 1
+		fi
+	done
+
+	# create lockfile and wait till we get it
+	exec 99>/var/lock/subsys/akmods
+	flock -w 900 99
+}
+
+buildinstall_kmod()
+{
+	local this_kernelver=${1}
+	local this_kmodname=${2}
+	local this_kmodsrpm=${3}
+	local this_kmodverrel=${4}
+
+	if [[ ! -r "${this_kmodsrpm}" ]]; then
+		akmods_echo 2 1 "ERROR: ${this_kmodsrpm} not found."
+		akmods_echo 2 1 --failure; return 1
+	fi
+
+
+	# result and logdir
+	if [[ ! -d "/var/cache/akmods/${this_kmodname}" ]]; then
+		if ! mkdir "/var/cache/akmods/${this_kmodname}" ; then
+			akmods_echo 2 1  "ERROR: could not create /var/cache/akmods/${this_kmodname}."
+			akmods_echo 2 1 --failure; return 1
+		fi
+	fi
+
+	## preparations
+	# tmpdir
+	create_tmpdir
+
+	# akmods needs to write there (and nobody else, but mktemp takes care of that!)
+	chown akmods "${tmpdir}" "${tmpdir}"results
+
+	# remove old logfiles if they exist
+	rm -f "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.log" "/var/cache/akmods/${this_kmodname}/.last.log"
+
+	# create a per kmod logfile
+	if ! touch "/var/cache/akmods/${this_kmodname}/.last.log" ; then
+		akmods_echo 2 1  "ERROR: failed to create kmod specific logfile."
+		return 1
+	fi
+
+	# akmods_echo will log to this file from now on as well
+	kmodlogfile="/var/cache/akmods/${this_kmodname}/.last.log"
+
+	# Unset TMPDIR since it is misused by "runuser"
+	# https://bugzilla.rpmfusion.org/show_bug.cgi?id=2596
+	unset TMPDIR
+
+	# build module using akmod
+	akmods_echo 1 4 "Building RPM using the command '$(which akmodsbuild) --target $(uname -m) --kernels ${this_kernelver} ${this_kmodsrpm}'"
+	/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
+	local returncode=$?
+
+	# copy rpmbuild log to kmod specific logfile
+	if [[ -s "${tmpdir}"/akmodsbuild.log ]]; then
+		while read line ; do
+			echo "$(date +%Y/%m/%d\ %H:%M:%S) akmodsbuild: ${line}" >> "${kmodlogfile}"
+		done < "${tmpdir}"/akmodsbuild.log
+	fi
+
+	# result
+	if (( ! ${returncode} == 0 )); then
+		if [[ "${continue_line}" ]]; then
+			akmods_echo 1 2 --failure
+		fi
+		akmods_echo 2 1  "Building rpms failed; see /var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log for details"
+		cp -fl "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log"
+		kmodlogfile=""
+		remove_tmpdir
+		return 4
+	fi
+
+	# dnf/yum install - repository disabled on purpose see rfbz#3350
+	akmods_echo 1 4 "Installing newly built rpms"
+	if [ -f /usr/bin/dnf ]; then
+		akmods_echo 1 4 "DNF detected"
+		dnf -y install --disablerepo='*' $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) >> "${kmodlogfile}" 2>&1
+	else
+		akmods_echo 1 4 "DNF not found, using YUM instead."
+		yum -y install --disablerepo='*' $(find "${tmpdir}results" -type f -name '*.rpm' | grep -v debuginfo) >> "${kmodlogfile}" 2>&1
+	fi
+	local returncode=$?
+
+	# place the newly built rpms where user expects them
+	cp "${tmpdir}results/"* "/var/cache/akmods/${this_kmodname}/"
+
+	# everything fine?
+	if (( ${returncode} != 0 )); then
+		if [[ "${continue_line}" ]]; then
+			akmods_echo 1 2 --failure
+		fi
+		akmods_echo 2 1 "Could not install newly built RPMs. You can find them and the logfile"
+		akmods_echo 2 1 "${this_kmodverrel}-for-${this_kernelver}.failed.log in /var/cache/akmods/${this_kmodname}/"
+		cp -fl "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.failed.log"
+		kmodlogfile=""
+		remove_tmpdir
+		return 8
+	fi
+
+	# finish
+	akmods_echo 1 4 "Successful."
+	cp -fl "${kmodlogfile}" "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}.log"
+	kmodlogfile=""
+	remove_tmpdir
+
+	return 0
+}
+
+check_kmod_up2date()
+{
+	local this_kernelver=${1}
+	local this_kmodname=${2}
+
+	# kmod present?
+	if [[ ! -d /usr/lib/modules/${this_kernelver}/extra/${this_kmodname}/ ]] ; then
+		# build it
+		return 1
+	fi
+
+	# kmod up2date?
+	local kmodpackage="$(rpm -qf /usr/lib/modules/${this_kernelver}/extra/${this_kmodname}/ 2> /dev/null)"
+	if [[ ! "${kmodpackage}" ]]; then
+		# seems we didn't get what we wanted
+		# well, better to do nothing in this case
+		akmods_echo 1 2 -n "Warning: Could not determine what package owns /usr/lib/modules/${this_kernelver}/extra/${this_kmodname}/"
+		return 0
+	fi
+	local kmodver=$(rpm -q --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' "${kmodpackage}" | sed 's|(none)|0|; s!\.\(fc\|lvn\)[0-9]*!!g')
+	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')
+
+	rpmdev-vercmp "${kmodver}" "${akmodver}" &>/dev/null
+	local retvalue=$?
+	if [ "$retvalue" == 0 ]; then
+		# Versions are the same. Nothing to do.
+		return 0
+	elif [ "$retvalue" == 11 ]; then
+		# kmod is newer, nothing to do.
+		return 0
+	elif [ "$retvalue" == 12 ]; then
+		# akmod is newer, need to build kmod.
+		return 1
+	else
+		# Something went wrong
+		akmods_echo 1 2 -n "Error: Could not determine if akmod is newer than the installed kmod"
+		akmods_echo 1 2 --failure
+		return 0
+	fi
+}
+
+check_kmods()
+{
+	local this_kernelver="${1}"
+
+	akmods_echo 1 2 -n "Checking kmods exist for ${this_kernelver}"
+	for akmods_kmodfile in /usr/src/akmods/*-kmod.latest ; do
+		local this_kmodname="$(basename ${akmods_kmodfile%%-kmod.latest})"
+		
+		# actually check this akmod?
+		if [[ "${akmods}" ]]; then
+			for akmod in ${akmods} ; do
+				if [[ "${this_kmodname}" != "${akmod}" ]] ; then
+					# ignore this one
+					continue 2
+				fi
+			done
+		fi
+
+		# go
+		if ! check_kmod_up2date ${this_kernelver} ${this_kmodname} ; then
+			# okay, kmod wasn't found or is not up2date
+			if [[ "${continue_line}" ]]; then
+				akmods_echo 1 2 --success 
+				# if the files for building modules are not available don't even try to build modules
+				if [[ ! -r /usr/src/kernels/"${this_kernelver}"/Makefile ]] && \
+				   [[ ! -r /usr/lib/modules/${this_kernelver}/build/Makefile ]]; then
+					akmods_echo 1 2 "Files needed for building modules against kernel"
+					akmods_echo 1 2 "${this_kernelver} could not be found as the following"
+					akmods_echo 1 2 "directories are missing:" 
+					akmods_echo 1 2 "/usr/src/kernels/${this_kernelver}/"
+					akmods_echo 1 2 -n "/usr/lib/modules/${this_kernelver}/build/"
+					akmods_echo 1 2 -n "Is the correct kernel-devel package installed?"
+					akmods_echo 1 2 --failure
+					return 1
+				fi
+			fi
+
+			local this_kmodverrel="$(rpm -qp --qf '%{VERSION}-%{RELEASE}' "${akmods_kmodfile}" | sed 's!\.\(fc\|lvn\)[0-9]*!!g' )"
+			if [[ ! "${alwaystry}" ]] && [[ -e "/var/cache/akmods/${this_kmodname}/${this_kmodverrel}-for-${this_kernelver}".failed.log ]]; then
+				akmods_echo 1 2 -n "Ignoring ${this_kmodname}-kmod as it failed earlier"
+				akmods_echo 1 2 --warning
+				local someignored="true"
+			else
+				akmods_echo 1 2 -n "Building and installing ${this_kmodname}-kmod"
+			 	buildinstall_kmod ${this_kernelver} ${this_kmodname} ${akmods_kmodfile} ${this_kmodverrel}
+                                local returncode=$?
+				if [[ "$returncode" == "0" ]]; then
+                                	akmods_echo 1 2 --success
+                                elif [[ "$returncode" == "8" ]]; then
+                                        akmods_echo 1 2 --failure "New kmod RPM was built but could not be installed."
+				else
+					local somefailed="true"
+				fi
+			fi
+		fi
+	done
+
+	if [[ "${continue_line}" ]]; then
+		akmods_echo 1 2 --success
+	elif [[ "${someignored}" ]] || [[ "${somefailed}" ]] ; then
+		echo
+		akmods_echo 1 2 "Hint: Some kmods were ignored or failed to build or install."
+		akmods_echo 1 2 "You can try to rebuild and install them by by calling"
+		akmods_echo 1 2 "'/usr/sbin/akmods --force' as root."
+		echo
+		sleep 2
+	fi
+
+}
+
+myprog_help ()
+{
+	echo "Checks the akmod packages and rebuilds them if needed"
+	echo $'\n'"Usage: ${myprog} [OPTIONS]"
+	echo $'\n'"Options:"
+	echo " --force             -- try all, even if they failed earlier"
+	echo " --kernels <kernel>  -- build and install only for kernel <kernel>"
+	echo "                        (formatted the same as 'uname -r' would produce)"
+	echo " --akmod <akmod>     -- build and install only akmod <akmod>"
+}
+
+
+# first parse command line options
+while [ "${1}" ] ; do
+	case "${1}" in
+		--kernel|--kernels)
+			shift
+			if [[ ! "${1}" ]] ; then
+				echo "ERROR: Please provide the kernel-version to build for together with --kernel" >&2
+				exit 1
+			elif [[ ! -r /usr/src/kernels/"${1}"/Makefile ]] && \
+			     [[ ! -r /usr/lib/modules/${1}/build/Makefile ]]; then
+				echo "Could not find files needed to compile modules for ${1}"
+				echo "Are the development files for kernel ${1} or the appropriate kernel-devel package installed?"
+				exit 1
+			elif [[ -r /usr/src/kernels/"${1}"/Makefile ]] && \
+			     [[ ! -r /boot/vmlinuz-"${1}" ]]; then
+				# this is a red hat / fedora kernel-devel package, but the kernel for it is not installed
+				# kmodtool would add a dep on that kernel when building; thus when we'd try to install the 
+				# rpms we'd run into a missing-dep problem. Thus we prevent that case
+				echo "Kernel ${1} not installed"
+				exit 1
+			fi
+			# overwrites the default:
+			kernels="${kernels}${1}"
+			# an try to build, even if we tried already
+			alwaystry=true
+			shift
+			;;
+		--akmod|--kmod)
+			shift
+			if [[ ! "${1}" ]] ; then
+				echo "ERROR: Please provide a name of a akmod package together with --akmods" >&2
+				exit 1
+			elif [[ -r /usr/src/akmods/"${1}"-kmod.latest ]] ; then 
+				akmods="${akmods}${1} "
+			elif [[ -r /usr/src/akmods/"${1}".latest ]] ; then 
+				akmods="${akmods}${1%%-kmod} "
+			else
+				echo "Could not find akmod ${1}"
+				exit 1
+			fi
+			shift
+			;;
+		--force)
+			alwaystry=true
+			shift
+			;;
+		--from-init)
+			# just in case: remove stale lockfile if it exists:
+			rm -f /var/cache/akmods/.lockfile
+			shift
+			;;
+		--from-posttrans|--from-kernel-posttrans|--from-akmod-posttrans)
+			# ignored
+			shift
+			;;
+		--verbose)
+			let verboselevel++
+			shift
+			;;
+		--quiet)
+			let verboselevel--
+			shift
+			;;
+		--help)
+			myprog_help
+			exit 0
+			;;
+		--version)
+			echo "${myprog} ${myver}"
+			exit 0
+			;;
+		*)
+			echo "Error: Unknown option '${1}'." >&2
+			myprog_help >&2
+			exit 2
+			;;
+	esac
+done
+
+# sanity checks
+init
+
+# go
+for kernel in ${kernels} ; do
+	check_kmods ${kernel}
+done
+
+# finished :)
+finally 0
diff --git a/akmods-shutdown b/akmods-shutdown
new file mode 100755
index 0000000..9bdd41d
--- /dev/null
+++ b/akmods-shutdown
@@ -0,0 +1,31 @@
+#!/bin/bash
+#
+# akmods-shutdown - Helper script to build kernel modules on shutdown
+# Copyright (c) 2012 Richard shaw <hobbes1069 at gmail.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+echo "Building modules for all installed kernels."
+for kernel in /usr/src/kernels/*; do
+	kernel=$(basename $kernel)
+	/usr/sbin/akmods --force --kernels $kernel
+done
+
diff --git a/akmods-shutdown.service b/akmods-shutdown.service
new file mode 100644
index 0000000..7fcccc1
--- /dev/null
+++ b/akmods-shutdown.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Builds and install new kmods from akmod packages
+Before=shutdown.service reboot.service halt.service
+Conflicts=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/bin/true
+ExecStop=-/usr/sbin/akmods-shutdown
+TimeoutStopSec=5min
+
+[Install]
+WantedBy=multi-user.target
diff --git a/akmods.h2m b/akmods.h2m
new file mode 100644
index 0000000..22f3e55
--- /dev/null
+++ b/akmods.h2m
@@ -0,0 +1,12 @@
+[BUGS]
+https://bugzilla.rpmfusion.org/buglist.cgi?product=Fedora&component=akmods&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED
+[REPORTING BUGS]
+Submit a bug against the akmods component at:
+.br
+https://bugzilla.rpmfusion.org/enter_bug.cgi?product=Fedora
+[AUTHOR]
+Thorsten Leemhuis <fedora [AT] leemhuis [DOT] info>
+[MAINTAINER]
+Richard Shaw <hobbes1069 [AT] gmail [DOT] com>
+[SEE ALSO]
+http://rpmfusion.org/Packaging/KernelModules/Akmods
diff --git a/akmods.service.in b/akmods.service.in
new file mode 100644
index 0000000..ad82fee
--- /dev/null
+++ b/akmods.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=Builds and install new kmods from akmod packages
+Before=@SERVICE@
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/sbin/akmods --from-init
+
+[Install]
+WantedBy=multi-user.target
diff --git a/akmods.spec b/akmods.spec
index 753b774..b4f2319 100644
--- a/akmods.spec
+++ b/akmods.spec
@@ -6,7 +6,16 @@ Summary:        Automatic kmods build and install tool
 License:        MIT
 URL:            http://rpmfusion.org/Packaging/KernelModules/Akmods
 
-Source0:        https://github.com/hobbes1069/%{name}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
+Source0:        95-akmods.preset
+Source1:        akmods
+Source2:        akmodsbuild
+Source3:        akmods.h2m
+Source4:        akmodsinit
+Source5:        akmodsposttrans
+Source6:        akmods.service.in
+Source7:        akmods-shutdown
+Source8:        akmods-shutdown.service
+Source9:        README
 
 BuildArch:      noarch
 
@@ -46,7 +55,7 @@ after they were installed.
 
 
 %prep
-%setup -q
+echo Nothing to setup.
 
 
 %build
@@ -60,24 +69,28 @@ mkdir -p %{buildroot}%{_usrsrc}/akmods \
          %{buildroot}%{_unitdir} \
          %{buildroot}%{_localstatedir}/cache/akmods \
          %{buildroot}%{_prefix}/lib/systemd/system-preset
-install -pm 0755 akmods %{buildroot}%{_sbindir}/
-install -pm 0755 akmodsbuild %{buildroot}%{_sbindir}/
-install -pm 0755 akmods-shutdown %{buildroot}%{_sbindir}/
-install -pm 0755 akmodsposttrans %{buildroot}%{_sysconfdir}/kernel/postinst.d/
-install -pm 0644 akmods-shutdown.service %{buildroot}%{_unitdir}/
+install -pm 0755 %{SOURCE1} %{buildroot}%{_sbindir}/
+install -pm 0755 %{SOURCE2} %{buildroot}%{_sbindir}/
+install -pm 0755 %{SOURCE7} %{buildroot}%{_sbindir}/
+install -pm 0755 %{SOURCE5} %{buildroot}%{_sysconfdir}/kernel/postinst.d/
+install -pm 0644 %{SOURCE8} %{buildroot}%{_unitdir}/
 
-sed "s|@SERVICE@|display-manager.service|" akmods.service.in >\
+sed "s|@SERVICE@|display-manager.service|" %{SOURCE6} >\
     %{buildroot}%{_unitdir}/akmods.service
 
-install -pm 0644 95-akmods.preset %{buildroot}%{_prefix}/lib/systemd/system-preset/
+install -pm 0644 %{SOURCE0} %{buildroot}%{_prefix}/lib/systemd/system-preset/
 
 # Generate and install man pages.
 mkdir -p %{buildroot}%{_mandir}/man1
-help2man -N -i akmods.h2m -s 1 \
+help2man -N -i %{SOURCE3} -s 1 \
     -o %{buildroot}%{_mandir}/man1/akmods.1 akmods
-help2man -N -i akmods.h2m -s 1 \
+help2man -N -i %{SOURCE3} -s 1 \
     -o %{buildroot}%{_mandir}/man1/akmodsbuild.1 akmodsbuild
 
+# Install README
+mkdir -p %{buildroot}%{_docdir}/%{name}
+install -pm 0644 %{SOURCE9} %{buildroot}%{_docdir}/%{name}/
+
 
 %pre
 # create group and user
@@ -99,7 +112,8 @@ useradd -r -g akmods -d /var/cache/akmods/ -s /sbin/nologin \
 %systemd_postun akmods-shutdown.service
 
 
-%files 
+%files
+%doc %{_docdir}/%{name}/README
 %{_sbindir}/akmodsbuild
 %{_sbindir}/akmods-shutdown
 %{_sbindir}/akmods
diff --git a/akmodsbuild b/akmodsbuild
new file mode 100755
index 0000000..8cc18a9
--- /dev/null
+++ b/akmodsbuild
@@ -0,0 +1,358 @@
+#!/bin/bash
+#
+# akmodbuild - Helper script for building kernel module SRPMs
+# Copyright (c) 2007 Thorsten Leemhuis <fedora at leemhuis.info>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+myprog="akmodsbuild"
+myver="0.5.6"
+
+# defaults that might get overwritten by user:
+kernels="$(uname -r)"
+target="$(uname -m)"
+if [[ "${target}" == "armv7l" ]]; then
+  target="armv7hl"
+fi
+numberofjobs=$(grep -c processor /proc/cpuinfo 2> /dev/null)
+verboselevel=2
+outputdir="${PWD}"
+srpms=
+
+init ()
+{
+	## startup checks
+	# prevent root-usage
+	if [[ -w / ]]; then
+		echo "ERROR: Not to be used as root; start as user or '${myprog}' instead." >&2
+		exit 1 
+	fi
+
+	# do we have everything we need to build for the kernels in question?
+	for kernel in ${kernels}; do
+		if [[ ! -e /usr/src/kernels/${kernel}/Makefile ]] && [[ ! -e /usr/lib/modules/${kernel}/build/Makefile ]]; then
+			echo "ERROR: Files needed for building modules against kernel" >&2
+			echo " ${kernel} could not be found as the following" >&2
+			echo " directories are missing:"
+			echo " /usr/src/kernels/${kernel}/" >&2
+			echo " /usr/lib/modules/${kernel}/build/" >&2
+			exit 2
+		fi
+	done
+
+	if [[ ! "${srpms}" ]]; then
+			echo "ERROR: Please provide a list of SRPM-files to build."
+			exit 2
+	fi
+
+	# SRPMS available?
+	for srpm in ${srpms}; do
+		if [[ ! -r ${srpm} ]]; then
+			echo "ERROR: Can't find SRPM ${srpm}"
+			exit 1
+		fi
+	done
+
+	# room to save things
+	if [[ ! -d "${outputdir}" ]]; then
+		echo "ERROR: ${outputdir} is not a directory" >&2
+		exit 1
+	elif [[ ! -w "${outputdir}" ]]; then
+		echo "ERROR: ${outputdir} is not a writable" >&2
+		exit 1
+	fi
+
+
+	# make sure this is a number
+	if ! (( ${numberofjobs} > 0 )); then
+		echo "Warning: using hardcoded defaut value for number of jobs"
+		numberofjobs=2
+	fi
+
+	## preparations
+	# tmpdir
+	if ! tmpdir="$(mktemp -d -p /tmp ${myprog}.XXXXXXXX)" ; then 
+			echo "ERROR: Could create tempdir."
+			exit 1
+	fi
+
+	# buildtreee
+	mkdir "${tmpdir}"/{BUILD,SOURCES,SPECS,SRPMS,RPMS,RPMS/"${target}"}
+
+	# logfile
+	if [[ ! "${logfile}" ]] ; then
+		logfile="${tmpdir}/logfile"
+	fi
+
+	if ( [[ -e "${logfile}" ]] && [[ ! -w "${logfile}" ]] ) || ! touch "${logfile}" ; then
+			echo "ERROR: Could not write logfile."
+			finally
+			exit 1
+	fi
+}
+
+
+finally()
+{
+	# kill background jobs if needed
+	if [[ "${watch_jobid}" ]]; then
+		kill "${watch_jobid}"
+	fi
+	if [[ "${rpmbuild_jobid}" ]]; then
+		kill "${rpmbuild_jobid}"
+	fi
+
+	# remove tmpfiles
+	if [[ -d "${tmpdir}" ]]; then
+		rm -rf "${tmpdir}"
+	fi
+}
+trap "finally" 2
+
+
+akmods_echo()
+{
+	# where to output
+	local this_fd=${1}
+	shift
+
+	# verboselevel
+	local this_verbose=${1}
+	shift
+
+	if [[ "${1}" == "--not-logfile" ]]; then
+		local notlogfile=true
+		shift
+	fi
+
+	# output to console
+	if (( ${verboselevel} >= ${this_verbose} )) ; then
+		echo "$@" >&${this_fd}
+	fi
+
+	# global logfile
+	if [[ ! ${notlogfile} ]]; then
+		echo "$@" >> "${logfile}"
+	fi
+}
+
+
+watch_rpmbuild()
+{
+	# background function to show rpmbuild progress
+	# does't use akmods_echo here; this stage handles the output on its own
+	# (seperate process and there is no need to log this)
+	if (( ${verboselevel} == 2 )); then
+		tail --pid ${1} -n +1 -s 0.1 -f ${2} 2>/dev/null | grep --line-buffered -e '%prep' -e '%build' -e '%install' -e '%clean' |  while read line; do
+			if [[ "${line}" != "${line##*prep}" ]]; then
+				echo -n "prep "
+			elif [[ "${line}" != "${line##*build}" ]]; then
+				echo -n "build "
+			elif [[ "${line}" != "${line##*install}" ]]; then
+				echo -n "install "
+			elif [[ "${line}" != "${line##*clean}" ]]; then
+				echo -n "clean; "
+				# last linefeed is done by the caller
+			fi
+		done
+	elif (( ${verboselevel} > 2 )); then
+		tail --pid ${1} -n +1 -s 0.1 -f ${2}
+	fi
+}
+
+process_srpm()
+{
+	local source_rpm="${1}"
+
+	# status info
+	akmods_echo 1 2 -n "* Rebuilding ${source_rpm} for kernel(s) ${kernels}: "
+
+	# kick off rebuild into background
+	/usr/bin/time --format='%x' --output="${tmpdir}/.jobexit" rpmbuild \
+		--define "_topdir     ${tmpdir}/" \
+		--define "_buildtree  ${tmpdir}/BUILD" \
+		--define "_specdir    ${tmpdir}/SPECS" \
+		--define "_sourcedir  ${tmpdir}/SOURCES" \
+		--define "_srcrpmdir  ${tmpdir}/SRPMS" \
+		--define "_rpmdir     ${tmpdir}/RPMS" \
+		--define "_smp_mflags -j${numberofjobs}" \
+		--define "kernels     ${kernels}" \
+		--target ${target} \
+		--rebuild "${source_rpm}" 2>&1 | tee -a "${logfile}" > "${tmpdir}/.joblog"  &
+
+	local rpmbuild_jobid=$!
+
+	# show progress
+	if (( ${verboselevel} >= 2 )); then
+		watch_rpmbuild ${rpmbuild_jobid} "${tmpdir}/.joblog" 2> /dev/null &
+		local watch_jobid=$!
+	fi
+
+	# wait for rpmbuild
+	wait ${rpmbuild_jobid}
+	local rpmbuild_returncode=$(tail -n 1 "${tmpdir}/.jobexit")
+	unset rpmbuild_jobid
+
+	# give watch_rpmbuild a moment to catch up; kill it if it does not
+	if (( ${verboselevel} >= 2 )); then
+		sleep 0.5
+		kill ${watch_jobid} &> /dev/null
+		unset watch_jobid
+	fi
+
+	# did rpmbuild succeed?
+	if (( ${rpmbuild_returncode} != 0 )); then
+		# linefeed:
+		akmods_echo 1 2 ""
+
+		akmods_echo 2 2 --not-logfile "rpmbuild failed with errorcode ${rpmbuild_returncode}; last 35 Lines of log:"
+		akmods_echo 2 2 --not-logfile "--- "
+		tail -n 35 "${tmpdir}/.joblog" >&2
+		akmods_echo 2 2  --not-logfile "---"
+		return ${rpmbuild_returncode}
+	fi
+
+	# finish status for watch_rpmbuild
+	if (( ${verboselevel} >= 2 )); then
+		akmods_echo 1 2 -n "Successfull; "
+	fi
+
+	local rpms_built="$(cd "${tmpdir}"/RPMS/"${target}" ; echo *)"
+
+	if ! mv "${tmpdir}/RPMS/${target}/"* "${outputdir}" ; then
+		# linefeed:
+		akmods_echo 1 2 ""
+
+		akmods_echo 2 2 "Failed to move ${tmpdir}/RPMS/${target}/"* "to ${outputdir}"
+		return 128
+	fi
+
+	if (( ${verboselevel} == 1 )); then
+		for rpm in ${rpms_built}; do
+			echo "${outputdir%%/}/${rpm}"
+		done
+	elif (( ${verboselevel} >= 2 )); then
+		akmods_echo 1 2  "Saved ${rpms_built} in ${outputdir%%/}/"
+	fi
+
+
+	# finished
+	return 0
+}
+
+myprog_help ()
+{
+	echo "Rebuilds kmod SRPM(s)"
+	echo $'\n'"Usage: ${myprog} [OPTIONS] <SRPMS>"
+	echo $'\n'"Options:"
+	echo " -k, --kernels         -- build for kernel-versions (output from 'uname -r')"
+	echo " -l, --logfile <file>  -- save rpmduild output to <file>"
+	echo " -o, --outputdir <dir> -- save rpms and logs here (current directory)"
+	echo " -t, --target          -- target-arch (output from 'uname -m')"
+	echo " -v, --verbose         -- increase verboseness"
+	echo " -q, --quiet           -- be more quiet"
+	echo " -h, --help            -- show usage"
+	echo " -V, --version         -- show version"
+}
+
+while [ "${1}" ] ; do
+	case "${1}" in
+		-k|--kernels)
+			shift
+			if [[ ! "${1}" ]] ; then
+				echo "ERROR: Please provide kernel-version(s) to build for together with --kernel" >&2
+				exit 1
+			fi
+			kernels="${1}"
+			shift
+			;;
+		-l|--logfile)
+			shift
+			if [[ ! "${1}" ]]; then
+				echo "ERROR: Please provide a filename together with --logfile" >&2
+				exit 1
+			fi
+			logfile="${1}"
+			shift
+			;;
+		-o|--outputdir)
+			shift
+			if [[ ! "${1}" ]]; then
+				echo "ERROR: Please provide the output directory together with --outputdir" >&2
+				exit 1
+			fi
+			outputdir="${1}"
+			shift
+			;;
+		-t|--target)
+			shift
+			if [[ ! "${1}" ]] ; then
+				echo "ERROR: Please provide the target-arch together with --target" >&2
+				exit 1
+			fi
+			target="${1}"
+			shift
+			;;
+		-v|--verbose)
+			let verboselevel++
+			shift
+			;;
+		-q|--quiet)
+			let verboselevel--
+			shift
+			;;
+		-h|--help)
+			myprog_help
+			exit 0
+			;;
+		-V|--version)
+			echo "${myprog} ${myver}"
+			exit 0
+			;;
+		--*)
+			echo "Error: Unknown option '${1}'." >&2
+			myprog_help >&2
+			exit 2
+			;;
+		*)
+			srpms="${srpms} ${1}"
+			shift
+			;;
+	esac
+done
+
+# sanity checks
+init
+
+# go
+for srpm in ${srpms}; do
+	process_srpm ${srpm}
+	returncode=$?
+
+	if (( ${returncode} != 0 )); then
+		finally
+		exit ${returncode}
+	fi
+done
+
+# finished
+finally
+
+exit 0
diff --git a/akmodsinit b/akmodsinit
new file mode 100755
index 0000000..8489151
--- /dev/null
+++ b/akmodsinit
@@ -0,0 +1,47 @@
+#!/bin/bash -
+#
+# akmodinit     Builds and install new kmods from akmod packages
+#
+# Author:       Thorsten Leemhuis <fedora at leemhuis.info>
+#
+# chkconfig:    2345 5 95
+#
+# description:  akmodsinit calls akmod during system boot to build and install
+#               kmods for the currently running kernel if neccessary.
+#
+# processname:  akmodsd
+# pidfile:      /var/run/akmodsd.pid
+#
+
+### BEGIN INIT INFO
+# Provides: akmodsd
+# Required-Start: $local_fs
+# Required-Stop: $local_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Builds and install new kmods from akmod packages
+# Description: akmodsinit calls akmod during system boot to build and install
+#              kmods for the currently running kernel if neccessary.
+### END INIT INFO
+
+start_akmods ()
+{
+	# build and install all kmods if neccessary
+	# for the currently running kernel (default in akmods)
+	/usr/sbin/akmods --from-init
+}
+
+
+# See how we were called.
+case "$1" in
+	start|restart|reload|condrestart)
+		start_akmods
+		;;
+	stop|status)
+		exit 0
+		;;
+	*)
+		echo $"Usage: $0 start"
+		exit 1
+		;;
+esac
diff --git a/akmodsposttrans b/akmodsposttrans
new file mode 100755
index 0000000..c619952
--- /dev/null
+++ b/akmodsposttrans
@@ -0,0 +1,37 @@
+#!/bin/bash -
+#
+# akmodposttrans - Calls akmods for newly installed kernels
+#
+# Copyright (c) 2009 Thorsten Leemhuis <fedora at leemhuis.info>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# todo-list:
+# - scary idea: install kernel-devel packages on demand?
+# - redirect output to a seperate logfile?
+
+# just check in case a user calls this directly
+if [[ ! -w / ]]; then
+	echo "Needs to run as root to be able to install rpms." >&2
+	exit 1
+fi
+
+# needs to run in background as rpmdb might be locked otherwise
+nohup /usr/sbin/akmods --from-kernel-posttrans --kernels ${1} &> /dev/null &
diff --git a/sources b/sources
index 4645603..e69de29 100644
--- a/sources
+++ b/sources
@@ -1 +0,0 @@
-00e5559bf73a4a0ddb2d328a44e623e3  akmods-0.5.6.tar.gz


More information about the rpmfusion-commits mailing list