diff options
-rwxr-xr-x | zfs-squash-datasets.sh | 115 |
1 files changed, 93 insertions, 22 deletions
diff --git a/zfs-squash-datasets.sh b/zfs-squash-datasets.sh index d668c80..3623edf 100755 --- a/zfs-squash-datasets.sh +++ b/zfs-squash-datasets.sh | |||
@@ -1,42 +1,99 @@ | |||
1 | #!/usr/local/bin/bash | 1 | #!/usr/local/bin/bash |
2 | DATASET_ROOT=$1 | ||
3 | DATASET_TARGET=$2 | ||
4 | 2 | ||
5 | MOUNTPOINT_TARGET=$(zfs get -o value -H mountpoint $DATASET_TARGET) | 3 | # DO NOT USE THIS SCRIPT |
4 | # It is in a state of hot garbage and will probably be deleted soon | ||
6 | 5 | ||
7 | if ! test -d "$MOUNTPOINT_TARGET"; then | 6 | |
7 | print_help_and_exit() { | ||
8 | echo "Please run this program with a source and a target dataset name as arguments" | 8 | echo "Please run this program with a source and a target dataset name as arguments" |
9 | echo "e.g. $0 zpool/dataset1 zpool/dataset2" | 9 | echo "e.g. $0 zpool/dataset1 zpool/dataset2" |
10 | exit | 10 | exit |
11 | } | ||
12 | |||
13 | SIMULATION=0 | ||
14 | |||
15 | args=$(getopt n $*) | ||
16 | test $? == 0 || print_help_and_exit | ||
17 | |||
18 | set -- $args | ||
19 | |||
20 | while :; do | ||
21 | sleep 1 | ||
22 | echo $1 | ||
23 | case "$1" in | ||
24 | --) shift; break ;; | ||
25 | -n) SIMULATION=1 ; shift ;; | ||
26 | esac | ||
27 | done | ||
28 | |||
29 | DATASET_ROOT=$1 | ||
30 | DATASET_TARGET=$2 | ||
31 | |||
32 | if ! zfs get mountpoint $DATASET_TARGET >/dev/null; then | ||
33 | echo "Dataset $DATASET_TARGET does not exist and will be created." | ||
34 | echo "You have 10 seconds to abort this with CTRL-C" | ||
35 | sleep 10 | ||
36 | if ! $SIMULATION; then | ||
37 | zfs create $DATASET_TARGET | ||
38 | fi | ||
11 | fi | 39 | fi |
12 | 40 | ||
41 | if zfs get -H -t filesystem -o name,value -r snapdir zeus/data/projects | grep -v visible >/dev/null; then | ||
42 | echo Please make all snapdirs visible: | ||
43 | zfs get -H -t filesystem -o name,value -r snapdir zeus/data/projects | ||
44 | exit 2 | ||
45 | fi | ||
46 | |||
47 | |||
48 | MOUNTPOINT_TARGET=$(zfs get -o value -H mountpoint $DATASET_TARGET) | ||
49 | test ${SIMULATION:0} = 1 && test $MOUNTPOINT_TARGET == "" && MOUNTPOINT_TARGET="datapool/simulation" | ||
50 | |||
51 | test -d "$MOUNTPOINT_TARGET" || print_help_and_exit | ||
52 | |||
13 | # make sure, that ctrl-c also works in the inner loops | 53 | # make sure, that ctrl-c also works in the inner loops |
14 | trap exit INT | 54 | trap exit INT |
15 | 55 | ||
16 | # recursively contains all snapshot names (the part after the @) from root on, sorted and only once | 56 | # recursively contains all snapshot names (the part after the @) from root on, sorted and only once |
17 | SNAPSHOTS=$(zfs list -H -oname -tsnap -r $DATASET_ROOT| cut -d@ -f2 | sort | uniq) | 57 | SNAPSHOTS=$(zfs list -H -oname -tsnap -r $DATASET_ROOT | cut -d@ -f2 | sort -u) |
18 | DATASETS=$(zfs list -H -oname -t filesystem -r $DATASET_ROOT) | 58 | DATASETS=$(zfs list -H -oname -t filesystem -r $DATASET_ROOT) |
19 | 59 | ||
60 | test "${SIMULATION:-0}" = 1 && echo "SIMULATION MODE" | ||
61 | |||
62 | $DATASETS | ||
63 | |||
64 | |||
20 | echo "We are going to flatten the hierachy of this dataset:" | 65 | echo "We are going to flatten the hierachy of this dataset:" |
21 | printf " %s\n" $DATASETS | 66 | printf "\t%s\n" $DATASETS |
22 | echo "into the dataset with the name:" | 67 | echo -e "into the dataset with the name:" |
23 | echo " $DATASET_TARGET" | 68 | echo -e "\t$DATASET_TARGET" |
24 | echo "mounted under:" | 69 | echo -e "mounted under:" |
25 | echo " $MOUNTPOINT_TARGET" | 70 | echo -e "\t$MOUNTPOINT_TARGET" |
71 | echo -e "with the following snapshots:" | ||
72 | printf "\t%s\n" $SNAPSHOTS | ||
26 | echo "" | 73 | echo "" |
27 | echo "You have 10 seconds to abort this with CTRL-C" | 74 | echo "You have 10 seconds to abort this with CTRL-C" |
28 | sleep 10 | 75 | sleep 10 |
29 | 76 | ||
77 | set -- $SNAPSHOTS | ||
78 | SNAPSHOTS_TOTAL=$# | ||
79 | SNAPSHOT_CURRENT=0 | ||
80 | |||
81 | set -- $DATASETS | ||
82 | shift | ||
83 | SUBDATASETS=$@ | ||
84 | |||
30 | for SNAPSHOT in $SNAPSHOTS; do | 85 | for SNAPSHOT in $SNAPSHOTS; do |
31 | echo "" | 86 | echo "" |
32 | echo "" | 87 | echo "" |
33 | echo "===========================" | 88 | SNAPSHOT_CURRENT=$((SNAPSHOT_CURRENT + 1)) |
34 | echo "Next snapshot is: $SNAPSHOT" | 89 | echo "[$SNAPSHOT_CURRENT/$SNAPSHOTS_TOTAL] Next snapshot is: $SNAPSHOT" |
35 | echo "===========================" | 90 | |
91 | for DATASET in $SUBDATASETS; do | ||
36 | 92 | ||
37 | for DATASET in $DATASETS; do | 93 | DATASET_RELATIVE=${DATASET##$DATASET_ROOT} |
38 | 94 | ||
39 | MOUNTPOINT=$(zfs get -H -o value mountpoint $DATASET) | 95 | MOUNTPOINT=$(zfs get -H -o value mountpoint $DATASET) |
96 | echo "RELATIVE=$DATASET_RELATIVE" | ||
40 | 97 | ||
41 | if [[ $MOUNTPOINT == "legacy" ]]; then | 98 | if [[ $MOUNTPOINT == "legacy" ]]; then |
42 | MOUNTPOINT=$(findmnt -n -o target $DATASET) | 99 | MOUNTPOINT=$(findmnt -n -o target $DATASET) |
@@ -51,18 +108,32 @@ for SNAPSHOT in $SNAPSHOTS; do | |||
51 | continue | 108 | continue |
52 | fi | 109 | fi |
53 | 110 | ||
54 | SNAPDIR=$(realpath $MOUNTPOINT/.zfs/snapshot/$SNAPSHOT) | 111 | SNAPDIR=$MOUNTPOINT/.zfs/snapshot/$SNAPSHOT |
55 | if test -d $SNAPDIR; then | 112 | if test -d $SNAPDIR; then |
56 | TARGET_DIR="$(realpath $MOUNTPOINT_TARGET)$(realpath $MOUNTPOINT)" | 113 | |
57 | mkdir -p "$TARGET_DIR" | 114 | TARGET_DIR="${MOUNTPOINT_TARGET}${DATASET_RELATIVE}" |
58 | echo rsync --info=stats3 -a "$SNAPDIR/" "$TARGET_DIR/" | 115 | |
59 | if ! rsync --info=stats3 -a "$SNAPDIR/" "$TARGET_DIR/" ; then | 116 | echo -e \\trsync --info=stats3 --delete -a "$SNAPDIR/" "$TARGET_DIR/" |
60 | >&2 echo "rsync could not entirely copy from $SNAPDIR to $DATASET_TARGET" | 117 | if test "${SIMULATION:-0}" = 0; then |
118 | |||
119 | mkdir -p "$TARGET_DIR" | ||
120 | |||
121 | if ! rsync --info=stats3 --delete -a "$SNAPDIR/" "$TARGET_DIR/" ; then | ||
122 | >&2 echo "rsync could not entirely copy from $SNAPDIR to $DATASET_TARGET" | ||
123 | fi | ||
61 | fi | 124 | fi |
125 | else | ||
126 | echo -e "\tSKIP: Snapshot $SNAPSHOT does not exist for dataset $DATASET" | ||
62 | fi | 127 | fi |
63 | done | 128 | done |
129 | |||
64 | NEW_SNAPSHOT="$DATASET_TARGET@$SNAPSHOT" | 130 | NEW_SNAPSHOT="$DATASET_TARGET@$SNAPSHOT" |
65 | echo "Files copied, creating snapshot: $NEW_SNAPSHOT" | 131 | echo "" |
66 | zfs snap $NEW_SNAPSHOT | 132 | echo -e "\t> Concluding snapshot: ${NEW_SNAPSHOT} <" |
133 | echo "" | ||
134 | |||
135 | if test "${SIMULATION:-0}" = 0; then | ||
136 | zfs snap $NEW_SNAPSHOT | ||
137 | fi | ||
67 | done | 138 | done |
68 | 139 | ||