archlinux: use pacman hook mechanism to build kernel support

Pacman automatically handle building of u2fmn.ko.

The same mechanism is now used to prepare the kernel
automatically when the kernel is updated.
This commit is contained in:
Olivier MEDOC 2016-09-05 12:51:12 +02:00
parent 0ff9e5a785
commit 589a035d85
4 changed files with 124 additions and 57 deletions

View File

@ -6,7 +6,7 @@
# Maintainer: Olivier Medoc <o_medoc@yahoo.fr>
pkgname=(qubes-vm-utils qubes-vm-kernel-support)
pkgver=`cat version`
pkgrel=5
pkgrel=7
epoch=
pkgdesc="Common Linux files for Qubes VM."
arch=("x86_64")
@ -23,10 +23,19 @@ backup=()
options=('staticlibs')
changelog=
source=(PKGBUILD-initcpio-hook.sh PKGBUILD-initcpio-install.sh PKGBUILD-qubes-prepare-vm-kernel.sh)
source=(PKGBUILD-initcpio-hook.sh
PKGBUILD-initcpio-install.sh
PKGBUILD-qubes-prepare-vm-kernel.sh
PKGBUILD-qubes-prepare-vm-kernel.hook
)
md5sums=(e88b50aed7d28087968da728ec1dc2b6
3d204b0d8acda9cf3ea5ebd5334a04d6
6b33d5cdacf9873d270bf785e3c4f39b
8e0754a613a2fa0a578361455d225b48
)
noextract=()
md5sums=(e88b50aed7d28087968da728ec1dc2b6 3d204b0d8acda9cf3ea5ebd5334a04d6 76ffd56b376136d7ee44190a0531a4af)
build() {
@ -53,12 +62,14 @@ install=PKGBUILD-qubes-vm-kernel-support.install
mkdir -p ${pkgdir}/usr/lib/initcpio/install/
mkdir -p ${pkgdir}/usr/lib/initcpio/hooks/
mkdir -p ${pkgdir}/usr/share/libalpm/hooks/
mkdir -p ${pkgdir}/usr/bin/
ls -la ${pkgdir}/usr/bin
install -m 755 ${srcdir}/PKGBUILD-qubes-prepare-vm-kernel.sh ${pkgdir}/usr/bin/qubes-prepare-vm-kernel
install -m 611 ${srcdir}/PKGBUILD-initcpio-install.sh ${pkgdir}/usr/lib/initcpio/install/qubes
install -m 611 ${srcdir}/PKGBUILD-initcpio-hook.sh ${pkgdir}/usr/lib/initcpio/hooks/qubes
install -m 611 ${srcdir}/PKGBUILD-qubes-prepare-vm-kernel.hook ${pkgdir}/usr/share/libalpm/hooks/80-qubes-prepare-vm-kernel.hook
make install-u2mfn DESTDIR=$pkgdir -C kernel-modules

View File

@ -0,0 +1,13 @@
[Trigger]
Type = File
Operation = Install
Operation = Upgrade
Target = usr/lib/modules/*/
Target = !usr/lib/modules/extramodules-*
Target = !usr/lib/modules/*/?*
[Action]
Description = Building and preparing the Qubes kernel modules...
When = PostTransaction
Exec = /usr/bin/qubes-prepare-vm-kernel
NeedsTargets

View File

@ -1,10 +1,12 @@
#!/bin/sh
#!/bin/sh
#
# The Qubes OS Project, http://www.qubes-os.org
#
# Copyright (C) 2015 Marek Marczykowski-Górecki
# <marmarekp@invisiblethingslab.com>
#
# Copyright © 2016 Sébastien Luttringer
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
@ -25,23 +27,6 @@ set -e
basedir=/var/lib/qubes/vm-kernels
function recompile_u2mfn() {
kver=$1
u2mfn_ver=`dkms status u2mfn|tail -n 1|cut -f 2 -d ' '|tr -d ':,'`
if ! modinfo -k "$kver" -n u2mfn 2>&1 > /dev/null; then
echo "Module u2mfn not available. Checking available source to be built."
u2mfn_ver=`cat /usr/src/u2mfn-*/dkms.conf | grep PACKAGE_VERSION | cut -d "=" -f 2 | tr -d '"' | sort -u | head -n 1`
if [ -z "$u2mfn_ver" ] ; then
echo "No source found for u2mfn. Is qubes-vm-kernel-support installed correctly?"
return 1
else
echo "Found sources for u2mfn version $u2mfn_ver"
fi
dkms install u2mfn/$u2mfn_ver -k $kver --no-initrd
fi
}
function build_modules_img() {
kver=$1
output_file=$2
@ -77,39 +62,101 @@ function build_initcpio() {
chmod 644 "$output_file"
}
if [ -z "$1" ]; then
echo "Usage: $0 <kernel-version> <kernel-name> [<display-kernel-version>]" >&2
exit 1
fi
do_prepare_xen_kernel() {
if [ ! -d /lib/modules/$1 ]; then
echo "ERROR: Kernel version $1 not installed" >&2
exit 1
fi
kernel_version="$1"
kernel_base="$2"
kernel_code="$3"
output_dir="$basedir/$kernel_version"
echo "--> Building files for $kernel_version in $output_dir"
kernel_version=$1
mkdir -p "$output_dir"
cp "/boot/vmlinuz-linux-$kernel_code" "$output_dir/vmlinuz-linux-$kernel_code"
echo "---> Generating modules.img"
build_modules_img "$kernel_version" "$output_dir/modules.img"
echo "---> Generating initramfs"
build_initcpio "$kernel_version" "$output_dir/initramfs-$kernel_code.img"
if [ -n "$2" ]; then
kernel_code="-linux-$2"
else
kernel_code="-linux"
fi
echo "--> Done."
if [ -n "$3" ]; then
output_dir="$basedir/$3"
else
output_dir="$basedir/$kernel_version"
fi
}
echo "--> Building files for $kernel_version in $output_dir"
# display what to run and run it quietly
run() {
echo "==> $*"
"$@" > /dev/null
}
echo "---> Recompiling kernel module (u2mfn)"
recompile_u2mfn "$kernel_version"
mkdir -p "$output_dir"
cp "/boot/vmlinuz$kernel_code" "$output_dir/vmlinuz$kernel_code"
echo "---> Generating modules.img"
build_modules_img "$kernel_version" "$output_dir/modules.img"
echo "---> Generating initramfs"
build_initcpio "$kernel_version" "$output_dir/initramfs$kernel_code.img"
# check kernel is valid for action
# it means kernel and its headers are installed
# $1: kernel version
check_kernel() {
local kver="$1"; shift
echo "Install tree: $install_tree/$kver/kernel"
if [[ ! -d "$install_tree/$kver/kernel" ]]; then
echo "==> No kernel $kver modules. You must install them to use DKMS!"
return 1
elif [[ ! -d "$install_tree/$kver/build/include" ]]; then
echo "==> No kernel $kver headers. You must install them to use DKMS!"
return 1
fi
return 0
}
echo "--> Done."
# handle actions on kernel addition/upgrade/removal
# $1: kernel version
# $*: dkms args
do_kernel() {
local kver="$1"; shift
check_kernel "$kver" || return
# do $@ once for each dkms module in $source_tree
local path
for path in "$install_tree"/"$kver"/extra/u2mfn.ko; do
echo "Preparing kernel for $path"
if [[ "$path" =~ ^$install_tree/([^/]+)-([^/]+)/extra/u2mfn\.ko$ ]]; then
do_prepare_xen_kernel "$kver" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}"
fi
done
}
# emulated program entry point
main() {
# prevent to have all each dkms call to fail
if (( EUID )); then
echo 'You must be root to use this hook' >&2
exit 1
fi
# dkms path from framework config
# note: the alpm hooks which trigger this script use static path
source_tree='/usr/src'
install_tree='/usr/lib/modules'
# check source_tree and install_tree exists
local path
for path in "$source_tree" "$install_tree"; do
if [[ ! -d "$path" ]]; then
echo "==> Missing mandatory directory: $path. Exiting!"
return 1
fi
done
if [ -n "$1" ] ; then
echo $install_tree
if [[ "$1" =~ ^$install_tree/([^/]+)/ ]]; then
do_kernel "${BASH_REMATCH[1]}"
fi
else
# parse stdin paths to guess what do do
while read -r path; do
if [[ "/$path" =~ ^$install_tree/([^/]+)/ ]]; then
do_kernel "${BASH_REMATCH[1]}"
fi
done
fi
return 0
}
main "$@"

View File

@ -3,23 +3,19 @@ help() {
echo "Before using pvgrub, the kernel you want to use needs to be regenerated with Qubes kernel modules in the TemplateVM:"
echo "1/ Ensure that your kernel and kernel sources are installed (ex: pacman -S linux-lts linux-lts-headers)"
echo "2/ Ensure that grub config file has been generated for your kernel (ex: grub-mkconfig > /boot/grub/grub.cfg)"
echo "3/ Run qubes-prepare-vm-kernel helper to compile Qubes-OS kernel modules and rebuild the initcpio"
echo " Usage: qubes-prepare-vm-kernel [your kernel version - found in /usr/lib/modules] [your kernel name - ex: 'linux' for vanilla kernel 'linux-lts' for long term support kernel]"
echo " Manual generation of initcpio:"
echo "3/ Run qubes-prepare-vm-kernel helper to compile Qubes-OS kernel modules and rebuild the initcpio for your kernel"
echo " Usage: qubes-prepare-vm-kernel [your kernel modules path - found in /usr/lib/modules]"
echo " Manual generation of initcpio in case of failure:"
echo " dkms install u2mfn/[u2mfn_version - found in /usr/src/] -k [kernel_version] --no-initrd"
echo " mkinitcpio -k [kernel_version] -p [kernel_name]"
}
## arg 1: the new package version
post_install() {
echo "Adding qubes required hooks to mkinitcpio.conf"
sed 's/^HOOKS="base/HOOKS="lvm2 qubes base/' -i /etc/mkinitcpio.conf
help
}
post_upgrade() {
echo "Adding qubes required hooks to mkinitcpio.conf"
sed 's/^HOOKS="base/HOOKS="lvm2 qubes base/' -i /etc/mkinitcpio.conf
help
}