update(scripts): driver loader cycle available gcc versions

The falco-driver-loader script calls dkms to compile the kernel
module using the default gcc.
In some systems, and in the falcosecurity/falco container image,
the defult gcc is not the right one to compile it.

The script will try to compile the module by cycling trough all the available GCCs
starting from the default one until the module is compiled the first
time.

The default gcc is the highest priority while trying.
Newer GCCs have the priority over older GCCs.

Co-Authored-By: Leonardo Di Donato <leodidonato@gmail.com>
Signed-off-by: Lorenzo Fontana <fontanalorenz@gmail.com>
This commit is contained in:
Lorenzo Fontana 2020-09-16 16:14:24 +02:00 committed by poiana
parent 8611af4373
commit 1efa4d3af0

View File

@ -143,33 +143,41 @@ load_kernel_module_compile() {
# skip dkms on UEK hosts because it will always fail # skip dkms on UEK hosts because it will always fail
if [[ $(uname -r) == *uek* ]]; then if [[ $(uname -r) == *uek* ]]; then
echo "* Skipping dkms install for UEK host" echo "* Skipping dkms install for UEK host"
else return
if hash dkms &>/dev/null; then fi
echo "* Trying to dkms install ${DRIVER_NAME} module"
if dkms install -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then if ! hash dkms &>/dev/null; then
echo "* ${DRIVER_NAME} module installed in dkms, trying to insmod" echo "* Skipping dkms install (dkms not found)"
if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then return
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms" fi
exit 0
elif insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1; then # try to compile using all the available gcc versions
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms (xz)" for CURRENT_GCC in $(which gcc) $(ls "$(dirname "$(which gcc)")"/gcc-* | grep 'gcc-[0-9]\+' | sort -r); do
exit 0 echo "* Trying to dkms install ${DRIVER_NAME} module with GCC ${CURRENT_GCC}"
else echo "#!/usr/bin/env bash" > /tmp/falco-dkms-make
echo "* Unable to insmod ${DRIVER_NAME} module" echo "make CC=${CURRENT_GCC} \$@" >> /tmp/falco-dkms-make
fi chmod +x /tmp/falco-dkms-make
if dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
echo "* ${DRIVER_NAME} module installed in dkms, trying to insmod"
if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms"
exit 0
elif insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1; then
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms (xz)"
exit 0
else else
DKMS_LOG="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/build/make.log" echo "* Unable to insmod ${DRIVER_NAME} module"
if [ -f "${DKMS_LOG}" ]; then
echo "* Running dkms build failed, dumping ${DKMS_LOG}"
cat "${DKMS_LOG}"
else
echo "* Running dkms build failed, couldn't find ${DKMS_LOG}"
fi
fi fi
else else
echo "* Skipping dkms install (dkms not found)" DKMS_LOG="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/build/make.log"
if [ -f "${DKMS_LOG}" ]; then
echo "* Running dkms build failed, dumping ${DKMS_LOG} (with GCC ${CURRENT_GCC})"
cat "${DKMS_LOG}"
else
echo "* Running dkms build failed, couldn't find ${DKMS_LOG} (with GCC ${CURRENT_GCC})"
fi
fi fi
fi done
} }
load_kernel_module_download() { load_kernel_module_download() {