diff options
| author | Simon Rettberg | 2025-04-09 13:59:49 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2025-04-09 13:59:49 +0200 |
| commit | 7eca62ec51d030e959d52d79c370d789ace5334a (patch) | |
| tree | e97370e2d003261c99f55b1dfadce3336b3141d2 /modules.d | |
| parent | [slx-clock] Try to guess RTC mode and write time back if no mode is specified (diff) | |
| download | systemd-init-7eca62ec51d030e959d52d79c370d789ace5334a.tar.gz systemd-init-7eca62ec51d030e959d52d79c370d789ace5334a.tar.xz systemd-init-7eca62ec51d030e959d52d79c370d789ace5334a.zip | |
[slx-dmsetup] Split dmsetup-slx-device into smaller services
Diffstat (limited to 'modules.d')
| -rwxr-xr-x | modules.d/dnbd3-rootfs/hooks/s3-connect-image.sh (renamed from modules.d/dnbd3-rootfs/hooks/s3-dnbd3root.sh) | 7 | ||||
| -rwxr-xr-x | modules.d/dnbd3-rootfs/module-setup.sh | 2 | ||||
| -rwxr-xr-x | modules.d/slx-dmsetup/bin/dmsetup_create_noudevsync | 25 | ||||
| -rwxr-xr-x | modules.d/slx-dmsetup/hooks/s3-cow-setup.sh (renamed from modules.d/slx-dmsetup/hooks/dmsetup-slx-device) | 227 | ||||
| -rwxr-xr-x | modules.d/slx-dmsetup/hooks/s3-mount-swap.sh | 10 | ||||
| -rwxr-xr-x | modules.d/slx-dmsetup/hooks/s3-prepare-rw-layer.sh | 80 | ||||
| -rwxr-xr-x | modules.d/slx-dmsetup/hooks/s3-scan-id44.sh | 23 | ||||
| -rwxr-xr-x | modules.d/slx-dmsetup/module-setup.sh | 21 | ||||
| -rwxr-xr-x | modules.d/slx-extra-script/module-setup.sh | 3 | ||||
| -rw-r--r-- | modules.d/slx-extra-script/services/s3-extra-post-dmsetup.service | 2 | ||||
| -rwxr-xr-x | modules.d/slx-ntfsfree/hooks/s3-ntfsfree.sh | 30 | ||||
| -rwxr-xr-x | modules.d/slx-ntfsfree/module-setup.sh | 21 |
12 files changed, 246 insertions, 205 deletions
diff --git a/modules.d/dnbd3-rootfs/hooks/s3-dnbd3root.sh b/modules.d/dnbd3-rootfs/hooks/s3-connect-image.sh index e78a007a..835a5613 100755 --- a/modules.d/dnbd3-rootfs/hooks/s3-dnbd3root.sh +++ b/modules.d/dnbd3-rootfs/hooks/s3-connect-image.sh @@ -207,9 +207,8 @@ if ! [ -b "$read_only_partition" ]; then fi echo "Using read-only partition: $read_only_partition" +echo "$read_only_partition" > "/.read_only_device" -# region add rw layer to dnbd3 image -# don't be fooled to think we are done, the next part is crucial -dmsetup-slx-device "$read_only_partition" settle -# endregion + +exit 0 diff --git a/modules.d/dnbd3-rootfs/module-setup.sh b/modules.d/dnbd3-rootfs/module-setup.sh index b8cc10af..67907d10 100755 --- a/modules.d/dnbd3-rootfs/module-setup.sh +++ b/modules.d/dnbd3-rootfs/module-setup.sh @@ -149,7 +149,7 @@ install() { inst_hook cmdline 90 "$moddir/hooks/set-dracut-environment-variables.sh" # make the final blockdevice for the root system (dnbd3 -> xmount -> # device-mapper) - slx_service "s3-dnbd3root" "Setup dnbd3-based block device of rootfs" \ + slx_service "s3-connect-image" "Setup dnbd3-based block device of rootfs" \ --after "s3-fetch-config.service" \ --after "dracut-pre-mount.service" \ --wbefore "dracut-mount.service" \ diff --git a/modules.d/slx-dmsetup/bin/dmsetup_create_noudevsync b/modules.d/slx-dmsetup/bin/dmsetup_create_noudevsync new file mode 100755 index 00000000..ebcf5ed6 --- /dev/null +++ b/modules.d/slx-dmsetup/bin/dmsetup_create_noudevsync @@ -0,0 +1,25 @@ +#!/bin/bash + +# Helper to call 'dmsetup setup' without syncing with udev +# and then actively create the devices with the mknodes command. +# Either pass the table contents as $2, or pipe them into the function +# dmsetup_create_noudevsync <name> [table] +( + set -eo pipefail + if [ -n "$2" ]; then + printf "%s\n" "$2" | dmsetup create "$1" --noudevsync + else + dmsetup create "$1" --noudevsync + fi + dmsetup mknodes --noudevsync "$1" + echo "dm: Created $1" +) +ret=$? + +[ -b "/dev/mapper/$1" ] || ret=99 +if [ $ret -ne 0 ]; then + echo "dm: Error creating $1, removing..." + dmsetup remove --noudevsync "$1" +fi + +exit $ret diff --git a/modules.d/slx-dmsetup/hooks/dmsetup-slx-device b/modules.d/slx-dmsetup/hooks/s3-cow-setup.sh index 05a1b823..75f0c0c4 100755 --- a/modules.d/slx-dmsetup/hooks/dmsetup-slx-device +++ b/modules.d/slx-dmsetup/hooks/s3-cow-setup.sh @@ -28,15 +28,21 @@ exec {BASH_XTRACEFD}> /run/openslx/dmsetup.log set -x # read-only device to prepare for CoW -[ -n "$1" ] || drop_shell "Read-only device was not given!" -[ -b "$1" ] || drop_shell "Given device '$1' does not exist or is not block device" +[ -s "/.read_only_device" ] && read_only_device="$( cat "/.read_only_device" )" +[ -n "$read_only_device" ] || read_only_device="$1" +[ -n "$read_only_device" ] || drop_shell 'Read only device neither given via /.read_only_device nor $1' -declare -g read_only_device="$1" -declare -g read_only_device_sz="$( blockdev --getsz "$1" )" -# Use _sz suffix for sizes expressed in number of 512b sectors, -# _size for random other crap +[ -b "$read_only_device" ] || drop_shell "Given device '$1' does not exist or is not block device" -declare -rg ntfs_list="/run/openslx/.thin-ntfs-candidates" +declare -g read_only_device_sz="$( blockdev --getsz "$read_only_device" )" +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# !! Use _sz suffix for sizes expressed in number of 512b sectors, !! +# !! _size for random other crap !! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +if ! (( read_only_device_sz > 0 )); then + drop_shell "Could not determine size of read only device '$read_only_device'" +fi # handle_unit <value> <unit> # Supply percentage, or size in [kmgt]bytes, @@ -153,30 +159,6 @@ parse_config_int() { done <<< "$1" } -# Helper to call 'dmsetup setup' without syncing with udev -# and then actively create the devices with the mknodes command. -# Either pass the table contents as $2, or pipe them into the function -# dmsetup_create_noudevsync <name> [table] -dmsetup_create_noudevsync() { - ( - set -eo pipefail - if [ -n "$2" ]; then - printf "%s\n" "$2" | dmsetup create "$1" --noudevsync - else - dmsetup create "$1" --noudevsync - fi - dmsetup mknodes --noudevsync "$1" - echo "dm: Created $1" - ) - local ret=$? - [ -b "/dev/mapper/$1" ] || ret=99 - if [ $ret -ne 0 ]; then - echo "dm: Error creating $1, removing..." - dmsetup remove --noudevsync "$1" - fi - return $ret -} - # encrypt_device <dev_path> <encrypted_name> [<start> <size>] encrypt_device() { # TODO: Send key back to us, demand ransom @@ -383,28 +365,6 @@ create_pool() { # calculate number of sectors needed and check boundaries: # XXX Formula from thin-pool.txt calculates size in *bytes*, we want 512b blocks metadata_dev_sz="$(( 48 * scratch_device_sz / data_block_sz / 512 ))" - # If we want NTFS as a backup plan to extend the pool, check if the current size - # is less than 100GB, and only then consider this feature. - # Maybe make that thresold configurable one day, but for the desktop client - # use case this is sensible for now. - if [ "$SLX_NTFSFREE" = "backup" ] && (( scratch_device_sz < 209715200 )) \ - && [ -z "$metadata_persistent" ]; then - echo "pool: Considering NTFS partitions as backup since pool is small" - find_ntfs_partitions - if [ -s "$ntfs_list" ]; then - # Look what size we end up if we want at least 50GB - local sum="$( awk -v sum=0 \ - '{sum+=$1; if (sum >= 104857600) exit}END{printf "%.0f", sum}' \ - "$ntfs_list" )" - if (( sum > 0 )); then - (( sum > 209715200 )) && sum=209715200 # Max 100GB - # Account for this potential growth in the metadata device size for future expansion - metadata_dev_sz="$(( metadata_dev_sz + 48 * sum / data_block_sz / 512 ))" - echo "$sum" > "/run/openslx/.thin-ntfs-growsize" - root_ntfs_extra="$sum" - fi - fi - fi # Min 2MB -> 4096 sectors, max 16GB -> 33554432 sectors [ "$metadata_dev_sz" -lt 4096 ] && metadata_dev_sz="4096" # TODO handle the exotic case of a too large metadata device to fit within RAM. @@ -446,7 +406,7 @@ create_pool() { fi local pool_data_dev - if (( root_ntfs_extra == 0 )) && (( scratch_device_offset == 0 )); then + if (( scratch_device_offset == 0 )); then # No offset, no potential expansion, don't create another linear target pool_data_dev="$scratch_device" else @@ -502,140 +462,32 @@ create_volume() { return 0 } -# Find NTFS partitions with decently sized ranges of -# free space. We can use these as our writable layer -# for our thin-pool, if configured. -# If suitable, this will create the file $ntfs_list with -# one line per suitable partition, format -# total_size_blocks devpath -# Results are sorted by size, descending order -find_ntfs_partitions() { - [ -z "$SLX_NTFSFREE" ] && return - [ "$SLX_NTFSFREE" = "never" ] && return - [ -e "$ntfs_list" ] && return - echo "ntfs: Scanning for suitable NTFS partitions to use as writable device" - if ! command -v ntfsfree &> /dev/null; then - echo "ntfs: ntfsfree not found, cannot use NTFS partitions as RW layer" - return - fi - local part sum ro dev - ntfs_extra_space_sz=0 - for part in /dev/disk/by-partuuid/*; do - # Skip empty/ro devices - dev="$( readlink -f "$part" )" - dev="${dev##*/}" - ro="$( cat "/sys/class/block/${dev}/ro" )" - [ "$ro" = 1 ] && continue - # Only count ranges >= 256MB, sum will be in number of 512b blocks - sum="$( ntfsfree --block-size 512 --min-size "$(( 256 * 1024 * 1024 ))" "$part" 2> /dev/null \ - | awk -v sum=0 '{if ($1 == "Range") sum += $4}END{printf "%.0f", sum}' )" - # Only consider volume if sum of these ranges > 1GB (this is BLOCKS, not bytes) - (( sum > 2 * 1024 * 1024 )) || continue - echo "$sum $part" # only thing in loop going to stdout - (( ntfs_extra_space_sz += sum )) - done | sort -nr > "$ntfs_list" - echo "ntfs: Found $( wc -l < "$ntfs_list" ) suitable partitions" -} -ntfs_extra_space_sz=0 - ### ## MAIN ### . /etc/openslx - . slx-tools -# "Preload" functions by executing them NOT in a subshell -dev_find_partitions &> /dev/null -dev_swap_version &> /dev/null # This is the main variable driving this script +declare -g writable_device="$( cat "/.writable_device" )" declare -g id44_crypted= -declare -g writable_device= -if [ -z "$SLX_WRITABLE_DEVICE_IDENTIFIER" ]; then - SLX_WRITABLE_DEVICE_IDENTIFIER="44 87f86132-ff94-4987-b250-444444444444" - echo "SLX_WRITABLE_DEVICE_IDENTIFIER='${SLX_WRITABLE_DEVICE_IDENTIFIER}'" >> /etc/openslx -fi -if [ -n "$SLX_WRITABLE_DEVICE_IDENTIFIER" ]; then - unset writable_devices - declare -a writable_devices - read -r -a list <<<"$SLX_WRITABLE_DEVICE_IDENTIFIER" - echo "Scanning for partitions with type/label ${list[*]}..." - while read -r -a list; do - writable_devices+=( "${list[@]}" ) - done < <( dev_find_partitions "${list[@]}" ) - echo "Found ${#writable_devices[@]} matching partitions" - if [[ "${#writable_devices[@]}" -eq 0 && "$SLX_NTFSFREE" != "never" ]] || [ "$SLX_NTFSFREE" = "always" ]; then - find_ntfs_partitions - fi - if [ -s "$ntfs_list" ] || [[ "${#writable_devices[@]}" -gt 1 ]]; then - # More than one device, and/or NTFS space, need linear - echo "Have more than one writable device, creating linear target" - tbl="/run/openslx/dmsetup-linear-id44" - pos=0 - grow_max_sz=9999999999 - for dev in "${writable_devices[@]}"; do - max="$(( grow_max_sz - pos ))" - (( max <= 0 )) && break - sz="$( blockdev --getsz "$dev" )" - (( sz > 0 )) || continue - (( sz > max )) && sz="$max" - echo "$pos $sz linear $dev 0" - (( pos += sz )) - done > "$tbl" - if [ -s "$ntfs_list" ]; then - sum= - while read -r sum dev _ || [ -n "$sum" ]; do # each dev - echo "Appending NTFS partition $dev..." - word= - while read -r word range_start_b _ range_sz _ || [ -n "$word" ]; do # each slice of dev - [ "$word" = "Range" ] || continue - (( range_sz > 0 )) || continue - slice_sz="$(( grow_max_sz - pos ))" - (( slice_sz <= 0 )) && break - (( slice_sz > range_sz )) && slice_sz="$range_sz" - # Append line - if echo "$pos $slice_sz linear $dev $range_start_b" >> "$tbl"; then - # Update counter - (( pos += slice_sz )) - else - echo "Could not write new table row into $tbl" - fi - done < <( ntfsfree --block-size 512 --min-size "$(( 256 * 1024 * 1024 ))" "$dev" ) - done < "$ntfs_list" - # Don't try to add NTFS space again later - SLX_NTFSFREE="never" - sed -i "s/^SLX_NTFSFREE.*$/# & # disabled in stage3\nSLX_NTFSFREE='never'/" "/etc/openslx" - rm -f -- "$ntfs_list" - fi - # See if we need a linear target at all - if ! [ -s "$tbl" ]; then - echo "Empty tmp/id44 table, fallback to RAM" - elif [ "$( wc -l < "$tbl" )" -eq 1 ] && [[ "${#writable_devices[@]}" -ge 1 ]]; then - # Only one line, have writable device -> use directly - echo "Table somehow ended up with one entry, discarding" - writable_device="${writable_devices[0]}" - else - # set up linera device - echo "Setting up linear id44 device with $( wc -l < "$tbl" ) slices" - if ! dmsetup_create_noudevsync "id44-group" < "$tbl"; then - echo "$0: Error creating group of writable devices. Fallback to RAM :-(" - else - writable_device="/dev/mapper/id44-group" - fi - fi - else - # Single device - echo "Have a single writable device, using it directly" - writable_device="${writable_devices[0]}" - fi -fi if [ -z "$writable_device" ]; then - echo "Could not find writable device with id(s) '$SLX_WRITABLE_DEVICE_IDENTIFIER'." + echo "No writable device" ramdisk_fallback -elif is_on "$SLX_ID44_CRYPT"; then - # Config option crypts the entire ID44 device(s), before any slices are taken from it. + exit 0 +fi + +if ! [ -b "$writable_device" ]; then + drop_shell "Writable device '$writable_device' not a block device" +fi + +# "Preload" functions by executing them NOT in a subshell +dev_find_partitions &> /dev/null + +# Handle global encryption first +if is_on "$SLX_ID44_CRYPT"; then if encrypt_device "$writable_device" "id44-crypt"; then writable_device="/dev/mapper/id44-crypt" # Remember the whole device is already encrypted, and ignore the crypt flag for the partition table later @@ -645,6 +497,9 @@ fi # NOTE: from here on out, every value related to size is in 512 bytes sectors! declare -rg writable_device_sz="$( blockdev --getsz "$writable_device" )" +if ! (( writable_device > 0 )); then + drop_shell "Could not determine size of writable device '$writable_device'" +fi # If SLX_WRITABLE_DEVICE_PARTITION_TABLE is not set, just do # regular thin-snapshot for the CoW layer, else parse it. @@ -652,7 +507,7 @@ if [ -z "$SLX_WRITABLE_DEVICE_PARTITION_TABLE" ]; then SLX_WRITABLE_DEVICE_PARTITION_TABLE="thin-snapshot root 100% 0" fi -# extra swap? +# extra swap if no existing? if grep -qFw 'slx.swap' "/proc/cmdline"; then # Only if our basic writable_device is large enough, or we have ntfs backup echo "Additional swap on ID44 requested if existing is too small" @@ -662,22 +517,13 @@ if grep -qFw 'slx.swap' "/proc/cmdline"; then do_swap_sz="$(( ( writable_device_sz - 70312500 ) / 2 ))" # cap to 6GB (( do_swap_sz > 11718750 )) && do_swap_sz=11718750 - elif [ "$SLX_NTFSFREE" = "backup" ] \ - && (( ntfs_extra_space_sz > 70312500 )) && (( writable_device_sz > 11718750 )); then - # more than 40GB NTFS backup space, more than 6GB ID44, make 4GB swap - do_swap_sz=7812500 fi # Check how many we have and if they're regular, unencrypted ones. # If it's plenty, don't cut out swap from our backing device - swap_sz=0 if (( do_swap_sz == 0 )); then echo "Not enough ID44 space for swap..." else - for part in $( dev_find_partitions "82" "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f" ); do - dev_swap_version "$part" &> /dev/null || continue - this_sz="$( blockdev --getsz "$part" )" - (( this_sz > 0 )) && (( swap_sz += this_sz )) - done + swap_sz="$( awk '$1 == "SwapTotal:" {print $2 * 2}' /proc/meminfo )" echo "Have existing swap of $(( swap_sz / 2 / 1024 ))MiB" (( do_swap_sz -= swap_sz )) # Go ahead with swap? Only if we miss a reasonable amount... ( > 100MiB) @@ -801,7 +647,6 @@ done ## THIN-PROVISIONING ### declare -rg pool_dev="/dev/mapper/pool" -declare -gi root_ntfs_extra=0 # Extra blocks to provision to root fs for later expansion # Now decide what to do for the writable layer if [ -n "$thin_snapshot" ] || [ -n "${thin_volume[*]}" ]; then @@ -863,12 +708,6 @@ if [ -n "$thin_snapshot" ] || [ -n "${thin_volume[*]}" ]; then reserved_sz="$(( read_only_device_sz / 2 ))" (( reserved_sz > max_reserved_sz )) && reserved_sz="$max_reserved_sz" thin_snapshot_sz="$(( scratch_device_sz + read_only_device_sz - reserved_sz ))" - # For later on-demand growing, overprovision by free space we found on - # clean NTFS volumes. This requires a user-space helper to listen for - # dm events in stage4, which should in turn add that free space to the pool-data - if (( root_ntfs_extra > 0 )); then - thin_snapshot_sz="$(( thin_snapshot_sz + root_ntfs_extra ))" - fi if ! create_volume "$name" 1 "$thin_snapshot_sz" "$read_only_device"; then echo "Error: Failed to create external snapshot for '$read_only_device'." >&2 ramdisk_fallback # does not return diff --git a/modules.d/slx-dmsetup/hooks/s3-mount-swap.sh b/modules.d/slx-dmsetup/hooks/s3-mount-swap.sh new file mode 100755 index 00000000..0384bcf4 --- /dev/null +++ b/modules.d/slx-dmsetup/hooks/s3-mount-swap.sh @@ -0,0 +1,10 @@ +#!/bin/ash + +. slx-tools + +for part in $( dev_find_partitions "82" "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f" ); do + dev_swap_version "$part" &> /dev/null || continue + swapon "$part" +done + +exit 0 diff --git a/modules.d/slx-dmsetup/hooks/s3-prepare-rw-layer.sh b/modules.d/slx-dmsetup/hooks/s3-prepare-rw-layer.sh new file mode 100755 index 00000000..69fc75d2 --- /dev/null +++ b/modules.d/slx-dmsetup/hooks/s3-prepare-rw-layer.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +if ! [ -e "/.writable_devices" ]; then + echo "/.writable_devices not found" + exit 1 +fi +mapfile -t writable_devices < /.writable_devices + +declare -rg ntfs_list="/run/openslx/.thin-ntfs-candidates" + +. slx-tools + +if [ -s "$ntfs_list" ] || [[ "${#writable_devices[@]}" -gt 1 ]]; then + # More than one device, and/or NTFS space, need linear + echo "Have more than one writable device, creating linear target" + tbl="/run/openslx/dmsetup-linear-id44" + pos=0 + grow_max_sz=9999999999 + for dev in "${writable_devices[@]}"; do + max="$(( grow_max_sz - pos ))" + (( max <= 0 )) && break + sz="$( blockdev --getsz "$dev" )" + (( sz > 0 )) || continue + (( sz > max )) && sz="$max" + echo "$pos $sz linear $dev 0" + (( pos += sz )) + done > "$tbl" + if [ -s "$ntfs_list" ]; then + sum= + while read -r sum dev _ || [ -n "$sum" ]; do # each dev + echo "Appending NTFS partition $dev..." + word= + while read -r word range_start_b _ range_sz _ || [ -n "$word" ]; do # each slice of dev + [ "$word" = "Range" ] || continue + (( range_sz > 0 )) || continue + slice_sz="$(( grow_max_sz - pos ))" + (( slice_sz <= 0 )) && break + (( slice_sz > range_sz )) && slice_sz="$range_sz" + # Append line + if echo "$pos $slice_sz linear $dev $range_start_b" >> "$tbl"; then + # Update counter + (( pos += slice_sz )) + else + echo "Could not write new table row into $tbl" + fi + done < <( ntfsfree --block-size 512 --min-size "$(( 256 * 1024 * 1024 ))" "$dev" ) + done < "$ntfs_list" + # Don't try to add NTFS space again later + sed -i "s/^SLX_NTFSFREE.*$/# & # disabled in stage3\nSLX_NTFSFREE='never'/" "/etc/openslx" + rm -f -- "$ntfs_list" + fi + # See if we need a linear target at all + if ! [ -s "$tbl" ]; then + echo "Empty tmp/id44 table, fallback to RAM" + elif [ "$( wc -l < "$tbl" )" -eq 1 ] && [[ "${#writable_devices[@]}" -ge 1 ]]; then + # Only one line, have writable device -> use directly + echo "Table somehow ended up with one entry, discarding" + writable_device="${writable_devices[0]}" + else + # set up linear device + echo "Setting up linear id44 device with $( wc -l < "$tbl" ) slices" + if ! dmsetup_create_noudevsync "id44-group" < "$tbl"; then + echo "Error creating group of writable devices. Fallback to RAM :-(" + else + writable_device="/dev/mapper/id44-group" + fi + fi +else + # Single device + echo "Have a single writable device, using it directly" + writable_device="${writable_devices[0]}" +fi + +if [ -z "$writable_device" ]; then + echo "Could not find any suitable writable devices." +fi + +echo "$writable_device" > "/.writable_device" + +exit 0 diff --git a/modules.d/slx-dmsetup/hooks/s3-scan-id44.sh b/modules.d/slx-dmsetup/hooks/s3-scan-id44.sh new file mode 100755 index 00000000..60ba133d --- /dev/null +++ b/modules.d/slx-dmsetup/hooks/s3-scan-id44.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +. /etc/openslx +. slx-tools + +if [ -z "$SLX_WRITABLE_DEVICE_IDENTIFIER" ]; then + SLX_WRITABLE_DEVICE_IDENTIFIER="44 87f86132-ff94-4987-b250-444444444444" + echo "SLX_WRITABLE_DEVICE_IDENTIFIER='${SLX_WRITABLE_DEVICE_IDENTIFIER}'" >> /etc/openslx +fi + +declare -a writable_devices +read -r -a list <<<"$SLX_WRITABLE_DEVICE_IDENTIFIER" +echo "Scanning for partitions with type/label ${list[*]}..." +for dev in $( dev_find_partitions "${list[@]}" ); do + writable_devices+=( "$dev" ) +done +echo "Found ${#writable_devices[@]} matching partitions" + +for dev in "${writable_devices[@]}"; do + echo "$dev" +done > "/.writable_devices" + +exit 0 diff --git a/modules.d/slx-dmsetup/module-setup.sh b/modules.d/slx-dmsetup/module-setup.sh index 99c1adf2..e513ca6f 100755 --- a/modules.d/slx-dmsetup/module-setup.sh +++ b/modules.d/slx-dmsetup/module-setup.sh @@ -6,9 +6,10 @@ depends() { echo "haveged slx-tools" } install() { - inst "$moddir/hooks/dmsetup-slx-device" "/usr/local/bin/dmsetup-slx-device" + inst "$moddir/bin/dmsetup_create_noudevsync" "/usr/local/bin/dmsetup_create_noudevsync" # Grows the rootfs to match the underlying blockdev + # No using slx install helper because of additional condition _name="s3-grow-rootfs" inst "$moddir/hooks/${_name}.sh" \ "/usr/local/bin/${_name}.sh" @@ -19,12 +20,24 @@ install() { ln_r "${systemdsystemunitdir}/${_name}.service" \ "${systemdsystemunitdir}/initrd.target.wants/${_name}.service" + slx_service "s3-cow-setup" "Set up the CoW layer for rootfs" \ + --wafter "s3-connect-image.service" \ + --before "initrd-root-device.target" \ + --after "s3-fetch-config.service" + + slx_service "s3-mount-swap" "Mount existing swap partitions" \ + --before "s3-cow-setup" + + slx_service "s3-prepare-rw-layer" "Prepare suitable partitions for use as write layer" \ + --before "s3-cow-setup" + + slx_service "s3-scan-id44" "Scan for partitions marked as scratch space (ID44)" \ + --before "s3-prepare-rw-layer.service" \ + --after "s3-fetch-config.service" + inst_multiple blockdev xxd \ mkfs.ext4 resize2fs \ mkfs.xfs xfs_repair xfs_growfs - - # TODO properly find binary in PATH + /opt/openslx/{s,}bin etc - inst /opt/openslx/sbin/ntfsfree /usr/local/bin/ntfsfree } installkernel() { # install those modules in case the used kernel does not have them builtin diff --git a/modules.d/slx-extra-script/module-setup.sh b/modules.d/slx-extra-script/module-setup.sh index 9cc9bdbe..0c3600e2 100755 --- a/modules.d/slx-extra-script/module-setup.sh +++ b/modules.d/slx-extra-script/module-setup.sh @@ -9,7 +9,8 @@ depends() { install() { slx_service "s3-extra-script" "Execute extra script from URL" \ --wafter "s3-fetch-config.service" \ - --before "s3-dnbd3root.service" + --before "s3-connect-image.service" \ + --before "s3-prepare-rw-layer.service" mkdir --parents "${initdir}/${systemdsystemunitdir}/initrd.target.wants" local i for i in dmsetup mount; do diff --git a/modules.d/slx-extra-script/services/s3-extra-post-dmsetup.service b/modules.d/slx-extra-script/services/s3-extra-post-dmsetup.service index fd1f18e6..a7d8a6fe 100644 --- a/modules.d/slx-extra-script/services/s3-extra-post-dmsetup.service +++ b/modules.d/slx-extra-script/services/s3-extra-post-dmsetup.service @@ -1,7 +1,7 @@ [Unit] Description=Run extra script after dmsetup ConditionFileIsExecutable=/etc/extra-init -After=s3-dnbd3root.service +After=s3-cow-setup.service Before=s3-write-fstab.service Before=initrd-switch-root.target initrd-cleanup.service diff --git a/modules.d/slx-ntfsfree/hooks/s3-ntfsfree.sh b/modules.d/slx-ntfsfree/hooks/s3-ntfsfree.sh new file mode 100755 index 00000000..0c663ef3 --- /dev/null +++ b/modules.d/slx-ntfsfree/hooks/s3-ntfsfree.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +. /etc/openslx +[ "${SLX_NTFSFREE:-never}" = "never" ] && exit 0 + +declare -rg ntfs_list="/run/openslx/.thin-ntfs-candidates" +[ -e "$ntfs_list" ] && exit 0 + +echo "Scanning for suitable NTFS partitions to use as writable device" +if ! command -v ntfsfree &> /dev/null; then + echo "ntfsfree not found, cannot use NTFS partitions as RW layer" + exit 1 +fi + +for part in /dev/disk/by-partuuid/*; do + # Skip empty/ro devices + dev="$( readlink -f "$part" )" + dev="${dev##*/}" + ro="$( cat "/sys/class/block/${dev}/ro" )" + [ "$ro" = 1 ] && continue + # Only count ranges >= 256MB, sum will be in number of 512b blocks + sum="$( ntfsfree --block-size 512 --min-size "$(( 256 * 1024 * 1024 ))" "$part" 2> /dev/null \ + | awk -v sum=0 '{if ($1 == "Range") sum += $4}END{printf "%.0f", sum}' )" + # Only consider volume if sum of these ranges > 1GB (this is BLOCKS, not bytes) + (( sum > 2 * 1024 * 1024 )) || continue + echo "$sum $part" # only thing in loop going to stdout +done | sort -nr > "$ntfs_list" +echo "Found $( wc -l < "$ntfs_list" ) suitable partitions" + +exit 0 diff --git a/modules.d/slx-ntfsfree/module-setup.sh b/modules.d/slx-ntfsfree/module-setup.sh new file mode 100755 index 00000000..dabe2dda --- /dev/null +++ b/modules.d/slx-ntfsfree/module-setup.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +check() { + return 255 +} +depends() { + echo "slx-tools" +} +install() { + slx_service "s3-ntfsfree" "Scan for free space on NTFS partitions" \ + --wafter "s3-fetch-config.service" + --before "s3-prepare-rw-layer" + # TODO properly find binary in PATH + /opt/openslx/{s,}bin etc + inst /opt/openslx/sbin/ntfsfree /usr/local/bin/ntfsfree +} +installkernel() { + # install those modules in case the used kernel does not have them builtin + instmods \ + dm-thin-pool dm-snapshot dm-zero dm-crypt \ + crc32c xts aes drbg ansi_cprng \ + xfs ext4 +} |
