Statistiques
| Révision :

root / bin / zfs-replica @ 67

Historique | Voir | Annoter | Télécharger (11,13 ko)

1 1 kreverch
#!/bin/bash
2 39 ltaulell
# $Id$
3 51 ltaulell
# Copyright (C) 2013 Kevin Reverchon, Loïs Taulelle
4 51 ltaulell
# This file/program is part of gZFS free software
5 51 ltaulell
# See COPYING file for details
6 51 ltaulell
#
7 1 kreverch
8 1 kreverch
#--- Define variables ---#
9 1 kreverch
DIR_CONF_REPLICA="/opt/gZFS/replicas/"
10 1 kreverch
getConfigSnapshotTool="/sbin/get-conf-snapshot"
11 1 kreverch
zfsSnapshot="/sbin/zfs-snapshot"
12 1 kreverch
FILE_NAME=$1
13 62 kreverch
TEMP_FILE_NAME="$1-tmp"
14 62 kreverch
>$TEMP_FILE_NAME
15 49 kreverch
BINZFS="/sbin/zfs"
16 49 kreverch
BINZPOOL="/sbin/zpool"
17 66 ltaulell
BINMBUFFER="mbuffer -4 -v 0 -q -s 128k -m 1G"
18 66 ltaulell
LOCALHOST=$(hostname -s)
19 1 kreverch
20 67 ltaulell
LOGFILEROTATE=21
21 67 ltaulell
LOGDIR="/var/log/zfs-replica"
22 67 ltaulell
23 67 ltaulell
if [ "$2" == "--cronlog" ];
24 67 ltaulell
then
25 67 ltaulell
  LOG=true
26 67 ltaulell
  if [ ! -d $LOGDIR ];
27 67 ltaulell
  then
28 67 ltaulell
    mkdir -p $LOGDIR
29 67 ltaulell
  fi
30 67 ltaulell
else
31 67 ltaulell
  LOG=false
32 67 ltaulell
fi
33 67 ltaulell
34 1 kreverch
#********************************
35 67 ltaulell
#* function ok_exit
36 67 ltaulell
#*******************************
37 67 ltaulell
function ok_exit {
38 67 ltaulell
  if $LOG; then
39 67 ltaulell
    echo $1 1>&2
40 67 ltaulell
    # restauration de stderr et stdout, fermeture des fd temporaires
41 67 ltaulell
    exec 2>&7 7>&-
42 67 ltaulell
    exec 1>&6 6>&-
43 67 ltaulell
  fi
44 67 ltaulell
  exit 0
45 67 ltaulell
}
46 67 ltaulell
47 67 ltaulell
#********************************
48 67 ltaulell
#* function err_exit
49 67 ltaulell
#*******************************
50 67 ltaulell
function err_exit {
51 67 ltaulell
  if $LOG; then
52 67 ltaulell
    echo $1 1>&2
53 67 ltaulell
    # restauration de stderr et stdout, fermeture des fd temporaires
54 67 ltaulell
    exec 2>&7 7>&-
55 67 ltaulell
    exec 1>&6 6>&-
56 67 ltaulell
  fi
57 67 ltaulell
  cat $LOGFILE
58 67 ltaulell
  exit 1
59 67 ltaulell
}
60 67 ltaulell
61 67 ltaulell
#********************************
62 1 kreverch
#* function initenv
63 1 kreverch
#*******************************
64 1 kreverch
function initenv {
65 10 kreverch
if [[ -z $FILE_NAME ]]
66 10 kreverch
then
67 11 kreverch
   echo "/!\\ Replica Configuration file missing /!\\" 1>&2
68 11 kreverch
   exit 1
69 10 kreverch
fi
70 1 kreverch
71 67 ltaulell
if [ ! -s $FILE_NAME ]
72 1 kreverch
then
73 67 ltaulell
   echo "Replica Configuration file not found"
74 67 ltaulell
   exit 0
75 1 kreverch
fi
76 5 kreverch
lastsnapshotReplicated=$(cat $FILE_NAME|grep lastsnapshotreplicated|cut -d "=" -f2)
77 1 kreverch
server=$(cat $FILE_NAME|grep server|cut -d "=" -f2)
78 1 kreverch
nbreplica=$(cat $FILE_NAME|grep nbreplica|cut -d "=" -f2)
79 1 kreverch
namereplica=$(cat $FILE_NAME|grep namereplica|cut -d "=" -f2)
80 1 kreverch
namevolfs=$(cat $FILE_NAME|grep "name="|cut -d "=" -f2)
81 1 kreverch
82 67 ltaulell
if $LOG;
83 67 ltaulell
then
84 67 ltaulell
  LOGFILE="$LOGDIR/${namevolfs//\//-}.log"
85 67 ltaulell
86 67 ltaulell
  if [ -f $LOGFILE ];
87 67 ltaulell
  then
88 67 ltaulell
    savelog -t -c $LOGFILEROTATE -q -n $LOGFILE
89 67 ltaulell
  fi
90 67 ltaulell
91 67 ltaulell
  # sauvegarde de stdout et stderr dans des fd (file descriptor) temporaires
92 67 ltaulell
  #+redirection de stdout vers $TMPFILE
93 67 ltaulell
  #+redirection de stderr vers stdout
94 67 ltaulell
  #+ = ">> $TMPFILE 2>&1"
95 67 ltaulell
  exec 6>&1 7>&2
96 67 ltaulell
  exec 1>$LOGFILE
97 67 ltaulell
  exec 2>&1
98 67 ltaulell
fi
99 67 ltaulell
100 1 kreverch
if [[ -z $namereplica ]] || [[ -z $nbreplica ]] || [[ -z $namevolfs ]]
101 1 kreverch
then
102 67 ltaulell
   err_exit "Incoherence data in $FILE_NAME"
103 1 kreverch
fi
104 1 kreverch
105 1 kreverch
echo "$getConfigSnapshotTool $namevolfs"
106 1 kreverch
getlistSnapshot=$($getConfigSnapshotTool $namevolfs)
107 1 kreverch
if [[ "$getlistSnapshot" == "" ]]
108 1 kreverch
then
109 67 ltaulell
  err_exit "Please, enable a snapshot configuration for $namevolfs"
110 1 kreverch
fi
111 1 kreverch
}
112 1 kreverch
113 1 kreverch
#****************************************
114 1 kreverch
#* function check server ssh connection
115 1 kreverch
#***************************************
116 1 kreverch
function checkServerConnection {
117 1 kreverch
118 67 ltaulell
ssh -o BatchMode=yes root@$server date
119 1 kreverch
120 9 kreverch
if [ "$?" != "0" ]
121 1 kreverch
then
122 67 ltaulell
  err_exit "SSH Connection server $server failed, please check the private/public key"
123 1 kreverch
fi
124 1 kreverch
125 1 kreverch
}
126 1 kreverch
127 66 ltaulell
function computePort {
128 66 ltaulell
# add a number, based on replica name, to mbuffer base port.
129 66 ltaulell
# This try to avoid problems, on multiple replicas cases, such as reception of
130 66 ltaulell
# different replicas on same mbuffer port: yeah, epic fail!
131 66 ltaulell
  BasePORT="1030"
132 66 ltaulell
  #for i in $(echo $snapshot2replicate| od -An -t u1); do j=$(($j+$i)); echo $j; done
133 66 ltaulell
  SumChar=0
134 66 ltaulell
  BaseChars=$(echo $snapshot2replicate | od -An -t u1)
135 66 ltaulell
  for i in $BaseChars
136 66 ltaulell
  do
137 66 ltaulell
    SumChar=$(($SumChar+$i))
138 66 ltaulell
  done
139 66 ltaulell
  PORT=$(($BasePORT+$SumChar))
140 66 ltaulell
}
141 66 ltaulell
142 66 ltaulell
143 12 kreverch
function checkCoherence {
144 49 kreverch
  ssh -o BatchMode=yes root@$server $BINZFS list $namereplica
145 12 kreverch
  if [ "$?" != "0" ]
146 12 kreverch
  then
147 12 kreverch
     return false
148 12 kreverch
  fi
149 12 kreverch
150 12 kreverch
}
151 12 kreverch
152 1 kreverch
function del_old_snapshot {
153 1 kreverch
#*** ETAPE SUPPRESSION DES SNAPSHOTS OBSELETES ***#
154 1 kreverch
if [[ "$server" == "" ]]
155 1 kreverch
then
156 1 kreverch
  echo ""
157 49 kreverch
  CPT_SNAP=$($BINZFS list -t snapshot -r $namereplica |cut -d" " -f1 |grep -i $namereplica\@ |wc -l)
158 46 kreverch
  echo "*** Number of snapshots for $namereplica is : $CPT_SNAP"
159 49 kreverch
  $BINZFS list -t snapshot -r $namereplica
160 1 kreverch
161 1 kreverch
  if [ $CPT_SNAP -gt $nbreplica ]
162 1 kreverch
  then
163 46 kreverch
    echo "*** Detection of the oldest snapshot"
164 49 kreverch
    for ID_SNAP_OLDER in $($BINZFS list -t snapshot -r $namereplica |cut -d" " -f1 |grep -i $namereplica\@)
165 1 kreverch
    do
166 46 kreverch
      echo "*** The oldest snapshot is : $ID_SNAP_OLDER"
167 1 kreverch
      break
168 1 kreverch
    done
169 49 kreverch
    $BINZFS destroy $ID_SNAP_OLDER
170 1 kreverch
    if [ $? -eq 0 ]
171 1 kreverch
    then
172 46 kreverch
       echo "*** Remove the snapshot $ID_SNAP_OLDER [OK]"
173 1 kreverch
    else
174 46 kreverch
      echo "/!\\ Remove the snapshot $ID_SNAP_OLDER [ERROR]."
175 1 kreverch
    fi
176 1 kreverch
  fi
177 1 kreverch
178 1 kreverch
else
179 1 kreverch
  echo ""
180 49 kreverch
  CPT_SNAP=$(ssh -o BatchMode=yes root@$server $BINZFS list -t snapshot -r $namereplica |cut -d" " -f1 |grep -i $namereplica\@ |wc -l)
181 46 kreverch
  echo "*** Number of snapshots for $namereplica is : $CPT_SNAP"
182 49 kreverch
  ssh -o BatchMode=yes root@$server $BINZFS list -t snapshot -r $namereplica
183 1 kreverch
184 1 kreverch
  if [ $CPT_SNAP -gt $nbreplica ]
185 1 kreverch
  then
186 46 kreverch
    echo "*** Detection of the oldest snapshot"
187 49 kreverch
    for ID_SNAP_OLDER in $(ssh -o BatchMode=yes root@$server $BINZFS list -t snapshot -r $namereplica |cut -d" " -f1 |grep -i $namereplica\@)
188 1 kreverch
    do
189 46 kreverch
      echo "*** The oldest snapshot is : $ID_SNAP_OLDER"
190 1 kreverch
      break
191 1 kreverch
    done
192 49 kreverch
    ssh -o BatchMode=yes root@$server $BINZFS destroy $ID_SNAP_OLDER
193 1 kreverch
    if [ $? -eq 0 ]
194 1 kreverch
    then
195 46 kreverch
       echo "*** Remove the snapshot $ID_SNAP_OLDER [OK]"
196 1 kreverch
    else
197 46 kreverch
      echo "/!\\ Remove the snapshot $ID_SNAP_OLDER [ERROR]."
198 1 kreverch
    fi
199 1 kreverch
  fi
200 1 kreverch
201 1 kreverch
fi
202 1 kreverch
#*** FIN ETAPE SUPPRESSION DES SNAPSHOTS OBSELETES ***#
203 1 kreverch
}
204 1 kreverch
205 1 kreverch
206 1 kreverch
#*************************************
207 1 kreverch
#* function FULL REPLICATION
208 1 kreverch
#*************************************
209 1 kreverch
function fullreplication {
210 27 kreverch
211 27 kreverch
parentdataset=$(awk '{
212 27 kreverch
              n = split($0, t, "/")
213 27 kreverch
              for (i = 0; ++i <= n-1;)
214 33 kreverch
                if (i == 1)
215 31 kreverch
                  printf t[i]
216 31 kreverch
                else
217 31 kreverch
                  printf "/"t[i]
218 27 kreverch
              }' <<< $(echo $namereplica))
219 27 kreverch
220 1 kreverch
if [[ "$server" == "" ]]
221 1 kreverch
then
222 27 kreverch
223 49 kreverch
    $BINZFS list $parentdataset
224 27 kreverch
    if [[ "?" != "0" ]]
225 27 kreverch
    then
226 49 kreverch
      $BINZFS create -p $parentdataset
227 27 kreverch
    fi
228 27 kreverch
229 49 kreverch
    $BINZFS send $snapshot2replicate | $BINZFS recv $namereplica
230 1 kreverch
    if [[ "$?" == "0" ]]
231 1 kreverch
    then
232 1 kreverch
       while read line
233 1 kreverch
       do
234 62 kreverch
            $(echo $line|sed -e "s:lastsnapshotreplicated=.*$:lastsnapshotreplicated=$snapshot2replicate:g" >>$TEMP_FILE_NAME)
235 1 kreverch
       done <<< "$(cat $FILE_NAME)"
236 62 kreverch
       /bin/rm $FILE_NAME
237 62 kreverch
       /bin/mv $TEMP_FILE_NAME $FILE_NAME
238 1 kreverch
       del_old_snapshot
239 67 ltaulell
       ok_exit
240 1 kreverch
    fi
241 1 kreverch
242 1 kreverch
else
243 1 kreverch
  checkServerConnection
244 1 kreverch
  if [[ "$snapshot2replicate" != "" ]]
245 1 kreverch
  then
246 49 kreverch
    ssh -o BatchMode=yes root@$server $BINZFS list $parentdataset
247 27 kreverch
    if [[ "?" != "0" ]]
248 27 kreverch
    then
249 49 kreverch
      ssh -o BatchMode=yes root@$server $BINZFS create -p $parentdataset
250 27 kreverch
    fi
251 27 kreverch
252 66 ltaulell
#    $BINZFS send $snapshot2replicate |ssh -o BatchMode=yes root@$server $BINZFS recv $namereplica
253 66 ltaulell
    computePort
254 66 ltaulell
    ssh -o BatchMode=yes root@$server "$BINMBUFFER -I $LOCALHOST:$PORT | $BINZFS recv $namereplica " &
255 66 ltaulell
    sleep 5s # allow server to be ready
256 66 ltaulell
    $BINZFS send $snapshot2replicate | $BINMBUFFER -O $server:$PORT
257 1 kreverch
    if [[ "$?" == "0" ]]
258 1 kreverch
    then
259 1 kreverch
       while read line
260 1 kreverch
       do
261 62 kreverch
            $(echo $line|sed -e "s:lastsnapshotreplicated=.*$:lastsnapshotreplicated=$snapshot2replicate:g" >>$TEMP_FILE_NAME)
262 1 kreverch
       done <<< "$(cat $FILE_NAME)"
263 62 kreverch
       /bin/rm $FILE_NAME
264 62 kreverch
       /bin/mv $TEMP_FILE_NAME $FILE_NAME
265 1 kreverch
       del_old_snapshot
266 67 ltaulell
       ok_exit
267 1 kreverch
    fi
268 1 kreverch
  fi
269 1 kreverch
fi
270 1 kreverch
271 1 kreverch
}
272 1 kreverch
273 1 kreverch
274 1 kreverch
275 1 kreverch
function incremental_replication {
276 1 kreverch
277 62 kreverch
echo "Start incremental replication for : $snasphot2replicate"
278 1 kreverch
if [[ "$server" == "" ]]
279 1 kreverch
then
280 62 kreverch
    $BINZFS send -i $lastsnapshotReplicated $namevolfs@$snasphot2replicate | $BINZFS recv $namereplica
281 62 kreverch
    snapshot2replicate="$namevolfs@$snasphot2replicate"
282 1 kreverch
    if [[ "$?" == "0" ]]
283 1 kreverch
    then
284 1 kreverch
       while read line
285 62 kreverch
       do
286 65 kreverch
            echo $line|sed -e "s:lastsnapshotreplicated=.*$:lastsnapshotreplicated=$snapshot2replicate:g" >>$TEMP_FILE_NAME
287 1 kreverch
       done <<< "$(cat $FILE_NAME)"
288 62 kreverch
       /bin/rm $FILE_NAME
289 62 kreverch
       /bin/mv $TEMP_FILE_NAME $FILE_NAME
290 1 kreverch
       del_old_snapshot
291 67 ltaulell
       ok_exit
292 1 kreverch
    fi
293 1 kreverch
else
294 1 kreverch
  checkServerConnection
295 62 kreverch
if [ "$snasphot2replicate" == "" ]
296 1 kreverch
then
297 67 ltaulell
   err_exit
298 1 kreverch
else
299 66 ltaulell
    #$BINZFS send -i $lastsnapshotReplicated $namevolfs@$snasphot2replicate | ssh -o BatchMode=yes root@$server $BINZFS recv $namereplica
300 66 ltaulell
    computePort
301 66 ltaulell
    ssh -o BatchMode=yes root@$server "$BINMBUFFER -I $LOCALHOST:$PORT | $BINZFS recv $namereplica " &
302 66 ltaulell
    sleep 5s # allow server to be ready
303 66 ltaulell
    $BINZFS send -i $lastsnapshotReplicated $namevolfs@$snasphot2replicate | $BINMBUFFER -O $server:$PORT
304 62 kreverch
    snapshot2replicate="$namevolfs@$snasphot2replicate"
305 1 kreverch
    if [[ "$?" == "0" ]]
306 1 kreverch
    then
307 1 kreverch
       while read line
308 1 kreverch
       do
309 62 kreverch
            $(echo $line|sed -e "s:lastsnapshotreplicated=.*$:lastsnapshotreplicated=$snapshot2replicate:g" >>$TEMP_FILE_NAME)
310 1 kreverch
       done <<< "$(cat $FILE_NAME)"
311 62 kreverch
       /bin/rm $FILE_NAME
312 62 kreverch
       /bin/mv $TEMP_FILE_NAME $FILE_NAME
313 1 kreverch
       del_old_snapshot
314 67 ltaulell
       ok_exit
315 1 kreverch
    fi
316 1 kreverch
  fi
317 1 kreverch
fi
318 1 kreverch
319 1 kreverch
}
320 1 kreverch
321 1 kreverch
322 1 kreverch
#****************************************
323 1 kreverch
#* NO INTERACTIVE MODE
324 1 kreverch
#****************************************
325 1 kreverch
function nointeractive {
326 1 kreverch
327 1 kreverch
#--- check and init env ---#
328 1 kreverch
initenv
329 1 kreverch
330 1 kreverch
fileconf=$($getConfigSnapshotTool $namevolfs|grep fileconf|cut -d "=" -f2)
331 49 kreverch
NBsnapshot=$($BINZFS list -H -r -t snapshot $namevolfs|wc -l)
332 1 kreverch
333 1 kreverch
if [[ $NBsnapshot -eq 0 ]]
334 1 kreverch
then
335 1 kreverch
   echo "no snapshot, start snapshoting ..."
336 33 kreverch
   $zfsSnapshot $fileconf
337 1 kreverch
fi
338 1 kreverch
339 12 kreverch
valchk=checkCoherence
340 41 kreverch
if [[ "$valchk" == "false" ]] && [[ "$lastsnapshotReplicated" != "" ]]
341 12 kreverch
then
342 41 kreverch
   echo "Replication by incremental snapshot is not possible : checkcoherence return false "
343 12 kreverch
   echo "Start FULL Replication ..."
344 12 kreverch
   while read line
345 12 kreverch
   do
346 12 kreverch
     snapshot2replicate=$(echo $line |echo $line |sed -e "s/ \+/ /g"|cut -d " " -f1)
347 49 kreverch
   done <<< "$($BINZFS list -H -r -t snapshot $namevolfs)"
348 12 kreverch
   fullreplication
349 12 kreverch
fi
350 12 kreverch
351 12 kreverch
352 1 kreverch
#--- FULL REPLICATION ---#
353 62 kreverch
if [[ $NBsnasphot -eq 1 ]] || [[ "$lastsnapshotReplicated" == "" ]]
354 1 kreverch
then
355 1 kreverch
   echo "Replication by incremental snapshot is not possible"
356 1 kreverch
   echo "Start FULL Replication ..."
357 1 kreverch
   while read line
358 1 kreverch
   do
359 1 kreverch
     snapshot2replicate=$(echo $line |echo $line |sed -e "s/ \+/ /g"|cut -d " " -f1)
360 49 kreverch
   done <<< "$($BINZFS list -H -r -t snapshot $namevolfs)"
361 1 kreverch
   fullreplication
362 1 kreverch
fi
363 1 kreverch
364 1 kreverch
#-- INCREMENTAL REPLICATION ---#
365 1 kreverch
if [[ $NBsnapshot -gt 1 ]]
366 1 kreverch
then
367 1 kreverch
  cpt=1
368 1 kreverch
  while read line
369 1 kreverch
  do
370 1 kreverch
371 1 kreverch
    if [[ $cpt -eq 1 ]]
372 1 kreverch
    then
373 62 kreverch
       snasphot2replicate=$(echo $line |sed -e "s/ \+/ /g"|cut -d " " -f1|cut -d "@" -f2)
374 62 kreverch
       echo $lastsnasphot
375 62 kreverch
       echo $snasphot2replicate
376 1 kreverch
       break
377 1 kreverch
    fi
378 1 kreverch
    cpt=$cpt+1
379 49 kreverch
  done <<< "$($BINZFS list -H -r -t snapshot $namevolfs|tac)"
380 1 kreverch
  lastsnapshot=$(echo $lastsnapshotReplicated |sed -e "s/ \+/ /g"|cut -d " " -f1|cut -d "@" -f2)
381 1 kreverch
382 62 kreverch
  if [ "$snasphot2replicate" == "$lastsnapshot" ]
383 1 kreverch
  then
384 67 ltaulell
     err_exit "Nothing to replicate"
385 1 kreverch
386 1 kreverch
  fi
387 59 kreverch
  if [ "$server" == "" ]
388 59 kreverch
  then
389 59 kreverch
     check_lastsnapshotReplica=$($BINZFS list -H -r -t snapshot $namereplica |grep $lastsnapshot|wc -l)
390 62 kreverch
     check_currentsnapshotReplica=$($BINZFS list -H -r -t snapshot $namereplica |grep $snasphot2replicate=|wc -l)
391 59 kreverch
  else
392 59 kreverch
     check_lastsnapshotReplica=$(ssh -o BatchMode=yes root@$server $BINZFS list -H -r -t snapshot $namereplica |grep $lastsnapshot|wc -l)
393 62 kreverch
     check_currentsnapshotReplica=$(ssh -o BatchMode=yes root@$server $BINZFS list -H -r -t snapshot $namereplica |grep $snasphot2replicate=|wc -l)
394 59 kreverch
  fi
395 1 kreverch
  if [[ $check_lastsnapshotReplica -eq 0 ]]
396 1 kreverch
  then
397 67 ltaulell
     err_exit "Incoherence, incremental replication failed : $lastsnapshotReplicated is missing"
398 1 kreverch
  fi
399 1 kreverch
400 1 kreverch
  if [[ $check_currentsnapshotReplica -eq 1 ]]
401 1 kreverch
  then
402 67 ltaulell
    err_exit "No replica to do, $lastSnapshot already exists"
403 1 kreverch
  fi
404 1 kreverch
fi
405 62 kreverch
 echo $snasphot2replicate
406 1 kreverch
incremental_replication
407 1 kreverch
}
408 1 kreverch
409 1 kreverch
nointeractive
410 1 kreverch
411 67 ltaulell
# restauration de stderr et stdout, fermeture des fd temporaires
412 67 ltaulell
exec 2>&7 7>&-
413 67 ltaulell
exec 1>&6 6>&-