-
Notifications
You must be signed in to change notification settings - Fork 1
/
pbs-mount-backup.sh
executable file
·110 lines (98 loc) · 3.2 KB
/
pbs-mount-backup.sh
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
#!/bin/sh
set -eu
DEFAULT_DISK="/dev/disk/by-id/virtio-mounted_backup"
DEFAULT_RAMSIZE="128"
DEFAULT_DMNAME="mounted_backup"
DEFAULT_TARGET="/mnt/backup"
usage() {
cat <<EOF
Usage:
$(basename "$0") mount [-d <disk>] [-r <RAM size>] [-n <DM name>] [-t <dir>]
$(basename "$0") umount [-n <DM name>]
<disk> The block device with the backup
Default: ${DEFAULT_DISK}
<RAM size> The size of the RAM disk to buffer writes, in MB
Default: ${DEFAULT_RAMSIZE}
<DM name> The name of the device mapper device to create
Default: ${DEFAULT_DMNAME}
<dir> Directory where to mount the backup
Default: ${DEFAULT_TARGET}
EOF
}
if [ "$#" = 0 ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
usage
exit 1
fi
MODE="$1"
shift 1
DISK="$DEFAULT_DISK"
RAMSIZE="$DEFAULT_RAMSIZE"
DMNAME="$DEFAULT_DMNAME"
TARGET="$DEFAULT_TARGET"
while getopts d:r:n:t:h OPT; do
case "$OPT" in
d) DISK="$OPTARG";;
r) RAMSIZE="$OPTARG";;
n) DMNAME="$OPTARG";;
t) TARGET="$OPTARG";;
h) usage; exit 0;;
\?) usage; exit 1;;
esac
done
shift $((OPTIND - 1))
DMPATH="/dev/mapper/${DMNAME}"
if [ "$MODE" = mount ]; then
if ! [ -b "$DISK" ]; then
echo "Backup disk not found: ${DISK}" >&2
echo "Did you mount it in PVE?" >&2
exit 1
fi
if [ -b "$DMPATH" ]; then
echo "DM name ${DMNAME} already taken. Did you forget to umount first?" >&2
exit 1
fi
modprobe brd rd_size=$((RAMSIZE*1024))
echo "0 $(blockdev --getsz "$DISK") snapshot ${DISK} /dev/ram1 P 8" | dmsetup create "$DMNAME"
partprobe "$DMPATH"
grep '^/' /proc/mounts | sort -k1 -r | while read -r ORIG_DEV MNT _; do
UUID="$(blkid -o value -s UUID "$ORIG_DEV")"
if [ -z "$UUID" ]; then
continue
fi
BACKUP_DEV="$(blkid -U "$UUID")"
case "$BACKUP_DEV" in
"$DMPATH"*)
BACKUP_MNT="${TARGET}/${MNT#/}"
mkdir -p "$TARGET"
if mount "$BACKUP_DEV" "$BACKUP_MNT"; then
echo "Mounted ${BACKUP_DEV} (assumed backup of ${ORIG_DEV} mounted on ${MNT}) to ${BACKUP_MNT}."
else
echo "Failed to mount ${BACKUP_DEV} (assumed backup of ${ORIG_DEV} mounted on ${MNT}) to ${BACKUP_MNT}."
fi
;;
*)
echo "Backup of ${ORIG_DEV} (mounted on ${MNT}) does not seem to be part of the backup."
;;
esac
done
if [ -z "${QEMU_AGENT:-}" ]; then
case "$-" in
*s*)
# script was passed via stdin, so we probably got called via
# QEMU guest agent
;;
*)
echo ""
echo "After usage, please execute '$(basename "$0") umount' (inside VM)"
;;
esac
fi
elif [ "$MODE" = "umount" ]; then
if ! [ -b "$DMPATH" ]; then
echo "DM device not found. Did you mount a backup?" >&2
exit 1
fi
awk "\$2 ~ \"^${TARGET%/}\" { print \$2 }" /proc/mounts | sort -r | xargs -r umount
dmsetup ls | grep "^${DMNAME}" | cut -f1 | tac | xargs dmsetup remove
rmmod brd
fi