From 589a035d85ab1cafc9e0330992291ca5fd8c7f74 Mon Sep 17 00:00:00 2001 From: Olivier MEDOC Date: Mon, 5 Sep 2016 12:51:12 +0200 Subject: [PATCH] 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. --- archlinux/PKGBUILD | 17 ++- .../PKGBUILD-qubes-prepare-vm-kernel.hook | 13 ++ archlinux/PKGBUILD-qubes-prepare-vm-kernel.sh | 141 ++++++++++++------ .../PKGBUILD-qubes-vm-kernel-support.install | 10 +- 4 files changed, 124 insertions(+), 57 deletions(-) create mode 100644 archlinux/PKGBUILD-qubes-prepare-vm-kernel.hook diff --git a/archlinux/PKGBUILD b/archlinux/PKGBUILD index d6c5c4b..838ebd8 100644 --- a/archlinux/PKGBUILD +++ b/archlinux/PKGBUILD @@ -6,7 +6,7 @@ # Maintainer: Olivier Medoc 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 diff --git a/archlinux/PKGBUILD-qubes-prepare-vm-kernel.hook b/archlinux/PKGBUILD-qubes-prepare-vm-kernel.hook new file mode 100644 index 0000000..de8e456 --- /dev/null +++ b/archlinux/PKGBUILD-qubes-prepare-vm-kernel.hook @@ -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 diff --git a/archlinux/PKGBUILD-qubes-prepare-vm-kernel.sh b/archlinux/PKGBUILD-qubes-prepare-vm-kernel.sh index edabc88..9ccc17e 100644 --- a/archlinux/PKGBUILD-qubes-prepare-vm-kernel.sh +++ b/archlinux/PKGBUILD-qubes-prepare-vm-kernel.sh @@ -1,10 +1,12 @@ - #!/bin/sh +#!/bin/sh # # The Qubes OS Project, http://www.qubes-os.org # # Copyright (C) 2015 Marek Marczykowski-Górecki # # +# 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 []" >&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 "$@" diff --git a/archlinux/PKGBUILD-qubes-vm-kernel-support.install b/archlinux/PKGBUILD-qubes-vm-kernel-support.install index 9cf4445..1a2dd0a 100644 --- a/archlinux/PKGBUILD-qubes-vm-kernel-support.install +++ b/archlinux/PKGBUILD-qubes-vm-kernel-support.install @@ -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 }