diff options
| author | Jonathan Bauer | 2020-05-25 11:26:54 +0200 |
|---|---|---|
| committer | Jonathan Bauer | 2020-05-25 11:26:54 +0200 |
| commit | 8b36285c9ec75ee9fa59f44b0714b952b574190f (patch) | |
| tree | 3d4e51530e54e3d7643e47f2bd4e550be0de07f0 | |
| parent | build-initramfs.sh: support CentOS-7 again (diff) | |
| parent | Merge branch 'master' into nobash-merge (diff) | |
| download | systemd-init-8b36285c9ec75ee9fa59f44b0714b952b574190f.tar.gz systemd-init-8b36285c9ec75ee9fa59f44b0714b952b574190f.tar.xz systemd-init-8b36285c9ec75ee9fa59f44b0714b952b574190f.zip | |
Merge branch 'nobash-merge' into downloader-nobash-merge
28 files changed, 307 insertions, 332 deletions
diff --git a/build-initramfs.sh b/build-initramfs.sh index 2b31f55b..3ff67f6e 100755 --- a/build-initramfs.sh +++ b/build-initramfs.sh @@ -418,8 +418,10 @@ main() { exit 1 fi echo " * kernel headers: $kernel_headers" - [ -n "$qcow_handler" ] && echo " * qcow2 handler: $qcow_handler" - export _QCOW_HANDLER="$qcow_handler" + if [ -n "$qcow_handler" ]; then + echo " * qcow2 handler: $qcow_handler" + export qcow_handler + fi if [ "$update" = "yes" ]; then pushd "${_repo_dir}" diff --git a/modules.d/conf-tgz/hooks/fetch-config-tgz.sh b/modules.d/conf-tgz/hooks/fetch-config-tgz.sh index 1c8ace61..26e705b2 100755 --- a/modules.d/conf-tgz/hooks/fetch-config-tgz.sh +++ b/modules.d/conf-tgz/hooks/fetch-config-tgz.sh @@ -3,27 +3,25 @@ type emergency_shell >/dev/null 2>&1 || source /lib/dracut-lib.sh +. /etc/openslx - slx_server="$(getarg slxsrv=)" - slx_server_base="$(getarg slxbase=)" +if [ -z "$SLX_NO_CONFIG_TGZ" ]; then + # build config.tgz url from SLX_KCL_SERVERS and SLX_BASE_PATH + # both are written to /etc/openslx by dnbd3-rootfs's fetch-config.sh script + conftgz_url="http://${SLX_KCL_SERVERS}/${SLX_BASE_PATH}/config.tgz" - if [ -z "$SLX_NO_CONFIG_TGZ" ]; then - # build config.tgz url - conftgz_url="http://${slx_server#@}/${slx_server_base}/config.tgz" - - # check if system's uuid was set - if [ -s "/run/system-uuid" ]; then - uuid="$(cat /run/system-uuid)" - if [ -n "$uuid" ]; then - conftgz_url="${conftgz_url}?uuid=${uuid}" - fi + # check if system's uuid was set + if [ -s "/run/system-uuid" ]; then + uuid="$(cat /run/system-uuid)" + if [ -n "$uuid" ]; then + conftgz_url="${conftgz_url}?uuid=${uuid}" fi - info "Download config.tgz from '$conftgz_url'..." - slx-tools download_retry -s "${conftgz_url}" > "/etc/config.tgz" + fi + info "Download config.tgz from '$conftgz_url'..." + slx-tools download_retry -s "${conftgz_url}" > "/etc/config.tgz" - if [[ ! -s "/etc/config.tgz" ]]; then - warn \ - "Downloading 'config.tgz' from '${slx_server}' failed with: $return_code" - # TODO handle error - fi + if [[ ! -s "/etc/config.tgz" ]]; then + warn "Failed to download '${conftgz_url}'!" fi +fi +: diff --git a/modules.d/conf-tgz/hooks/unpack-config-tgz.sh b/modules.d/conf-tgz/hooks/unpack-config-tgz.sh index a0da0cd3..71b3ca1e 100755 --- a/modules.d/conf-tgz/hooks/unpack-config-tgz.sh +++ b/modules.d/conf-tgz/hooks/unpack-config-tgz.sh @@ -14,28 +14,36 @@ tarcopy() { cd - &>/dev/null } -# this module unpacks the config.tgz -temporary_extract_directory="$(mktemp -d)" - if [[ -e "/etc/config.tgz" ]]; then - tar --extract --preserve-permissions \ - --file="/etc/config.tgz" \ - --directory="$temporary_extract_directory" +unpack_config_tgz() { + local config_tgz="/etc/config.tgz" + [ -e "$config_tgz" ] || return 1 + local extract_dir="$(mktemp -d)" + tar --extract --preserve-permissions \ + --file="/etc/config.tgz" \ + --directory="$extract_dir" + if [ "$?" -ne 0 ]; then + warn "Failed to extract '$config_tgz' to '$extract_dir'." + return 1 fi - warn "Failed to extract '/etc/config.tgz' to '$temporary_extract_directory'." - warn "$exceptions_last_traceback" -# extracted to temporary directory, now check for SLX_LOCAL_CONFIGURATION - -source "/etc/openslx" -if [[ -n "$SLX_LOCAL_CONFIGURATION" ]]; then - if [[ ! -d "${temporary_extract_directory}/openslx-configs/${SLX_LOCAL_CONFIGURATION}" ]]; then - warn "SLX_LOCAL_CONFIGURATION is set but no corresponding folder found in '/etc/config.tgz'. Ignoring..." - else - tarcopy "${temporary_extract_directory}/openslx-configs/${SLX_LOCAL_CONFIGURATION}" "${temporary_extract_directory}" + # check SLX_LOCAL_CONFIGURATION + source "/etc/openslx" + if [ -n "$SLX_LOCAL_CONFIGURATION" ]; then + if [ ! -d "${extract_dir}/openslx-configs/${SLX_LOCAL_CONFIGURATION}" ]; then + warn "Ignoring missing SLX_LOCAL_CONFIGURATION in '/etc/config.tgz'." + else + tarcopy \ + "${extract_dir}/openslx-configs/${SLX_LOCAL_CONFIGURATION}" \ + "${extract_dir}" + fi fi -fi - # purge openslx-configs/ - rm -rf "${temporary_extract_directory}/openslx-configs" - tarcopy "${temporary_extract_directory}" "$NEWROOT" + # always purge openslx-configs/ + rm -rf "${extract_dir}/openslx-configs" + # finally copy the rest into stage4 + if ! tarcopy "${extract_dir}" "$NEWROOT"; then + warn "'tarcopy' from '$extract_dir' to '$NEWROOT' failed." + fi +} - # TODO error handling +unpack_config_tgz +: diff --git a/modules.d/dnbd3-rootfs/helper/build.inc b/modules.d/dnbd3-rootfs/helper/build.inc index b3f9561c..2816440a 100644 --- a/modules.d/dnbd3-rootfs/helper/build.inc +++ b/modules.d/dnbd3-rootfs/helper/build.inc @@ -4,13 +4,9 @@ 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() { - local qcow_handler="$_QCOW_HANDLER" - IFS='|' _pattern="^(${_supported_qcow_handlers[*]})$" export _pattern - if [[ ! "$qcow_handler" =~ $_pattern ]] ; then - echo "Unknown qcow handler '$qcow_handler' - will built all known." - echo "Supported handlers: ${_supported_qcow_handlers[*]}" - fi _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 <kernel_version> @@ -23,7 +19,15 @@ build_initialize_components() { return 1 fi fi - # take care of the qcow handler + + # process qcow handler + echo "Supported handlers: ${_supported_qcow_handlers[*]}" + IFS='|' _pattern="^(${_supported_qcow_handlers[*]})$" export _pattern + if [ -z "$qcow_handler" ]; then + echo "No qcow handler specified, will use xmount." + elif [[ ! "$qcow_handler" =~ $_pattern ]] ; then + echo "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 echo "Could not find xmount binary, building it..." @@ -40,7 +44,7 @@ build_initialize_components() { fi fi fi - if [ -z "$qcow_handler" ] || [ "$qcow_handler" = "kernel" ]; then + 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 diff --git a/modules.d/dnbd3-rootfs/hooks/copy-dracut-systemd-files-into-newroot.sh b/modules.d/dnbd3-rootfs/hooks/copy-dracut-systemd-files-into-newroot.sh index 5de1f2e9..aca83b8e 100755 --- a/modules.d/dnbd3-rootfs/hooks/copy-dracut-systemd-files-into-newroot.sh +++ b/modules.d/dnbd3-rootfs/hooks/copy-dracut-systemd-files-into-newroot.sh @@ -30,6 +30,6 @@ do # "ln" returns an error if the link already exists. source_path="../${file}" target_path="${new_systemd_system_unit_path}/initrd.target.wants/${file}" - ln --symbolic "$source_path" "$targetPath" &>/dev/null || \ + ln --symbolic "$source_path" "$target_path" &>/dev/null || \ warn "Failed to link \"$source_path\" to \"$target_path\"." done diff --git a/modules.d/dnbd3-rootfs/hooks/fetch-config.sh b/modules.d/dnbd3-rootfs/hooks/fetch-config.sh index a11332a7..2fa1c78c 100755 --- a/modules.d/dnbd3-rootfs/hooks/fetch-config.sh +++ b/modules.d/dnbd3-rootfs/hooks/fetch-config.sh @@ -7,6 +7,20 @@ type emergency_shell >/dev/null 2>&1 || source /lib/dracut-lib.sh slx_server="$(getarg slxsrv=)" slx_server_base="$(getarg slxbase=)" +# if no slxsrv was specified, use the server the kernel was +# downloaded from as fallback. Mostly for legacy PXE boot. +if [ -z "$slx_server" ]; then + slx_server="$(getarg BOOT_IMAGE= | awk -F[/:] '{print $4}')" +fi +if [ -z "$slx_server" ]; then + # use tftp server from ip parameter + slx_server="$(getarg ip= | awk -F: '{print $2}' )" +fi +if [ -z "$slx_server" ]; then + # we have a problem :/ + emergency_shell "Failed to determine SLX server to fetch config from." +fi + # build config_url config_url="http://${slx_server#@}/${slx_server_base}/config" diff --git a/modules.d/dnbd3-rootfs/hooks/prepare-root-partition.sh b/modules.d/dnbd3-rootfs/hooks/prepare-root-partition.sh index aa782184..38a2dd72 100755 --- a/modules.d/dnbd3-rootfs/hooks/prepare-root-partition.sh +++ b/modules.d/dnbd3-rootfs/hooks/prepare-root-partition.sh @@ -46,7 +46,27 @@ container_unpack_losetup() { } # endregion -( +# region connect dnbd3 image +# Determine stage4 image path and revision +if [ -z "$SLX_DNBD3_IMAGE" ]; then + # specified on the KCL? + SLX_DNBD3_IMAGE="$(getarg slx.stage4.path=)" +fi +if [ -z "$SLX_DNBD3_IMAGE" ]; then + # not specified, fall back to old bwlp default path convention + SLX_DNBD3_IMAGE="stage4/bwlp/maxilinux-$(uname -r)" +fi +# save it for later +echo "SLX_DNBD3_IMAGE='$SLX_DNBD3_IMAGE'" >> /etc/openslx +if [ -z "$SLX_DNBD3_RID" ]; then + # specified on the KCL? + SLX_DNBD3_RID="$(getarg slx.stage4.rid=)" +fi +if [ -n "$SLX_DNBD3_RID" ]; then + _dnbd3_client_additional_args=("--rid" "$SLX_DNBD3_RID") + echo "SLX_DNBD3_RID='$SLX_DNBD3_RID'" >> /etc/openslx +fi + IFS=", " for host in ${SLX_DNBD3_SERVERS} FAIL; do if [ "$host" = "FAIL" ]; then @@ -59,11 +79,11 @@ for host in ${SLX_DNBD3_SERVERS} FAIL; do --host "$host" \ --image "${SLX_DNBD3_IMAGE}" \ --device "$_dnbd3_dev" \ - ${SLX_DNBD3_RID:+--rid "$SLX_DNBD3_RID"}; then + "${_dnbd3_client_additional_args[@]}"; then break fi done -) + # endregion # region unpack dnbd3 image [ -z "$SLX_QCOW_HANDLER" ] && SLX_QCOW_HANDLER="xmount" @@ -76,19 +96,19 @@ else fi # Fail fast if unpacking dnbd3 image failed. -[ -z "$read_only_device" ] && exit 1 +if [ -z "$read_only_device" ]; then + emergency_shell "Failed to unpack the qcow2 image!" +fi # endregion # region find system partition within dnbd3 image if [ -z "$SLX_SYSTEM_PARTITION_PREPARATION_SCRIPT" ]; then if [ -z "$SLX_SYSTEM_PARTITION_IDENTIFIER" ]; then - # if empty use whole device - read_only_partition="$read_only_device" - true - else - read_only_partition="$(slx-tools dev_find_partitions \ - "$read_only_device" "$SLX_SYSTEM_PARTITION_IDENTIFIER")" + SLX_SYSTEM_PARTITION_IDENTIFIER="SLX_SYS" + echo "SLX_SYSTEM_PARTITION_IDENTIFIER='$SLX_SYSTEM_PARTITION_IDENTIFIER'" >> /etc/openslx fi + read_only_partition="$(slx-tools dev_find_partitions \ + "$read_only_device" "$SLX_SYSTEM_PARTITION_IDENTIFIER")" else eval "$SLX_SYSTEM_PARTITION_PREPARATION_SCRIPT" fi diff --git a/modules.d/dnbd3-rootfs/module-setup.sh b/modules.d/dnbd3-rootfs/module-setup.sh index 77543a54..01d3c736 100755 --- a/modules.d/dnbd3-rootfs/module-setup.sh +++ b/modules.d/dnbd3-rootfs/module-setup.sh @@ -1,34 +1,7 @@ #!/usr/bin/env bash # -*- coding: utf-8 -*- - _parse_dracut_args() { - local __doc__=' - Set log level via dracut logging options and returns current debug state. - - >>> echo "$_debug" - 1 - >>> _parse_dracut_args; echo $? - 1 - - >>> _parse_dracut_args --stdlog 3; echo $? - - >>> _parse_dracut_args --stdlog 4; echo $? - >>> logging.get_commands_level - >>> logging.get_level - 0 - debug - debug - - >>> logging.get_level - critical - >>> _parse_dracut_args --stdlog 4 --verbose - >>> logging.get_level - debug - - >>> _parse_dracut_args --stdlog 4 --unknown-dracut-option; echo $? - 0 - ' local verbose=false local debug=false while true; do @@ -53,8 +26,6 @@ _parse_dracut_args() { local level $verbose && level=info $debug && level=debug - #logging.set_level "$level" - #logging.set_commands_level debug done $debug return $? @@ -165,7 +136,7 @@ install() { fi # endregion # region hooks - inst_hook cmdline 00 "$moddir/hooks/enable-sysrq.sh" + #inst_hook cmdline 00 "$moddir/hooks/enable-sysrq.sh" # NOTE: Can be used to support old style ip append syntax and have an # exclusive interface name - required when using dracut's regular # 'network' module diff --git a/modules.d/slx-addons/module-setup.sh b/modules.d/slx-addons/module-setup.sh index 296b3fe4..d75b38ad 100755 --- a/modules.d/slx-addons/module-setup.sh +++ b/modules.d/slx-addons/module-setup.sh @@ -9,4 +9,6 @@ depends() { } install() { inst_hook pre-pivot 30 "$moddir/scripts/setup-addons.sh" + inst "${moddir}/services/ldconfig.service" \ + "/opt/openslx/services/ldconfig.service" } diff --git a/modules.d/slx-addons/scripts/setup-addons.sh b/modules.d/slx-addons/scripts/setup-addons.sh index 94c2c444..d4b94a1a 100644 --- a/modules.d/slx-addons/scripts/setup-addons.sh +++ b/modules.d/slx-addons/scripts/setup-addons.sh @@ -33,44 +33,40 @@ if [ ! -d "$NEWROOT/opt/openslx/addons" ]; then return 0 fi -setup_addons() { - local ADDONS_DIR="$NEWROOT/opt/openslx/addons/" - cd "$ADDONS_DIR" || return 1 - for ADDON in *; do - if ! setup_addon "$ADDON"; then - info "Failed to setup $ADDON" - fi - done +# This just activates the ldconfig service to run during the sysinit target +# Since addons are likely to install libs, this is necessary to garantee +# that the live system "sees" the libraries. +activate_stage4_ldconfig() { + local service_path="/opt/openslx/services/ldconfig.service" + [ -e "$service_path" ] || return 1 + local target_dir="${NEWROOT}/etc/systemd/system/sysinit.target.wants" + mkdir -p "$target_dir" + cp -f "$service_path" "${NEWROOT}/etc/systemd/system/${service_path##*/}" + ln -sf "../${service_path##*/}" "${target_dir}/${service_path##*/}" } setup_addon() { - [ -z "$1" -o ! -d "$ADDONS_DIR/$1" ] && return 1 - local ADDON="$1" - cd "$ADDONS_DIR/$ADDON" || return 1 - + if [ ! -d "$1" ]; then + warn "Given '$1' not a directory, skipping." + return 1 + fi + local addon_dir="$1" + cd "$addon_dir" if ! bash addon-required 2>&1 ; then - info "'$ADDONS_DIR/$ADDON/addon-required' missing or returned non-zero, skipping..." + info "'$addon_dir/addon-required' missing or returned non-zero, skipping..." return 1 fi + # purge addon-* files + rm -f -- addon-* - for entry in $(find * -not -wholename "addon-*" 2>/dev/null); do - if [ -d "$entry" ]; then - [ -d "/$entry" ] || mkdir -p "/${entry}" - continue - fi - local dir=${entry%/*} - [ -d "$NEWROOT/$dir" ] || mkdir -p "$NEWROOT/$dir" - if [ -f "$entry" -a ! -L "$entry" ]; then - if [ ! -e "$NEWROOT/${entry}" ] || ! diff -q "$entry" "$NEWROOT/${entry}"; then - mv -f -- "$entry" "$NEWROOT/${entry}" - fi - else - # either block dev, char dev or a symlink, just overwrite them "blindly" - mv -f -- "$entry" "$NEWROOT/${entry}" - fi + # move all the files over + for entry in $(find * -not -type d 2>/dev/null); do + [ "$entry" != "${entry%/*}" ] && mkdir -p "${NEWROOT}/${entry%/*}" + mv -f -- "$entry" "${NEWROOT}/${entry}" done - # post merge: remove whiteouts from filesystem + # post merge: remove files marked as whiteouts + # (e.g. they were removed during the addon installation) for WHITEOUT in "$NEWROOT/opt/openslx/etc/"*.whiteout; do [ -e "$WHITEOUT" ] || continue while read line; do @@ -78,28 +74,29 @@ setup_addon() { done < "$WHITEOUT" done - # finally update ld.so.cache expected to be under /opt/openslx/etc/<addon_name>.ld.so.cache - # NOTE: if we have more than one addon in the future, we need to be extra - # careful with prebuilt ld.caches since they need to match *ALL* addons - local ADDON_LD_CACHE="$NEWROOT/opt/openslx/etc/$ADDON.ld.so.cache" - if [ ! -e "$ADDON_LD_CACHE" ] || ! mv -f -- "$ADDON_LD_CACHE" "$NEWROOT/etc/ld.so.cache" ; then - # Using prebuilt ld cache failed, try hard to find a ldconfig... - for LDCONFIG in "$(type -p ldconfig 2>/dev/null)" "${NEWROOT}/sbin/ldconfig.real"; do - if [ -x "$LDCONFIG" ] && "$LDCONFIG" -r "$NEWROOT"; then - return 0 - fi - done - # try with chroot if we have it - local CHROOT_PATH="$(type -p chroot 2>/dev/null)" - if [ -x "$CHROOT_PATH" ] && "$CHROOT_PATH" "$NEWROOT" ldconfig; then - return 0 - fi - # very bad indeed, libraries won't be registered in the cache ... - warn "Failed to find 'ldconfig' to rebuild the addon's missing ld.so.cache..." - return 1 - fi + cd - &>/dev/null } -if ! setup_addons; then - warn "Failed to fully setup some addons! They will likely malfunction..." +active=() +for addon in "${NEWROOT}/opt/openslx/addons/"*; do + if setup_addon "$addon"; then + active+=("${addon#${NEWROOT}/opt/openslx/addons/}") + info "Activated '$addon' (@ $(date +%s))" + fi +done + +# if only one addon was installed, use its pre-generated ld.so.cache +# if more than one were installed, make sure ldconfig is called in stage4 +if [ "${#active[@]}" -eq 1 ]; then + addon_cache="${NEWROOT}/opt/openslx/etc/${active[0]}.ld.so.cache" + if [ -e "$addon_cache" ]; then + info "Using ld.so.cache of '${active[0]}'." + mv -f -- "${NEWROOT}/etc/ld.so.cache"{,.stage4} + mv -f -- "$addon_cache" "${NEWROOT}/etc/ld.so.cache" + fi +elif [ "${#active[@]}" -gt 1 ]; then + info "Activating ldconfig in stage4 due to multiple loaded addons: ${active[@]}" + activate_stage4_ldconfig fi + +: diff --git a/modules.d/slx-addons/services/ldconfig.service b/modules.d/slx-addons/services/ldconfig.service new file mode 100644 index 00000000..be799e66 --- /dev/null +++ b/modules.d/slx-addons/services/ldconfig.service @@ -0,0 +1,8 @@ +[Unit] +Description=Run ldconfig +Before=graphical.target +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/sbin/ldconfig diff --git a/modules.d/slx-clock/module-setup.sh b/modules.d/slx-clock/module-setup.sh index 0c21b032..8fdbbef6 100755 --- a/modules.d/slx-clock/module-setup.sh +++ b/modules.d/slx-clock/module-setup.sh @@ -17,4 +17,5 @@ install() { inst_multiple ntpdate /etc/services /usr/share/zoneinfo/Europe/Berlin inst /usr/share/zoneinfo/Europe/Berlin /etc/localtime inst_hook pre-mount 15 "$moddir/scripts/ntp-sync.sh" + inst_hook pre-pivot 15 "$moddir/scripts/configure-timesyncd.sh" } diff --git a/modules.d/slx-clock/scripts/configure-timesyncd.sh b/modules.d/slx-clock/scripts/configure-timesyncd.sh new file mode 100644 index 00000000..af1148eb --- /dev/null +++ b/modules.d/slx-clock/scripts/configure-timesyncd.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +. /etc/openslx + +if [ -n "$SLX_NTP_SERVER" ]; then + tsdir="${NEWROOT}/etc/systemd/timesyncd.conf.d" + mkdir -p "$tsdir" + ( + echo "[Time]" + echo "NTP=$SLX_NTP_SERVER" + ) > "${tsdir}/slx-ntp.conf" +fi diff --git a/modules.d/slx-dmsetup/module-setup.sh b/modules.d/slx-dmsetup/module-setup.sh index 68e9b7b4..dff4e34b 100755 --- a/modules.d/slx-dmsetup/module-setup.sh +++ b/modules.d/slx-dmsetup/module-setup.sh @@ -11,14 +11,15 @@ install() { inst_hook pre-pivot 10 "$moddir/scripts/generate-fstab-swap.sh" inst_hook pre-pivot 00 "$moddir/scripts/grow-rootfs.sh" # deliberatly left ext helpers out for now, since we don't really use it. - inst_multiple blockdev xxd \ + inst_multiple blockdev fallocate xxd \ mkfs.ext4 resize2fs \ + mkfs.xfs \ xfs_repair xfs_growfs } installkernel() { # install those modules in case the used kernel does not have them builtin instmods \ - dm-thin-pool dm-snapshot \ + dm-thin-pool dm-snapshot dm-zero \ dm-crypt crc32c xts \ xfs ext4 } diff --git a/modules.d/slx-dmsetup/scripts/dmsetup-slx-device b/modules.d/slx-dmsetup/scripts/dmsetup-slx-device index 36dfef10..6ee810c4 100755 --- a/modules.d/slx-dmsetup/scripts/dmsetup-slx-device +++ b/modules.d/slx-dmsetup/scripts/dmsetup-slx-device @@ -24,8 +24,8 @@ exec &> /run/openslx/dmsetup.log # read-only device to prepare for CoW [ -z "$1" ] && emergency_shell "Read-only device was not given!" -declare -rg read_only_device="$1" -declare -rg read_only_device_size="$(blockdev --getsz $1)" +declare -g read_only_device="$1" +declare -g read_only_device_size="$(blockdev --getsz $1)" # global array variables storing the configuration of the partitions declare -ag linear snapshot thin_snapshot thin_volume @@ -95,7 +95,7 @@ parse_config() { dmsetup_create_noudevsync() { ( set -o errexit - dmsetup create "$1" --noudevsync --table "$2" + printf "%s\n" "$2" | dmsetup create "$1" --noudevsync dmsetup mknodes --noudevsync "$1" ) local ret=$? @@ -129,24 +129,63 @@ create_snapshot() { return 0 } -# Call this to fallback to a RAMdisk stored under /run/openslx -# This will call terminate the whole script by calling finish_setup, if successful +# This function is called if no ID44 partition could be found or anoother kind +# of critical error occurs during the CoW layer setup. It will combine the +# the read-only device with a DM zero device to increase its virtual size +# by half the RAM size. A sparse file of that size will then be created and +# placed on a dedicated tmpfs. ramdisk_fallback() { echo "$0: Falling back to regular dm-snapshot on a RAMdisk." - local file="$(mktemp -u -p /run/openslx dnbd_cow.XXX)" - local size="$SLX_RAMDISK_SIZE_IN_MB" - [ -z "$size" ] && size="$(awk '/MemTotal/ {printf("%d\n", $2 / 2 / 1024 )}' /proc/meminfo)" - dd of="$file" seek="$size" bs=1M count=0 &> /dev/null - writable_device="$(losetup --show --find "$file")" - cow_device_candidate="root" + + # RAM size in kb, note that this is equal to half + # of the entire RAM in 512-bytes sectors. + local ram_size_in_kb="$(awk '/MemTotal/ {printf("%d\n", $2 )}' /proc/meminfo)" + + # try to prepare the zero extension device + local extended_device="/dev/mapper/${read_only_device##*/}-extended" + ( + set -e + lsmod | grep -q dm-zero || modprobe dm-zero + dmsetup_create_noudevsync zero "0 $ram_size_in_kb zero" + dmsetup_create_noudevsync "${extended_device##*/}" \ + "0 $read_only_device_size linear $read_only_device 0 + $read_only_device_size $ram_size_in_kb linear /dev/mapper/zero 0" + ) + if [ "$?" -eq 0 ]; then + read_only_device="$extended_device" + read_only_device_size="$(( read_only_device_size + ram_size_in_kb ))" + else + echo "$0: Failed to setup the fake larger '$read_only_device'." + echo "$0: Continuing with its original size." + fi + + # prepare dedicated tmpfs mount point + local cow_tmpfs="/run/openslx/cow" + if ! mkdir -p "$cow_tmpfs"; then + cow_tmpfs="${cow_tmpfs}.$$" + if ! mkdir -p "$cow_tmpfs"; then + # ultimate fallback on regular /run/openslx + cow_tmpfs="/run/openslx" + fi + fi + if ! mount -t tmpfs cow-tmpfs -o size="$(( read_only_device_size / 2 ))k" "$cow_tmpfs"; then + echo "$0: Failed to mount tmpfs in '$cow_tmpfs' of size '$(( read_only_device_size / 2 ))'." + fi + + # create sparse file there + local file="$(mktemp -u -p "$cow_tmpfs" dnbd_cow.XXX)" + if ! dd of="$file" seek="$(( read_only_device_size / 2 ))" bs=1k count=0 &> /dev/null; then + emergency_shell "Failed to allocate CoW file $file." + fi + declare -rg writable_device="$(losetup --show --find "$file")" + local cow_device_candidate="root" while [ -b "/dev/mapper/$cow_device_candidate" ]; do cow_device_candidate="root.$RANDOM" done if [ -z "$writable_device" ] || ! create_snapshot "$cow_device_candidate N"; then emergency_shell "CRITICAL: failed to setup RAMdisk fallback." - exit 1 fi - finish_setup "$cow_device_candidate" "0" "$size" + finish_setup "$cow_device_candidate" "0" "$read_only_device_size" } # finish_setup <device> <type> [<size>] @@ -200,9 +239,15 @@ save_partition_info() { . /etc/openslx # This is the main variable driving this script declare -g writable_device= +if [ -z "$SLX_WRITABLE_DEVICE_IDENTIFIER" ]; then + SLX_WRITABLE_DEVICE_IDENTIFIER=("44" "87f86132-ff94-4987-b250-444444444444") + # TODO make scripts reading this variable compatible with list of IDs + echo "SLX_WRITABLE_DEVICE_IDENTIFIER='${SLX_WRITABLE_DEVICE_IDENTIFIER[0]}'" >> /etc/openslx + echo "SLX_WRITABLE_DEVICE_IDENTIFIERS='${SLX_WRITABLE_DEVICE_IDENTIFIER[@]}'" >> /etc/openslx +fi if [ -n "$SLX_WRITABLE_DEVICE_IDENTIFIER" ]; then # only first one for now TODO create linear devices of all ID44s - writable_device="$(slx-tools dev_find_partitions "$SLX_WRITABLE_DEVICE_IDENTIFIER" | head -n 1)" + writable_device="$(slx-tools dev_find_partitions "${SLX_WRITABLE_DEVICE_IDENTIFIER[@]}" | head -n 1)" fi if [ -z "$writable_device" ]; then echo "$0: Could not find writable device with id '$SLX_WRITABLE_DEVICE_IDENTIFIER'." diff --git a/modules.d/slx-dmsetup/scripts/gen-fstab-persistent b/modules.d/slx-dmsetup/scripts/gen-fstab-persistent deleted file mode 100644 index ed00b5de..00000000 --- a/modules.d/slx-dmsetup/scripts/gen-fstab-persistent +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash -# -# Hook to generate stage4's fstab entries for persistent partitions -# -# Persistent identifiers (MBR types, GPT partition labels) -# are expected to be specified in the OpenSLX config -# as 'SLX_PERSISTENT_DEVICE_IDENTIFIER' and their filesystem -# as 'SLX_PERSISTENT_DEVICE_FILESYSTEM', e.g ext4 or xfs. -# If not specified, will default to 'auto' but will not -# active systemd's features 'x-systemd.makefs' and 'x-systemd.growfs' - -. /etc/openslx - -type -p emergency_shell >/dev/null 2>&1 || source /lib/dracut-lib.sh - -# NOTE: systemd makes the mount point path automatically. -# if multiple exists, take the biggest one (first in the list) -if [ -n "$SLX_PERSISTENT_DEVICE_IDENTIFIER" ]; then - declare -a persistent_dev_list - for persistent_dev in \ - $(get_partitions_by_id ${SLX_PERSISTENT_DEVICE_IDENTIFIER//,/ /}); do - [ -z "$persistent_dev" ] && continue - persistent_dev_list+=("$persistent_dev") - done - if [ "${#persistent_dev[@]}" -gt 0 ]; then - if [ "${#persistent_dev[@]}" -gt 1 ]; then - warn "$0: More than one persistent device found." - warn "$0: Will use the biggest one: ${persistent_dev[0]}" - fi - persistent_dev_systemd_name="$( tr '/' '-' <<< ${persistent_dev[0]:1})" - persistent_mount_opts="nofail" - if [ -n "$SLX_PERSISTENT_DEVICE_FILESYSTEM" ]; then - #persistent_mount_opts+=",x-systemd.requires=ensure-fs@${persistent_dev_systemd_name}" - persistent_mount_opts+=",x-systemd.after=ensure-fs@${persistent_dev_systemd_name}" - fi - ( - echo -ne "${persistent_dev[0]}\t" - echo -ne "${SLX_PERSISTENT_DEVICE_MOUNT_POINT:-/opt/openslx/persistent}\t" - echo -ne "${SLX_PERSISTENT_DEVICE_FILESYSTEM:-auto}\t" - echo -ne "${persistent_mount_opts}\t0\t2" - ) >> "$NEWROOT/etc/fstab" - - # drop-in to create filesystem if needed and - #persistent_dev_systemd_name="$( tr '/' '-' <<< ${persistent_dev[0]:1})" - #mkdir -p "$NEWROOT/etc/systemd/system/${persistent_dev_systemd_name}" - #cat <<- EOF > "$NEWROOT" - #EOF - else - warn "$0: No device with ID '$SLX_PERSISTENT_DEVICE_IDENTIFIER' found." - fi -fi -true diff --git a/modules.d/slx-dmsetup/scripts/generate-fstab-persistent.sh b/modules.d/slx-dmsetup/scripts/generate-fstab-persistent.sh deleted file mode 100644 index 5c6f2b82..00000000 --- a/modules.d/slx-dmsetup/scripts/generate-fstab-persistent.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash -# -# Hook to generate stage4's fstab entries for persistent partitions -# -# Persistent identifiers (MBR types, GPT partition labels) -# are expected to be specified in the OpenSLX config -# as 'SLX_PERSISTENT_DEVICE_IDENTIFIER' and their filesystem -# as 'SLX_PERSISTENT_DEVICE_FILESYSTEM', e.g ext4 or xfs. -# If not specified, will default to 'auto' but will not -# active systemd's features 'x-systemd.makefs' and 'x-systemd.growfs' - -. /etc/openslx - -type -p emergency_shell >/dev/null 2>&1 || source /lib/dracut-lib.sh - -# NOTE: systemd makes the mount point path automatically. -# if multiple exists, take the biggest one (first in the list) -if [ -n "$SLX_PERSISTENT_DEVICE_IDENTIFIER" ]; then - declare -a persistent_dev_list - for persistent_dev in \ - $(get-partitions-by-id ${SLX_PERSISTENT_DEVICE_IDENTIFIER//,/ /}); do - [ -z "$persistent_dev" ] && continue - persistent_dev_list+=("$persistent_dev") - done - if [ "${#persistent_dev[@]}" -gt 0 ]; then - if [ "${#persistent_dev[@]}" -gt 1 ]; then - warn "$0: More than one persistent device found." - warn "$0: Will use the biggest one: ${persistent_dev[0]}" - fi - persistent_dev_systemd_name="$( tr '/' '-' <<< ${persistent_dev[0]:1})" - persistent_mount_opts="nofail" - if [ -n "$SLX_PERSISTENT_DEVICE_FILESYSTEM" ]; then - #persistent_mount_opts+=",x-systemd.requires=ensure-fs@${persistent_dev_systemd_name}" - persistent_mount_opts+=",x-systemd.after=ensure-fs@${persistent_dev_systemd_name}" - fi - ( - echo -ne "${persistent_dev[0]}\t" - echo -ne "${SLX_PERSISTENT_DEVICE_MOUNT_POINT:-/opt/openslx/persistent}\t" - echo -ne "${SLX_PERSISTENT_DEVICE_FILESYSTEM:-auto}\t" - echo -ne "${persistent_mount_opts}\t0\t2" - ) >> "$NEWROOT/etc/fstab" - - # drop-in to create filesystem if needed and - #persistent_dev_systemd_name="$( tr '/' '-' <<< ${persistent_dev[0]:1})" - #mkdir -p "$NEWROOT/etc/systemd/system/${persistent_dev_systemd_name}" - #cat <<- EOF > "$NEWROOT" - #EOF - else - warn "$0: No device with ID '$SLX_PERSISTENT_DEVICE_IDENTIFIER' found." - fi -fi -true diff --git a/modules.d/slx-dmsetup/scripts/get-partitions-by-id b/modules.d/slx-dmsetup/scripts/get-partitions-by-id deleted file mode 100755 index 2fe5ce7a..00000000 --- a/modules.d/slx-dmsetup/scripts/get-partitions-by-id +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash -# -# Get all partitions with given ids (list of /dev/sdXX) -# Examples of supported ID types: -# * MBR's type: 44 -# * GPT's UUID: 0657fd6d-a4ab-43c4-84e5-0933c84b4f4f (swap) -# * GPT's Name: OpenSLX-ID44 -# -# First argument can be a block device to limit the search to -# partitions thereof, e.g. for /dev/loop0 to look for /dev/loop0pX -# -# NOTE: for compatibility reasons, MBR's type will also -# be matched against part name 'OpenSLX-ID<id>'. -# The output will be a list of matching devices, -# sorted from largest to smallest. -get_partitions_by_id () { - local ID dev exp target - exp= - # target for the scan, defaults to /dev to check everything - target=/dev - if [ -b "$1" ]; then - target="$1"'*' - shift - fi - # support commas and pipes to separate identifiers - local args=$@ - set -- ${args//[,|]/ } - while [ $# -gt 0 ]; do - ID=$1 - shift - [ -z "$ID" ] && continue - # if single digit, e.g. 7, look for 0x7 and 0x07 - [[ $ID =~ ^[0-9]$ ]] && ID="0?$ID" - if [[ $ID =~ ^[0-9]{2}$ ]]; then - # if double digit look for MBR types and OpenSLX-ID$ID GPT labels - exp="$exp|ID_PART_ENTRY_(NAME=OpenSLX-ID|TYPE=0x)$ID" - elif [[ $ID =~ ^(0x[0-9]{2}|[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12})$ ]]; then - # if full MBR type (e.g. 0x44) or UUID look for TYPE - exp="$exp|ID_PART_ENTRY_TYPE=$ID" - else - # something else, look for names of partitions / filesystems - exp="$exp|ID_(PART_ENTRY_NAME|FS_LABEL)=$ID" - fi - done - exp=${exp:1} - #echo "Partition find is '$exp'" >&2 - for dev in $(find $target -type b); do - udevadm info --name="$dev" | grep -iqE "($exp)\$" \ - && echo "$(blockdev --getsize64 "$dev") $dev" - done | sort -n -k1 -r | cut -d' ' -f2 -} - -## MAIN -if [ $# -eq 0 ]; then - echo "$0 needs at least one argument." - exit 1 -fi - -get_partitions_by_id $@ - diff --git a/modules.d/slx-network/hooks/activate-bootif-dhcp.sh b/modules.d/slx-network/hooks/activate-bootif-dhcp.sh index f5345c61..86679ce7 100644 --- a/modules.d/slx-network/hooks/activate-bootif-dhcp.sh +++ b/modules.d/slx-network/hooks/activate-bootif-dhcp.sh @@ -4,8 +4,9 @@ # within stage4, unless specifically disabled by SLX_STAGE4_DHCP . /etc/openslx -[ -n "$SLX_STAGE4_DHCP" ] || exit 0 +[ -n "$SLX_DISABLE_STAGE4_DHCP" ] && exit 0 +mkdir -p "${NEWROOT}/opt/openslx/scripts" for script in setup-bootif-network udhcpc-trigger; do if [ -e "${NEWROOT}/opt/openslx/scripts/${script}" ]; then mv "${NEWROOT}/opt/openslx/scripts/${script}"{,.stage4} diff --git a/modules.d/slx-network/scripts/setup-bootif-network.stage3 b/modules.d/slx-network/scripts/setup-bootif-network.stage3 index 53ad8de9..50718894 100755 --- a/modules.d/slx-network/scripts/setup-bootif-network.stage3 +++ b/modules.d/slx-network/scripts/setup-bootif-network.stage3 @@ -88,18 +88,37 @@ if [ -n "$SLX_PXE_CLIENT_IP" ]; then dev "$MAIN_NETIF" fi -if [ "$USE_DHCP_UUID" = "yes" ] && [ -s "/run/system-uuid" ]; then - UUID="$(cat /run/system-uuid)" +additional_opts=() + +# we need to send the same UID (without '-') as the PXE firmware did, so use the plain +# one read with dmidecode (and not the one by get-system-uuid). +if [ "$USE_DHCP_UUID" = "yes" ]; then + UID="$(dmidecode -s system-uuid | sed -r 's/^(..)(..)(..)(..)-(..)(..)-(..)(..)-(....)-/00\4\3\2\1\6\5\8\7\9/')" + if [ "${#UID}" = 34 ]; then + echo "Using SMBIOS UID for DHCP" + additional_opts+=("-x" "0x3d:$UID") + fi +fi + +if [ -n "$SLX_PXE_CLIENT_IP" ]; then + additional_opts+=("-r" "$SLX_PXE_CLIENT_IP") fi +# DHCP options to request +request_opts=("-O" "hostname") +request_opts+=("-O" "ntpsrv") +request_opts+=("-O" "domain") +request_opts+=("-O" "wpad") +request_opts+=("-O" "search") +request_opts+=("-O" "nisdomain") + # udhcpc for i in 1 1 1 fail; do [ "$i" = "fail" ] && emergency_shell "DHCP failed 3 times... cannot continue." udhcpc -t 4 -T 3 -f -n -q \ -i "${MAIN_NETIF}" \ - "${SLX_PXE_CLIENT_IP:+-r $SLX_PXE_CLIENT_IP}" \ - "${UUID:+-x 0x3d:$UUID}" \ - -O ntpsrv -O domain -O wpad -O search -O nisdomain \ + "${request_opts[@]}" \ + "${additional_opts[@]}" \ -s "/usr/local/bin/udhcpc-trigger" # success? [ "$?" -eq 0 ] && break @@ -110,3 +129,5 @@ done set +x } &>> "/run/openslx/initramfs-network.log.$$" + + diff --git a/modules.d/slx-network/scripts/setup-bootif-network.stage4 b/modules.d/slx-network/scripts/setup-bootif-network.stage4 index 61f925d0..4f41dfed 100755 --- a/modules.d/slx-network/scripts/setup-bootif-network.stage4 +++ b/modules.d/slx-network/scripts/setup-bootif-network.stage4 @@ -21,7 +21,10 @@ readonly MAIN_NETIF # set default options declare -a udhcpc_opts +udhcpc_opts+=("-T" "1") +udhcpc_opts+=("-A" "5") udhcpc_opts+=("-t" "8") +udhcpc_opts+=("-O" "hostname") udhcpc_opts+=("-O" "domain") udhcpc_opts+=("-O" "nissrv") udhcpc_opts+=("-O" "nisdomain") diff --git a/modules.d/slx-network/scripts/udhcpc-trigger.stage4 b/modules.d/slx-network/scripts/udhcpc-trigger.stage4 index b4dfeafa..d7009dc6 100755 --- a/modules.d/slx-network/scripts/udhcpc-trigger.stage4 +++ b/modules.d/slx-network/scripts/udhcpc-trigger.stage4 @@ -66,7 +66,11 @@ case "$1" in ip addr add "$ip/$(ipcalc -s -p "$ip" "$subnet" | sed s/.*=//)" dev "$interface" # Set default route, if given if [ -n "$router" ]; then - ip route replace default via "$router" + # Only replace route if it's the same interface as the current default route, or we don't have any + current="$( ip route show | awk '{ if ($1 == "default") {print $5; exit 0}}' )" + if [ -z "$current" ] || [ "$interface" = "$current" ]; then + ip route replace default via "$router" + fi fi # get domain, hostname and thus fqdn from DNS diff --git a/modules.d/slx-network/services/udhcpc-bootif.service b/modules.d/slx-network/services/udhcpc-bootif.service index 21a5de3c..71a721dc 100644 --- a/modules.d/slx-network/services/udhcpc-bootif.service +++ b/modules.d/slx-network/services/udhcpc-bootif.service @@ -1,12 +1,12 @@ [Unit] Description=DHCP Client for the main boot interface -Before=network.target Requires=systemd-tmpfiles-setup.service After=systemd-tmpfiles-setup.service +DefaultDependencies=no [Service] Type=forking ExecStart=/opt/openslx/scripts/setup-bootif-network [Install] -WantedBy=network.target +WantedBy=sysinit.target diff --git a/modules.d/slx-splash/data/splash.ppm.gz b/modules.d/slx-splash/data/splash.ppm.gz Binary files differindex d30d44e2..f524b27b 100644 --- a/modules.d/slx-splash/data/splash.ppm.gz +++ b/modules.d/slx-splash/data/splash.ppm.gz diff --git a/modules.d/slx-splash/module-setup.sh b/modules.d/slx-splash/module-setup.sh index 05542269..29a85648 100755 --- a/modules.d/slx-splash/module-setup.sh +++ b/modules.d/slx-splash/module-setup.sh @@ -10,5 +10,6 @@ depends() { install() { cp "$moddir/data/splash.ppm.gz" "$initdir/etc/splash.ppm.gz" inst_hook pre-trigger 10 "$moddir/scripts/slx-splash.sh" + inst_hook pre-pivot 00 "$moddir/scripts/slx-splash-exam.sh" inst_hook pre-pivot 20 "$moddir/scripts/restore-cursor.sh" } diff --git a/modules.d/slx-splash/scripts/slx-splash-exam.sh b/modules.d/slx-splash/scripts/slx-splash-exam.sh new file mode 100644 index 00000000..b2bf4f53 --- /dev/null +++ b/modules.d/slx-splash/scripts/slx-splash-exam.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +. /etc/openslx + +if [ -n "$SLX_EXAM" ]; then + if [ -e "/etc/splash.ppm.gz" ]; then + systemd-preserve-process-marker /bin/busybox fbsplash -b -s "/etc/splash.ppm.gz" & + elif [ -e "/etc/splash.ppm" ]; then + systemd-preserve-process-marker /bin/busybox fbsplash -b -s "/etc/splash.ppm" & + else + echo "Splash screen requested, but not found in initramfs..." + fi +fi + +: diff --git a/modules.d/slx-uuid/bad-uuid-defaults.conf b/modules.d/slx-uuid/bad-uuid-defaults.conf index aaf59a7d..dab53d07 100644 --- a/modules.d/slx-uuid/bad-uuid-defaults.conf +++ b/modules.d/slx-uuid/bad-uuid-defaults.conf @@ -1,8 +1,10 @@ 00000000-0000-0000-0000-000000000000 +00000000-0000-0000-0000-000000000001 03000200-0400-0500-0006-000700080009 11111111-2222-3333-4444-555555555555 44454C4C-2000-1020-8020-A0C04F202020 4C4C4544-0000-2010-8020-80C04F202020 4C4C4544-0046-3310-805A-B6C04F4B4D31 +58585858-5858-5858-5858-585858585858 A023157C-F692-11DE-977C-7F0F26276F33 FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF diff --git a/modules.d/slx-uuid/module-setup.sh b/modules.d/slx-uuid/module-setup.sh index 569b5155..1e550136 100755 --- a/modules.d/slx-uuid/module-setup.sh +++ b/modules.d/slx-uuid/module-setup.sh @@ -13,7 +13,16 @@ depends() { } install() { mkdir -p "$initdir/etc/bad-uuid.d" - inst_simple "$moddir/bad-uuid-defaults.conf" "/etc/bad-uuid.d/bad-uuid-defaults.conf" + # check if we have an uuid blacklists installed by openslx/mltk on this system + if [ "$(ls -A /opt/openslx/bad-uuid.d)" ]; then + for blacklist in "/opt/openslx/bad-uuid.d"/* ]; do + inst_simple "$blacklist" "/etc/bad-uuid.d/${blacklist##*/}" + done + else + # use this module's default blacklist + inst_simple "$moddir/bad-uuid-defaults.conf" "/etc/bad-uuid.d/bad-uuid-defaults.conf" + fi + inst_multiple dmidecode inst_hook pre-udev 05 "$moddir/scripts/get-system-uuid.sh" inst_hook pre-pivot 10 "$moddir/scripts/copy-system-uuid-to-newroot.sh" |
