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