summaryrefslogtreecommitdiffstats
path: root/dd-parallel
diff options
context:
space:
mode:
authorFlorian Pritz <bluewind@xinu.at>2024-10-14 21:34:04 +0200
committerFlorian Pritz <bluewind@xinu.at>2024-10-14 21:54:03 +0200
commitd5ffb01d87852eb74f6b17ae06ac0c476010065b (patch)
tree1ac6a86d874f30c968ba26bf0f8a5954fa0c67a6 /dd-parallel
parentd10ee7703e20ef844907e90797ad66bf0fb984da (diff)
downloadbin-d5ffb01d87852eb74f6b17ae06ac0c476010065b.tar.gz
bin-d5ffb01d87852eb74f6b17ae06ac0c476010065b.tar.xz
Add new scripts
Signed-off-by: Florian Pritz <bluewind@xinu.at>
Diffstat (limited to 'dd-parallel')
-rwxr-xr-xdd-parallel31
1 files changed, 31 insertions, 0 deletions
diff --git a/dd-parallel b/dd-parallel
new file mode 100755
index 0000000..0745225
--- /dev/null
+++ b/dd-parallel
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# Run multiple dd processes in parallel to copy a single file/blockdevice. Each
+# dd process will operate on a dedicated part of the file at a time (1GB chunks
+# for big files).
+
+set -e
+
+# Source: https://stackoverflow.com/a/25268449
+min() {
+ printf "%s\n" "${@:2}" | sort "$1" | head -n1
+}
+max() {
+ # using sort's -r (reverse) option - using tail instead of head is also possible
+ min "${1}r" "${@:2}"
+}
+
+inputfile=$1
+if [[ -b "$inputfile" ]]; then
+ inputsize=$(blockdev --getsize64 "$inputfile")
+else
+ inputsize=$(stat --format %s "$inputfile")
+fi
+outputfile=$2
+
+stepsize=1000
+parallel=6
+# 1GB blocks or smaller blocks if we cannot achieve the required parallelization with 1GB
+blocksize=$(min -g 1000000 "$((inputsize / stepsize / parallel))" )
+
+seq 0 $stepsize $(($inputsize / $blocksize )) | xargs -P$parallel -I{} dd if="$inputfile" bs=$blocksize skip={} conv=sparse seek={} count=$stepsize status=none of="$outputfile"