summaryrefslogtreecommitdiffstats
path: root/modules.d/slx-dmsetup/scripts/dmsetup-slx-device
diff options
context:
space:
mode:
Diffstat (limited to 'modules.d/slx-dmsetup/scripts/dmsetup-slx-device')
-rwxr-xr-xmodules.d/slx-dmsetup/scripts/dmsetup-slx-device58
1 files changed, 56 insertions, 2 deletions
diff --git a/modules.d/slx-dmsetup/scripts/dmsetup-slx-device b/modules.d/slx-dmsetup/scripts/dmsetup-slx-device
index f986f6e9..f9bbdd9d 100755
--- a/modules.d/slx-dmsetup/scripts/dmsetup-slx-device
+++ b/modules.d/slx-dmsetup/scripts/dmsetup-slx-device
@@ -28,6 +28,8 @@ exec &> /run/openslx/dmsetup.log
declare -g read_only_device="$1"
declare -g read_only_device_size="$( blockdev --getsz "$1" )"
+declare -rg ntfs_list="/run/openslx/.thin-ntfs-candidates"
+
# global array variables storing the configuration of the partitions
declare -ag linear snapshot thin_snapshot thin_volume
parse_config() {
@@ -362,11 +364,12 @@ done
writable_device="$scratch_device"
writable_device_size="$scratch_device_size"
-###
+###
## THIN-PROVISIONING
###
declare -rg pool_data_dev="/dev/mapper/pool-data"
declare -rg pool_dev="/dev/mapper/pool"
+declare -gi root_ntfs_extra=0 # Extra blocks to provision to root fs for later expansion
create_pool() {
declare -r data_block_size=256 # Desired Block size (number of 512byte sectors)
declare -r wanted_low_mb=100 # Free space below this will trigger a dm event
@@ -375,8 +378,29 @@ create_pool() {
modprobe dm-thin-pool || echo "$0: dm-thin-pool load failed, maybe builtin?"
# create temporary metadata device
# calculate number of sectors needed and check boundaries:
- # XXX According to thin-provisioning.txt the / 512 part is WRONG!
+ # XXX Formula from thin-pool.txt calculates size in *bytes*, we want 512b blocks
metadata_dev_size="$(( 48 * writable_device_size / data_block_size / 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 the the desktop client
+ # use case this is sensible for now.
+ if [ "$SLX_NTFSFREE" = "backup" ] && (( writable_device_size < 209715200 )) \
+ && [ -z "$metadata_persistent" ]; then
+ 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_size="$(( metadata_dev_size + 48 * sum / data_block_size / 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_size" -lt 4096 ] && metadata_dev_size="4096"
# TODO handle the exotic case of a too large metadata device to fit within RAM.
@@ -451,6 +475,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
+ if ! command -v ntfsfree &> /dev/null; then
+ echo "$0: ntfsfree not found, cannot use NTFS partitions as RW layer"
+ return
+ fi
+ local part sum
+ for part in /dev/disk/by-partuuid/*; do
+ # Only count ranges >= 256MB, sum will be in number of 512b blocks
+ sum="$( ntfsfree --block-size 512 --min-size "$(( 256 * 1024 * 1024 ))" "$part" \
+ | 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"
+}
+
# Now decide what to do for the writable layer
if [ -n "$thin_snapshot" ] || [ -n "$thin_volume" ]; then
@@ -495,6 +545,10 @@ if [ -n "$thin_snapshot" ] || [ -n "$thin_volume" ]; then
else
thin_snapshot_size="$read_only_device_size"
fi
+ # For later on-demand growing
+ if (( root_ntfs_extra > 0 )); then
+ thin_snapshot_size="$(( thin_snapshot_size + root_ntfs_extra ))"
+ fi
if ! create_volume "$name" 1 "$thin_snapshot_size" "$read_only_device"; then
echo "Failed to create external snapshot for '$read_only_device'."
ramdisk_fallback