diff --git a/archlinux/PKGBUILD b/archlinux/PKGBUILD index 05f9b97..d6c5c4b 100644 --- a/archlinux/PKGBUILD +++ b/archlinux/PKGBUILD @@ -4,17 +4,16 @@ # then please put 'unknown'. # Maintainer: Olivier Medoc -pkgname=qubes-vm-utils +pkgname=(qubes-vm-utils qubes-vm-kernel-support) pkgver=`cat version` -pkgrel=3 +pkgrel=5 epoch= pkgdesc="Common Linux files for Qubes VM." arch=("x86_64") url="http://qubes-os.org/" license=('GPL') groups=() -depends=(qubes-libvchan imagemagick python2-cairo) -makedepends=(qubes-libvchan) +makedepends=(gcc make pkgconfig 'qubes-libvchan') checkdepends=() optdepends=() provides=() @@ -22,18 +21,17 @@ conflicts=() replaces=() backup=() options=('staticlibs') -install=PKGBUILD-qubes-vm-utils.install changelog= -source=() +source=(PKGBUILD-initcpio-hook.sh PKGBUILD-initcpio-install.sh PKGBUILD-qubes-prepare-vm-kernel.sh) noextract=() -md5sums=() #generate with 'makepkg -g' +md5sums=(e88b50aed7d28087968da728ec1dc2b6 3d204b0d8acda9cf3ea5ebd5334a04d6 76ffd56b376136d7ee44190a0531a4af) build() { -for source in qrexec-lib udev qmemman core Makefile; do +for source in qrexec-lib udev qmemman core kernel-modules Makefile; do (ln -s $srcdir/../$source $srcdir/$source) done @@ -41,11 +39,31 @@ make all } -package() { +package_qubes-vm-utils() { +depends=(qubes-libvchan imagemagick python2-cairo) +install=PKGBUILD-qubes-vm-utils.install make install DESTDIR=$pkgdir LIBDIR=/usr/lib SYSLIBDIR=/usr/lib SBINDIR=/usr/bin } +package_qubes-vm-kernel-support() { +depends=(qubes-libvchan mkinitcpio dkms grub) +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/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 + +make install-u2mfn DESTDIR=$pkgdir -C kernel-modules + +} + + # vim:set ts=2 sw=2 et: diff --git a/archlinux/PKGBUILD-initcpio-hook.sh b/archlinux/PKGBUILD-initcpio-hook.sh new file mode 100644 index 0000000..738b9dc --- /dev/null +++ b/archlinux/PKGBUILD-initcpio-hook.sh @@ -0,0 +1,51 @@ +#!/usr/bin/ash + +run_earlyhook() { + + msg "Starting Qubes copy on write setup script" + + if ! grep -q 'root=[^ ]*dmroot' /proc/cmdline; then + warning "Qubes: dmroot not requested, probably not a Qubes VM" + exit 0 + fi + + if [ -e /dev/mapper/dmroot ] ; then + die "Qubes: FATAL error: /dev/mapper/dmroot already exists?!" + fi + + modprobe xen-blkfront || warning "Qubes: Cannot load Xen Block Frontend..." + + msg "Qubes: Waiting for /dev/xvda* devices..." + while ! [ -e /dev/xvda ]; do sleep 0.1; done + msg "Qubes: /dev/xvda* found" + + SWAP_SIZE=$(( 1024 * 1024 * 2 )) # sectors, 1GB + + if [ `cat /sys/block/xvda/ro` = 1 ] ; then + msg "Qubes: Doing COW setup for AppVM..." + + while ! [ -e /dev/xvdc ]; do sleep 0.1; done + VOLATILE_SIZE=$(cat /sys/block/xvdc/size) # sectors + ROOT_SIZE=$(cat /sys/block/xvda/size) # sectors + if [ $VOLATILE_SIZE -lt $SWAP_SIZE ]; then + die "Qubes: volatile.img smaller than 1GB, cannot continue" + fi + sfdisk -q --unit S /dev/xvdc >/dev/null < +# +# 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 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + +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 + + mkdir /tmp/qubes-modules-$kver + truncate -s 400M /tmp/qubes-modules-$kver.img + mkfs -t ext3 -F /tmp/qubes-modules-$kver.img > /dev/null + mount /tmp/qubes-modules-$kver.img /tmp/qubes-modules-$kver -o loop + cp -a -t /tmp/qubes-modules-$kver /lib/modules/$kver + umount /tmp/qubes-modules-$kver + rmdir /tmp/qubes-modules-$kver + mv /tmp/qubes-modules-$kver.img $output_file +} + +function build_initramfs() { + kver=$1 + output_file=$2 + + /sbin/dracut --nomdadmconf --nolvmconf --force \ + --modules "kernel-modules qubes-vm-simple" \ + --conf /dev/null --confdir /var/empty \ + -d "xenblk xen-blkfront cdrom ext4 jbd2 crc16 dm_snapshot" \ + $output_file $kver + chmod 644 "$output_file" +} + +function build_initcpio() { + kver=$1 + output_file=$2 + + mkinitcpio -k "$kver" -g "$output_file" -A qubes,lvm2 + + chmod 644 "$output_file" +} + +if [ -z "$1" ]; then + echo "Usage: $0 []" >&2 + exit 1 +fi + +if [ ! -d /lib/modules/$1 ]; then + echo "ERROR: Kernel version $1 not installed" >&2 + exit 1 +fi + +kernel_version=$1 + +if [ -n "$2" ]; then + kernel_code="-linux-$2" +else + kernel_code="-linux" +fi + +if [ -n "$3" ]; then + output_dir="$basedir/$3" +else + output_dir="$basedir/$kernel_version" +fi + +echo "--> Building files for $kernel_version in $output_dir" + +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" + +echo "--> Done." diff --git a/archlinux/PKGBUILD-qubes-vm-kernel-support.install b/archlinux/PKGBUILD-qubes-vm-kernel-support.install new file mode 100644 index 0000000..9cf4445 --- /dev/null +++ b/archlinux/PKGBUILD-qubes-vm-kernel-support.install @@ -0,0 +1,30 @@ + +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 " 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 +} + +post_remove() { + echo "Removing qubes required hooks to mkinitcpio.conf" + sed 's/^HOOKS="lvm2 qubes base/HOOKS="base/' -i /etc/mkinitcpio.conf +} +