aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zfs-flatten.sh67
1 files changed, 67 insertions, 0 deletions
diff --git a/zfs-flatten.sh b/zfs-flatten.sh
new file mode 100644
index 0000000..179048c
--- /dev/null
+++ b/zfs-flatten.sh
@@ -0,0 +1,67 @@
1DATASET_ROOT=$1
2DATASET_TARGET=$2
3
4MOUNTPOINT_TARGET=$(zfs get -H mountpoint -o value $DATASET_TARGET)
5
6if ! test -d "$MOUNTPOINT_TARGET"; then
7 echo "Please run this program with a source and a target dataset name as arguments"
8 echo "e.g. $0 zpool/dataset1 zpool/dataset2"
9 exit
10fi
11
12# make sure, that ctrl-c also works in the inner loops
13trap exit INT
14
15# recursively contains all snapshot names (the part after the @) from root on, sorted and only once
16SNAPSHOTS=$(zfs list -H -r $DATASET_ROOT -oname -tsnap | cut -d@ -f2 | sort | uniq)
17DATASETS=$(zfs list -H -r $DATASET_ROOT -oname -t filesystem)
18
19echo "We are going to flatten the hierachy of this dataset:"
20printf " %s\n" $DATASETS
21echo "into the dataset with the name:"
22echo " $DATASET_TARGET"
23echo "mounted under:"
24echo " $MOUNTPOINT_TARGET"
25echo ""
26echo "You have 10 seconds to abort this with CTRL-C"
27sleep 10
28
29for SNAPSHOT in $SNAPSHOTS; do
30 echo ""
31 echo ""
32 echo "==========================="
33 echo "Next snapshot is: $SNAPSHOT"
34 echo "==========================="
35
36 for DATASET in $DATASETS; do
37
38 MOUNTPOINT=$(zfs get -H mountpoint -o value $DATASET)
39
40 if [[ $MOUNTPOINT == "legacy" ]]; then
41 MOUNTPOINT=$(findmnt -n -o target $DATASET)
42 if test -d $MOUNTPOINT; then
43 >&2 echo "Dataset has a legacy mountpoint, but was not found in the fstab: $DATASET"
44 continue
45 fi
46 fi
47
48 if [[ $MOUNTPOINT == "-" ]]; then
49 >&2 echo "Dataset does not have a mount point or is a vdev: $DATASET"
50 continue
51 fi
52
53 SNAPDIR=$(realpath $MOUNTPOINT/.zfs/snapshot/$SNAPSHOT)
54 if test -d $SNAPDIR; then
55 TARGET_DIR="$(realpath $DATASET_TARGET)$(realpath $MOUNTPOINT)"
56 mkdir -p "$TARGET_DIR"
57 echo rsync --info=stats3 -a "$SNAPDIR/" "$TARGET_DIR/"
58 if ! rsync --info=stats3 -a "$SNAPDIR/" "$TARGET_DIR/" ; then
59 >&2 echo "rsync could not entirely copy from $SNAPDIR to $DATASET_TARGET"
60 fi
61 fi
62 done
63 NEW_SNAPSHOT="$DATASET_TARGET@$SNAPSHOT"
64 echo "Files copied, creating snapshot: $NEW_SNAPSHOT"
65 zfs snap $NEW_SNAPSHOT
66done
67
..