dsnap-sync: rework BTRFS_PIPE handling
* redirect any output of btrfs send/receive to a PIPE * on failure, output saved messages to this PIPE * cleanup PIPE on program termination Signed-off-by: Ralf Zerres <ralf.zerres@networkx.de>
This commit is contained in:
104
bin/dsnap-sync
Normal file → Executable file
104
bin/dsnap-sync
Normal file → Executable file
@@ -36,21 +36,21 @@ SNAPPER_CONFIG=/etc/default/snapper
|
||||
SNAPPER_TEMPLATE_DIR=/etc/snapper/config-templates
|
||||
SNAPPER_CONFIG_DIR=/etc/snapper/configs
|
||||
|
||||
# define fifo pipes
|
||||
TMPDIR_PIPE=$(mktemp --tmpdir=$XDG_RUNTIME_DIR/$progname -d)
|
||||
PIPE=$TMPDIR_PIPE/$progname.out
|
||||
# Create TEMPDIR
|
||||
test ! -d $XDG_RUNTIME_DIR/$progname && mkdir -p $XDG_RUNTIME_DIR/$progname
|
||||
mkfifo $PIPE
|
||||
systemd-cat --identifier="$progname" < $PIPE &
|
||||
TMPDIR=$(mktemp --tmpdir=$XDG_RUNTIME_DIR/$progname -d)
|
||||
|
||||
BTRFS_PIPE=$TMPDIR_PIPE/btrfs.out
|
||||
BTRFS_SEND_PIPE=$TMPDIR_PIPE/btrfs_send.out
|
||||
BTRFS_RECIEVE_PIPE=$TMPDIR_PIPE/btrfs_recieve.out
|
||||
#mkfifo $BTRFS_PIPE
|
||||
#systemd-cat --identifier="btrfs-pipe" < $BTRFS_PIPE &
|
||||
# define fifo pipes
|
||||
#PIPE=$TMPDIR/$progname.out
|
||||
#mkfifo $PIPE
|
||||
#systemd-cat --identifier="$progname" < $PIPE &
|
||||
|
||||
BTRFS_PIPE=$TMPDIR/btrfs.fifo
|
||||
test -p $BTRFS_PIPE && mkfifo $BTRFS_PIPE
|
||||
|
||||
# redirect descriptors to given pipes
|
||||
exec 3>$PIPE 4>$BTRFS_PIPE
|
||||
#exec 3>$PIPE
|
||||
4>$BTRFS_PIPE
|
||||
|
||||
# global variables
|
||||
args=
|
||||
@@ -1447,6 +1447,7 @@ run_backup () {
|
||||
if [ $donotify -gt 0 ]; then
|
||||
notify_info "Backup in progress" "NOTE: Skipping '$selected_config' configuration."
|
||||
fi
|
||||
# go for next configuration
|
||||
i=$(($i+1))
|
||||
continue
|
||||
fi
|
||||
@@ -1497,10 +1498,14 @@ run_backup () {
|
||||
verify_snapper_structure "backup_root=$backup_root" "snapper_target_config=$snapper_target_config" "snapper_target_id=$snapper_target_id" "remote=$remote"
|
||||
;;
|
||||
btrfs-archive)
|
||||
# check for last common snapshot
|
||||
snapper_source_id=$snapper_source_sync_id
|
||||
snapper_source_snapshot=$SUBVOLUME/.snapshots/$snapper_source_sync_id/$snapper_snapshot_name
|
||||
snapper_source_info=$SUBVOLUME/.snapshots/$snapper_source_sync_id/info.xml
|
||||
if [ $snapper_source_sync_id -eq 0 ]; then
|
||||
create_snapshot
|
||||
else
|
||||
# check for last common snapshot
|
||||
snapper_source_id=$snapper_source_sync_id
|
||||
snapper_source_snapshot=$SUBVOLUME/.snapshots/$snapper_source_sync_id/$snapper_snapshot_name
|
||||
snapper_source_info=$SUBVOLUME/.snapshots/$snapper_source_sync_id/info.xml
|
||||
fi
|
||||
|
||||
# targets backup location will save the snapshots in the subdirectory (snapshot-id)
|
||||
# the snapshot is either the base snapshot (flat-file), or an incremental snapshot (btrfs-send stream)
|
||||
@@ -1541,7 +1546,6 @@ run_backup () {
|
||||
#fi
|
||||
|
||||
# need to substitue btrfs 'x.yyGiB' suffix, since pv will need 'xG'
|
||||
#if [ $snapper_source_snapshot_size -ge 1073741824 ]; then
|
||||
if [ $snapper_source_snapshot_size -ge 1048576 ]; then
|
||||
snapper_source_snapshot_size=$(btrfs qgroup show -f --gbytes $snapper_source_snapshot 2>/dev/null \
|
||||
| awk 'FNR>2 { gsub(/.[0-9][0-9]GiB/,"G"); print $2}')
|
||||
@@ -1592,28 +1596,29 @@ run_backup () {
|
||||
|
||||
case $selected_fstype in
|
||||
btrfs)
|
||||
cmd="btrfs send $btrfs_verbose_flag $snapper_source_snapshot 2>$BTRFS_SEND_PIPE \
|
||||
cmd="btrfs send $btrfs_verbose_flag $snapper_source_snapshot 2>4 \
|
||||
| $cmd_pv \
|
||||
$cmd_ionice $ssh btrfs receive $btrfs_verbose_flag $snapper_target_snapshot/ 2>$BTRFS_RECIEVE_PIPE"
|
||||
$cmd_ionice $ssh btrfs receive $btrfs_verbose_flag $snapper_target_snapshot/ 1>4 2>&1"
|
||||
;;
|
||||
*)
|
||||
# Can't use btrfs receive, since target filesystem can't support btrfs snapshot feature
|
||||
snapper_target_stream=${snapper_target_id}_${archive_type}.btrfs
|
||||
if [ ! -f $snapper_target_snapshot/$snapper_target_stream ]; then
|
||||
if [ -z $remote ]; then
|
||||
cmd="btrfs send $btrfs_verbose_flag $snapper_source_snapshot 2>$BTRFS_SEND_PIPE \
|
||||
cmd="btrfs send $btrfs_verbose_flag $snapper_source_snapshot 2>/dev/null \
|
||||
| $cmd_pv \
|
||||
$cmd_ionice cat > $snapper_target_snapshot/$snapper_target_stream 2>$BTRFS_RECIEVE_PIPE"
|
||||
$cmd_ionice cat > $snapper_target_snapshot/$snapper_target_stream"
|
||||
else
|
||||
cmd="btrfs send $btrfs_verbose_flag $snapper_source_snapshot 2>$BTRFS_SEND_PIPE \
|
||||
cmd="btrfs send $btrfs_verbose_flag $snapper_source_snapshot 2>/dev/null \
|
||||
| $cmd_pv \
|
||||
$cmd_ionice $ssh 'cat > $snapper_target_snapshot/$snapper_target_stream' 2>$BTRFS_RECIEVE_PIPE"
|
||||
$cmd_ionice $ssh 'cat > $snapper_target_snapshot/$snapper_target_stream' 2>4"
|
||||
fi
|
||||
else
|
||||
if [ $verbose -ge 2 ]; then
|
||||
printf "${RED}BTRFS_Stream: %s${NO_COLOR} already saved.\n" \
|
||||
"$snapper_target_snapshot/$snapper_target_stream"
|
||||
fi
|
||||
# go for next configuration
|
||||
i=$(($i+1))
|
||||
continue
|
||||
fi
|
||||
@@ -1631,11 +1636,13 @@ run_backup () {
|
||||
if [ $verbose -ge 3 ]; then
|
||||
printf "cmd: '%s'\n" "$cmd"
|
||||
fi
|
||||
$(eval $cmd) 1>/dev/null
|
||||
$(eval $cmd)
|
||||
if [ "$?" -gt 0 ]; then
|
||||
printf "${RED}BTRFS_SEND_PIPE: %s${NO_COLOR}\n" "$(cat $BTRFS_SEND_PIPE)"
|
||||
printf "${RED}BTRFS_RECIEVE_PIPE: %s${NO_COLOR}\n" "$(cat $BTRFS_RECIEVE_PIPE)"
|
||||
die "btrfs pipe error."
|
||||
printf "${RED}BTRFS_PIPE: %s${NO_COLOR}\n" "$(cat <4)"
|
||||
# go for next configuration
|
||||
i=$(($i+1))
|
||||
continue
|
||||
#die "btrfs pipe error."
|
||||
fi
|
||||
else
|
||||
# source holds synced snapshots
|
||||
@@ -1707,21 +1714,21 @@ run_backup () {
|
||||
# subvolume on the source and the receiving location (the parent-id).
|
||||
# using "btrfs send -p" instead of "btrfs send -c", then no parent search would be
|
||||
# needed (Andreij explained in: https://www.spinics.net/lists/linux-btrfs/msg69369.html)
|
||||
cmd="btrfs send $btrfs_verbose_flag -p $snapper_common_sync_snapshot $snapper_source_snapshot 2>$BTRFS_PIPE \
|
||||
cmd="btrfs send $btrfs_verbose_flag -p $snapper_common_sync_snapshot $snapper_source_snapshot 2>4 \
|
||||
| $cmd_pv \
|
||||
$cmd_ionice $ssh btrfs receive $btrfs_verbose_flag $snapper_target_snapshot/ 2>$BTRFS_PIPE"
|
||||
$cmd_ionice $ssh btrfs receive $btrfs_verbose_flag $snapper_target_snapshot/ 1>4 2>&1"
|
||||
;;
|
||||
*)
|
||||
# Can't use btrfs receive, since target filesystem can't support btrfs snapshot feature
|
||||
snapper_target_stream=${snapper_target_id}_incremental.btrfs
|
||||
if [ -z $remote ]; then
|
||||
cmd="btrfs send $btrfs_verbose_flag -p $snapper_common_sync_snapshot $snapper_source_snapshot 2>$BTRFS_SEND_PIPE \
|
||||
cmd="btrfs send $btrfs_verbose_flag -p $snapper_common_sync_snapshot $snapper_source_snapshot 2>4 \
|
||||
| $cmd_pv \
|
||||
$cmd_ionice cat > $snapper_target_snapshot/$snapper_target_stream 2>$BTRFS_PIPE"
|
||||
$cmd_ionice cat > $snapper_target_snapshot/$snapper_target_stream 2>4"
|
||||
else
|
||||
cmd="btrfs send $btrfs_verbose_flag -p $snapper_common_sync_snapshot $snapper_source_snapshot 2>$BTRFS_SEND_PIPE \
|
||||
cmd="btrfs send $btrfs_verbose_flag -p $snapper_common_sync_snapshot $snapper_source_snapshot 2>4 \
|
||||
| $cmd_pv \
|
||||
$cmd_ionice $ssh 'cat > $snapper_target_snapshot/$snapper_target_stream' 2>$BTRFS_PIPE"
|
||||
$cmd_ionice $ssh 'cat > $snapper_target_snapshot/$snapper_target_stream' 2>4"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@@ -1734,21 +1741,19 @@ run_backup () {
|
||||
if [ $verbose -ge 3 ]; then
|
||||
printf "${GREEN}btrfs command:${NO_COLOR} '%s'\n" "$cmd"
|
||||
fi
|
||||
$(eval $cmd) 2>&1 1>/dev/null
|
||||
case $? in
|
||||
$(eval $cmd)
|
||||
ret=$?
|
||||
case $ret in
|
||||
0)
|
||||
;;
|
||||
127)
|
||||
printf "${MAGENTA}btrfs pipe return-code: ${GREEN}'127'${NO_COLOR}\n"
|
||||
;;
|
||||
*)
|
||||
printf "${RED}btfs pipe ERROR!\n"
|
||||
printf "${RED}BTRFS_PIPE: %s${NO_COLOR}\n" "$(cat $BTRFS_PIPE)"
|
||||
#printf "${RED}BTRFS_SEND_PIPE: %s${NO_COLOR}\n" "$(cat $BTRFS_SEND_PIPE)"
|
||||
#printf "${RED}BTRFS_RECIEVE_PIPE: %s${NO_COLOR}\n" "$(cat $BTRFS_RECIEVE_PIPE)"
|
||||
#die "btrfs pipe error."
|
||||
# go for next configuration
|
||||
printf "${RED}btfs pipe ERROR: '%s'!\n" "$ret"
|
||||
printf "${RED}BTRFS_PIPE: %s${NO_COLOR}\n" "$(cat <4)"
|
||||
run_cleanup ${selected_config}
|
||||
# go for next configuration
|
||||
i=$(($i+1))
|
||||
continue
|
||||
;;
|
||||
@@ -1863,7 +1868,6 @@ run_finalize () {
|
||||
snapper_source_info=$(eval echo \$snapper_source_info_$i)
|
||||
snapper_target_config=$(eval echo \$snapper_target_config_$i)
|
||||
snapper_target_snapshot=$(eval echo \$snapper_target_snapshot_$i)
|
||||
#tape_id=$(eval echo \$tape_id_$i)
|
||||
|
||||
# It's important not to change the values of the snapper key/value pairs ($userdata)
|
||||
# which is stored in snappers info.xml file of the source snapshot.
|
||||
@@ -1894,7 +1898,7 @@ run_finalize () {
|
||||
local ii_sleep=15
|
||||
|
||||
# Solution2: kill running snapperd
|
||||
# -> will restart and sync; any unseen interdependencies
|
||||
# -> will restart and sync any unseen dependencies
|
||||
snapperd_pid=$(eval $ssh pgrep snapperd)
|
||||
if [ $verbose -ge 3 ]; then
|
||||
printf "${MAGENTA}Kill runnint ${GREEN}snapperd${MAGENTA} on target id:${GREEN}'%s'${NO_COLOR} ...\n" \
|
||||
@@ -2008,7 +2012,6 @@ run_finalize () {
|
||||
if [ $verbose -ge 3 ]; then
|
||||
printf "${MAGENTA}Tagging snapper metadata${NO_COLOR} for snapper id ${GREEN}'%s'${NO_COLOR} on source for configuration ${GREEN}'%s'${NO_COLOR} ...\n" \
|
||||
"$snapper_source_id" "$selected_config"
|
||||
#printf "calling: '%s'\n" "$(eval $cmd)"
|
||||
printf "calling: '%s'\n" "$cmd"
|
||||
fi
|
||||
ret=$(eval "$cmd")
|
||||
@@ -2018,7 +2021,7 @@ run_finalize () {
|
||||
sync
|
||||
fi
|
||||
if [ ${#snapper_source_sync_id} -gt 0 ]; then
|
||||
# TODO: no method to remove userdata pair, use awk
|
||||
# TODO: no snapper method to remove userdata pair, use awk
|
||||
cmd="snapper --config $selected_config modify \
|
||||
--description \"$snap_description_finished\" \
|
||||
--userdata \"important=no\" \
|
||||
@@ -2952,15 +2955,16 @@ run_config_preparation
|
||||
run_backup
|
||||
|
||||
# cleanup
|
||||
#if [ -f $PIPE ]; then
|
||||
# rm -f $PIPE || die "Failed to cleanup temporary pipe '%s'\n" "$PIPE"
|
||||
#fi
|
||||
if [ -d $TMPDIR_PIPE ]; then
|
||||
rm -rf $TMPDIR_PIPE || die "Failed to cleanup temporary directory '%s'\n" "$TMPDIR_PIPE"
|
||||
if [ -d $TMPDIR ]; then
|
||||
rm -rf $TMPDIR || die "Failed to cleanup temporary directory '%s'\n" "$TMPDIR"
|
||||
#printf "${RED}TODO: ${NO_COLOR}Will remove $TMPDIR}"
|
||||
fi
|
||||
|
||||
printf "${BLUE}Backups done!${NO_COLOR}\n"
|
||||
exec 3>&-
|
||||
|
||||
# close the read file descriptor
|
||||
#exec 3>&-
|
||||
exec 4>&-
|
||||
|
||||
if [ $donotify -gt 0 ]; then
|
||||
if [ "$uuid_cmdline" != "none" ]; then
|
||||
|
||||
Reference in New Issue
Block a user