#!/usr/bin/env bash # -*- coding: utf-8 -*- # shellcheck source=./rebash/core.sh declare -rg _mainmoddir="$(dirname "${BASH_SOURCE[0]}")/.." 2> /dev/null declare -rg _supported_qcow_handlers=("xmount" "kernel") # NOTE: expects 'qcow_handler' to be set in the environment, else # will only build support for xmount build_initialize_components() { _deps_base_dir="${_mainmoddir}/binaries" # We might want to move the "binaries" repos from the dnbd3-rootfs module to main repo one day... # TODO check for its existence using modinfo -k if [[ ! -f "${_deps_base_dir}/dnbd3/build/dnbd3.ko" ]] || \ [[ ! -f "${_deps_base_dir}/dnbd3/build/dnbd3-client" ]]; then logging.info "Could not find dnbd3, building it..." if ! CMAKE_FLAGS="-DKERNEL_DIR=${kernel_headers}" \ build_compile_dnbd3 "${_deps_base_dir}/dnbd3/"; then logging.error "Failed to build dnbd3." return 1 fi fi # process qcow handler logging.info "Supported handlers: ${_supported_qcow_handlers[*]}" IFS='|' _pattern="^(${_supported_qcow_handlers[*]})$" export _pattern if [ -z "$qcow_handler" ]; then logging.info "No qcow handler specified, will use xmount." elif [[ ! "$qcow_handler" =~ $_pattern ]] ; then logging.warn "Unknown qcow handler '$qcow_handler' - will use xmount" fi if [ -z "$qcow_handler" ] || [ "$qcow_handler" = "xmount" ]; then if [[ ! -f "${_deps_base_dir}/xmount/trunk/build/src/xmount" ]]; then logging.info "Could not find xmount binary, building it..." if ! build_compile_xmount "${_deps_base_dir}/xmount/"; then logging.error "Failed to build xmount binary." return 1 fi fi if [[ ! -f "${_deps_base_dir}/qemu-xmount/libxmount_input_qemu.so" ]]; then logging.info "Could not find xmount qemu library, building it..." if ! build_compile_qemu_xmount "${_deps_base_dir}/qemu-xmount/"; then logging error "Failed to build xmount qemu library." return 1 fi fi fi if [ "$qcow_handler" = "kernel" ]; then if [ ! -f "${_deps_base_dir}/kernel-qcow2-linux/drivers/block/loop/loop.ko" ] \ || [ ! -f "${_deps_base_dir}/kernel-qcow2-linux/drivers/block/loop/loop_file_fmt_qcow.ko" ] \ || [ ! -f "${_deps_base_dir}/kernel-qcow2-linux/drivers/block/loop/loop_file_fmt_raw.ko" ]; then logging.info "Could not find loop kernel modules, building them..." if ! build_compile_kernel_qcow "${_deps_base_dir}/kernel-qcow2-linux"; then logging.error "Failed to build qcow loop kernel modules." return 1 fi fi if [ ! -f "${_deps_base_dir}/kernel-qcow2-util-linux/losetup" ]; then logging.info "Could not find losetup with qcow2 support, building it..." if ! build_compile_losetup_qcow "${_deps_base_dir}/kernel-qcow2-util-linux"; then logging.error "Failed to build losetup with qcow support." return 1 fi fi fi # always compile this helper since it does not cost much to do so if [[ ! -f "${_deps_base_dir}/systemd-preserve-process-marker/systemd-preserve-process-marker" ]]; then logging.info "Could not find systemd-preserve-process-marker binary, building it ..." if ! build_compile_systemd_preserve_process_marker \ "${_deps_base_dir}/systemd-preserve-process-marker/"; then logging.error "Failed to build systemd-preserve-process-marker" return 1 fi fi logging.info "Compilation of dnbd3-rootfs dependencies succeeded." return 0 } clean_components() { local __doc__=' Removes all compiled kernel specific files. NOTE: This method is triggered manually and not supported by dracut itself. Example: `clean` ' local _submoddir="${_mainmoddir}/binaries" build_clean_xmount "${_submoddir}/xmount/" build_clean_qemu_xmount "${_submoddir}/qemu-xmount/" build_clean_dnbd3 "${_submoddir}/dnbd3/" build_clean_losetup_qcow "${_submoddir}/kernel-qcow2-util-linux" build_clean_dnbd3 "${_submoddir}/dnbd3/" build_clean_systemd_preserve_process_marker \ "${_submoddir}/systemd-preserve-process-marker/" return 0 } # endregion build_compile_qemu_xmount() { local __doc__=' Compiles qemu libxmount. NOTE: expects xmount installation under $1/../xmount/trunk/build/release_build/ Provides the following file: "$1/libxmount_input_qemu.so" Example: `build_compile_qemu_xmount /qemu_source /xmount/installation` ' pushd "$1" local xmount_installation="../xmount/trunk/build/release_build/usr" [ ! -z "$2" ] && xmount_installation="$2" ./configure --enable-xmount-input --python="$(which python2)" \ --extra-cflags="-std=gnu99" \ --disable-werror \ --extra-cflags="-fPIC" \ --extra-cflags="-I${xmount_installation}/include" \ --extra-cflags="-I${xmount_installation}/include/xmount" \ --disable-fdt --target-list="" make -j libxmount_input_qemu.so local ret=$? popd return $ret } build_clean_qemu_xmount() { local __doc__='Clean the build of `build_compile_qemu_xmount`.' pushd "$1" make clean local ret=$? popd return $ret } build_compile_xmount() { local __doc__=' Compiles xmount. Provides the xmount installation under: "$1/trunk/build/release_build/" Example: `build_compile_xmount /xmount_source /xmount_source/build /usr` ' pushd "$1" local destination_directory="./release_build" [ ! -z "$2" ] && destination_directory="$2" local install_prefix="/usr" [ ! -z "$3" ] && install_prefix="$3" mkdir --parents trunk/build cd trunk/build || return 1 cmake -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX="$install_prefix" .. make -j make install DESTDIR="$destination_directory" local ret=$? popd return $ret } build_clean_xmount() { local __doc__='Clean the build of `build_compile_xmount`.' rm --recursive --force "$1/trunk/build" } build_compile_dnbd3() { local __doc__=' Compiles dnbd3 kernel module and client. Provides the following file: "$1/build/dnbd3.ko" "$1/build/dnbd3-client" Examples: `build_compile_dnbd3 path/to/dnbd3/source/` Passing the kernel version to cmake: `CMAKE_FLAGS="-DKERNEL_VERSION=4.14.6-openslx+" \ build_compile_dnbd3 path/to/dnbd3/source/` ' pushd "$1" # NOTE: The generic way would be: "./build.sh" but this tries to build # more than we really need and takes more time. mkdir --parents build cd build # Inject CMAKE_FLAGS as a way to control how cmake is called, # e.g. to pass the kernel version cmake ${CMAKE_FLAGS} \ -DBUILD_FUSE_CLIENT=OFF \ -DBUILD_KERNEL_MODULE=ON \ -DBUILD_SERVER=OFF \ -DBUILD_STRESSTEST=OFF \ ../ make -j dnbd3 dnbd3-client local ret=$? popd return $ret } build_clean_dnbd3() { local __doc__='Clean the build of `build_compile_dnbd3`.' rm --recursive --force "$1/build" return $? } build_compile_kernel_qcow() { pushd "$1" # https://lab.ks.uni-freiburg.de/projects/kernel-qcow2/wiki if [ -z "$kernel_headers" ]; then logging.error "Kernel header directory not set, ignoring." return 1 fi mkdir -p "${kernel_headers}/drivers/block/loop" for _file in \ include/uapi/linux/loop.h \ drivers/block/Kconfig \ drivers/block/loop/loop_main.h \ drivers/block/loop/loop_file_fmt.h \ drivers/block/loop/Kconfig; do cp -f "${_file}" "${kernel_headers}/${_file}" done ( set -o errexit make -C "$kernel_headers" CONFIG_BLK_DEV_LOOP=m \ M=$(pwd)/drivers/block/loop loop.ko make -C "$kernel_headers" CONFIG_BLK_DEV_LOOP_FILE_FMT_RAW=m \ M=$(pwd)/drivers/block/loop loop_file_fmt_raw.ko make -C "$kernel_headers" CONFIG_BLK_DEV_LOOP_FILE_FMT_QCOW=m \ M=$(pwd)/drivers/block/loop loop_file_fmt_qcow.ko ) local ret=$? popd return $ret } build_clean_kernel_qcow() { if [ -z "$kernel_headers" ]; then logging.error "Kernel header directory not set, ignoring." return 1 fi pushd "$kernel_headers" make -C "$kernel_headers" M=$(pwd)/drivers/block/loop clean local ret=$? popd return $ret } build_compile_losetup_qcow() { pushd "$1" ( set -o errexit ./autogen.sh ./configure make -j losetup ) local ret=$? popd return $ret } build_clean_losetup_qcow() { pushd "$1" make clean local ret=$? popd return $ret } build_compile_systemd_preserve_process_marker() { local __doc__=' Compiles simple c program. Examples: `build_compile_systemd_preserve_process_marker path/to/program/folder` ' pushd "$1" make local ret=$? popd return $ret } build_clean_systemd_preserve_process_marker() { local __doc__=' Clean the build of `build_compile_systemd_preserve_process_marker`. ' pushd "$1" make clean local ret=$? popd return $ret } # region vim modline # vim: set tabstop=4 shiftwidth=4 expandtab: # vim: foldmethod=marker foldmarker=region,endregion: # endregion