2

I am running PV guests on xen 4.11 with pvgrub. The recent releases of ubuntu (>19.04) look to have switched to lz4 compressed kernels. These kernels work fine with direct boot, but under pvgrub and pvgrub2 they don't seem bootable.

Most recent release of ubuntu focal 20.04. Guest kernel 5.4.0-28.

error: not xen image.                [ vmlinuz-5.4.0-28-gen  10B  0%  0.17B/s ]
error: you need to load the kernel first.

Press any key to continue...

The same setup works with an older kernel (e.g. 4.19)

I notice there was an issue for this patched into xen itself, has anyone got these kernels working with pvgrub?

0
6

Thanks to some advise from Andy on the xen-users mailing list I have a temporary work around. From the sounds of it lz4 just isn't supported yet.

Specific to Ubuntu PV guests I have written the following as an apt hook using extract-vmlinux to decompress kernels during installation. https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux

The hook requires extract-linux somewhere (I used /usr/local/bin) and goes into /etc/kernel/postinst.d/

#!/bin/bash

KERNEL_VERSION="$1"
KERNEL_PATH="$2"

# extract-vmlinux is in /usr/local/bin
PATH="${PATH}:/usr/local/bin"

# Ensure we have the extract-linux tool
if ! command -v extract-vmlinux > /dev/null; then
        echo >&2 "Command 'extract-vmlinux' is not available (https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux),  Aborting"
        exit 1
fi

# The KERNEL_PATH must be valid
if [ ! -f "${KERNEL_PATH}" ]; then
        echo >&2 "Kernel file '${KERNEL_PATH}' not found. Aborting"
        exit 1
fi

# Create a temp file
TEMP_FILE=$(mktemp /tmp/decompress-kernel-XXXXX)
trap "rm -f ${TEMP_FILE}" 0

# If the given kernel file is still a bzimage see if its needs decompression
if echo "$(file -b "${KERNEL_PATH}")" | grep -q "^Linux kernel x86 boot executable bzImage"; then

        # Kernel is probably lz4 if there are lz4 headers in it
        LZ4_HEADER="$(printf '\002!L\030')"
        if ! grep -aqo "${LZ4_HEADER}" ${KERNEL_PATH}; then
                echo "No lz4 compression headers found, skipping..."
                exit 0
        fi

        echo "Decompressing '${KERNEL_PATH}'..."
        # Extract the kernel and replace existing if successful
        if extract-vmlinux ${KERNEL_PATH} > ${TEMP_FILE}; then

                # Double check the kernel is a valid ELF image
                if ! readelf -h ${TEMP_FILE} > /dev/null; then
                        echo >&2 "Decompression of kernel file '${KERNEL_PATH}' failed!, not a valid ELF image"
                        exit 1
                fi

                echo "Decompression of kernel file '${KERNEL_PATH}' successful"
                cp -v ${TEMP_FILE} ${KERNEL_PATH}

        else
                echo >&2 "Decompression of kernel file '${KERNEL_PATH}' failed!"
                exit 1
        fi

# Perhaps its already been decompressed
elif echo "$(file -b "${KERNEL_PATH}")" | grep -q "^ELF 64-bit LSB executable"; then
        echo "Kernel file '${KERNEL_PATH}' appears to be decompressed already. skipping"

else
        echo >&2 "Unable to determine the state of kernel file '${KERNEL_PATH}'"
        exit 1
fi
6
  • Holy smokes, this worked - awesome workaround!
    – timbru31
    May 6 '20 at 22:07
  • 1
    Edited this to use mktemp because the original version would allow any non-root user on the system to overwrite arbitrary files. Also a trap to clean up after itself if it doesn't get as far as 'mv'.
    – grifferz
    May 10 '20 at 20:43
  • 1
    Note that it is possible to check if an image has any LZ4 headers in it before trying this, so you can skip it for those that aren't actually LZ4-compressed: lz4match=$(printf '\002!L\030'); sudo grep -aq "$lz4match" /boot/vmlinuz-5.4.0-29-generic && echo "At least one LZ4 header found"
    – grifferz
    May 10 '20 at 20:46
  • Cheers grifferz someone said the same on the xen-users mailing list. I've updated with both changes.
    – John S
    May 10 '20 at 23:01
  • I've had significant problems using the script extract-vmlinux on a 5.4 kernel from Ubuntu 20.04. The script iterates over pos in try_decompress(), and overwrites the $tmp file in every iteration. For me there where 4 matches for pos but only the first one was valid. I assume changing the > to >> would help, but did not try. Also note that users should have a number of utilities installed, like readelf, lz4, and possibly lzop and others.
    – emmenlau
    Oct 9 '20 at 15:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.