diff options
Diffstat (limited to 'builder/modules.d/slx-dmsetup/scripts/dmsetup-slx-device')
-rwxr-xr-x | builder/modules.d/slx-dmsetup/scripts/dmsetup-slx-device | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/builder/modules.d/slx-dmsetup/scripts/dmsetup-slx-device b/builder/modules.d/slx-dmsetup/scripts/dmsetup-slx-device index 7a371123..89dab344 100755 --- a/builder/modules.d/slx-dmsetup/scripts/dmsetup-slx-device +++ b/builder/modules.d/slx-dmsetup/scripts/dmsetup-slx-device @@ -133,10 +133,36 @@ create_snapshot() { # This will call terminate the whole script by calling finish_setup, if successful 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 + # first we create a dedicated tmpfs to control the maximum size + local cow_tmpfs="/run/openslx/dnbd-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 + + local qcow_size_in_kb="$(( writable_device_size / 2 ))" + local ram_size_in_kb="$(awk '/MemTotal/ {printf("%d\n", $2 )}' /proc/meminfo)" + + # Use the qcow size + half the RAM as tmpfs size. + local cow_size="$(( qcow_size_in_kb + ( ram_size_in_kb / 2 ) ))" + if ! mount -t tmpfs tmpfs -o size="${cow_size}k" "$cow_tmpfs"; then + emergency_shell "Failed to prepare dedicated CoW tmpfs in $cow_tmpfs of size $cow_size." + fi + + local file="$(mktemp -u -p "$cow_tmpfs" dnbd_cow.XXX)" + local fail_count=0 + while ! fallocate -l "${cow_size}K" "$file" ; do + (( cow_size -= 4 )) + if [ "$(( fail_count ++ ))" -eq 1000 ]; then + break + fi + done + if [ "$fail_count" -eq 1000 ]; then + emergency_shell "Failed to allocate CoW file $file after 1000 tries. :(" + fi writable_device="$(losetup --show --find "$file")" cow_device_candidate="root" while [ -b "/dev/mapper/$cow_device_candidate" ]; do |