#!/usr/bin/env bash # region imports source '/usr/lib/rebash/core.sh' core.import '/usr/lib/openslx/tools.sh' core.import exceptions core.import utils core.import logging type emergency_shell >/dev/null 2>&1 || source /lib/dracut-lib.sh # endregion exceptions.try { source /etc/openslx logging.set_commands_level debug logging.set_level debug [[ "$SLX_LOG_FILE_PATH" == "" ]] && SLX_LOG_FILE_PATH=/var/log/openslx logging.set_log_file "$SLX_LOG_FILE_PATH" # region find writable partition if [[ "$SLX_WRITABLE_DEVICE_IDENTIFIER" != '' ]] && ! persistent_device="$( tools.find_block_device "$SLX_WRITABLE_DEVICE_IDENTIFIER" '' \ "$SLX_WRITABLE_DEVICE_IDENTIFIER_TIMEOUT_IN_SECONDS" )" then logging.warn "Failed to find unique device with identifier" \ "\"${SLX_WRITABLE_DEVICE_IDENTIFIER}\"; matched devices:" \ "\"${persistent_device}\"" fi if [ -n "$SLX_WRITABLE_DEVICE_STORAGE_FILE_PATH" ] && [ -n "$persistent_device" ] then persistent_mountpoint=/mnt/slx_writable_device storage_file_path="${persistent_mountpoint}/$SLX_WRITABLE_DEVICE_STORAGE_FILE_PATH" ! mkdir --parents "$(dirname "$storage_file_path")" if ! mount --type auto "$persistent_device" "$persistent_mountpoint"; then logging.warn "Failed to mount $persistent_device, checking filesystem." ! $SLX_WRITABLE_DEVICE_STORAGE_FILESYSTEM_CHECK_COMMAND \ "$persistent_device" if ! mount --type auto "$persistent_device" "$persistent_mountpoint" then logging.warn "Mounting $persistent_device, still failing," \ "creating new filesystem on device" $SLX_WRITABLE_DEVICE_STORAGE_FILESYSTEM_CREATE_COMMAND \ "$persistent_device" fi if ! mount --type auto "$persistent_device" "$persistent_mountpoint" then logging.warn "Mounting $persistent_device, still failing," \ "giving up, and using ramdisk" persistent_device="" fi fi if [ -n "$persistent_device" ]; then if [ ! -e "$storage_file_path" ]; then # Create a sparse file. dd of="$storage_file_path" bs=1M \ seek="$SLX_WRITABLE_DEVICE_STORAGE_MAXIMUM_FILE_SIZE_IN_MB" count=0 fi persistent_device="$(losetup --find)" losetup "$persistent_device" "$storage_file_path" fi fi # "P" for persistent storage, "N" for not persistent (affects dmsetup call, # see scripts/device-add-write-layer.sh) persistent='N' if [ -n "$persistent_device" ]; then writable_device="$persistent_device" if [ "$SLX_WRITABLE_DEVICE_PERSISTENT" = "yes" ]; then persistent='P' fi else ramdisk_size_in_kb="$SLX_RAMDISK_SIZE_IN_KB" if [ "$ramdisk_size_in_kb" = '' ]; then ramdisk_size_in_kb="$(awk '/MemTotal/ {print $2}' /proc/meminfo)" fi # NOTE: If the kernel modul "brd" is compiled into current kernel we can't # configure ram disk size dynamically. In this case it have to be # configured via kernel command line: "brd.rd_size=SITE_IN_KILOBYTE" # statically: #! rmmod brd 2>/dev/null #modprobe brd max_part=1 rd_size="$ramdisk_size_in_kb" #writable_device='/dev/ram0' ramdisk_location="$(mktemp)" dd of="$ramdisk_location" seek="$ramdisk_size_in_kb" count=0 1>/dev/null writable_device="$(losetup --find)" losetup "$writable_device" "$ramdisk_location" fi # endregion # region connect dnbd3 IFS_backup="$IFS" IFS="," return_code=1 for host in ${SLX_DNBD3_SERVERS}; do logging.info "Trying host \"$host\"." if systemd-preserve-process-marker dnbd3-client --host "$host" --image \ "${SLX_DNBD3_IMAGE}" --device "$SLX_DNBD3_DEVICE" \ --rid "$SLX_DNBD3_RID" then return_code=0 break fi done IFS="$IFS_backup" if [[ $return_code != 0 ]]; then logging.warn "Failed to connect \"${SLX_DNBD3_IMAGE}\" (revision" \ "\"$SLX_DNBD3_RID\") from one of \"$SLX_DNBD3_SERVERS\" to" \ "\"$SLX_DNBD3_DEVICE\"." exit 1 fi # endregion # region scan partitions if [ "$SLX_LOG_FILE_PATH" != "" ]; then read_only_device="$(container-unpack-xmount "$SLX_DNBD3_DEVICE" \ 2>>"$SLX_LOG_FILE_PATH")" else read_only_device="$(container-unpack-xmount "$SLX_DNBD3_DEVICE")" fi # Fail fast if no device could be determined. [ -z "$read_only_device" ] && exit 1 # endregion # region find read-only partition 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="$(tools.find_block_device \ "$SLX_SYSTEM_PARTITION_IDENTIFIER" "$read_only_device")" fi else eval "$SLX_SYSTEM_PARTITION_PREPARATION_SCRIPT" fi if [[ ! $? || -z "$read_only_partition" ]]; then logging.error "Failed to find unique device with identifier" \ "\"${SLX_SYSTEM_PARTITION_IDENTIFIER}\"; matched devices:" \ "\"${read_only_partition}\"" exit 1 fi # endregion logging.info "Using read-only partition: $read_only_partition" logging.info "Using writable device $writable_device, persistency: $persistent" # combine devices with device mapper device-add-write-layer "root" "$read_only_partition" "$writable_device" \ "$persistent" } exceptions.catch { logging.error "$exceptions_last_traceback" emergency_shell "error in ${BASH_SOURCE[0]}" } # region vim modline # vim: set tabstop=4 shiftwidth=4 expandtab: # vim: foldmethod=marker foldmarker=region,endregion: # endregion