blob: 568fda73b4b05179bd858e5c9897183aed9b0d5c (
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
#!/bin/sh
#set -e
do_snap_copy ()
{
fromdev="${1}"
todir="${2}"
snap_type="${3}"
size=$(fs_size "${fromdev}" "" "used")
if [ -b "${fromdev}" ]
then
log_success_msg "Copying snapshot ${fromdev} to ${todir}..."
# look for free mem
if [ -n "${HOMEMOUNTED}" -a "${snap_type}" = "HOME" ]
then
todev=$(awk -v pat="$(base_path ${todir})" '$2 == pat { print $1 }' /proc/mounts)
freespace=$(df -k | awk '/'${todev}'/{print $4}')
else
freespace=$(awk '/^MemFree:/{f=$2} /^Cached:/{c=$2} END{print f+c}' /proc/meminfo)
fi
tomount="/mnt/tmpsnap"
if [ ! -d "${tomount}" ]
then
mkdir -p "${tomount}"
fi
fstype=$(get_fstype "${fromdev}")
if [ -n "${fstype}" ]
then
# Copying stuff...
mount -o ro -t "${fstype}" "${fromdev}" "${tomount}" || log_warning_msg "Error in mount -t ${fstype} -o ro ${fromdev} ${tomount}"
cp -a "${tomount}"/* ${todir}
umount "${tomount}"
else
log_warning_msg "Unrecognized fstype: ${fstype} on ${fromdev}:${snap_type}"
fi
rmdir "${tomount}"
if echo ${fromdev} | grep -qs loop
then
losetup -d "${fromdev}"
fi
return 0
else
log_warning_msg "Unable to find the snapshot ${snap_type} medium"
return 1
fi
}
try_snap ()
{
# copy the contents of previously found snapshot to ${snap_mount}
# and remember the device and filename for resync on exit in live-boot.init
snapdata="${1}"
snap_mount="${2}"
snap_type="${3}"
snap_relpath="${4}"
if [ -z "${snap_relpath}" ]
then
# root snapshot, default usage
snap_relpath="/"
else
# relative snapshot (actually used just for "/home" snapshots)
snap_mount="${2}${snap_relpath}"
fi
if [ -n "${snapdata}" ] && [ ! -b "${snapdata}" ]
then
log_success_msg "found snapshot: ${snapdata}"
snapdev="$(echo ${snapdata} | cut -f1 -d ' ')"
snapback="$(echo ${snapdata} | cut -f2 -d ' ')"
snapfile="$(echo ${snapdata} | cut -f3 -d ' ')"
if ! try_mount "${snapdev}" "${snapback}" "ro"
then
break
fi
RES="0"
if echo "${snapfile}" | grep -qs '\(squashfs\|ext2\|ext3\|ext4\|jffs2\)'
then
# squashfs, jffs2 or ext2/ext3/ext4 snapshot
dev=$(get_backing_device "${snapback}/${snapfile}")
do_snap_copy "${dev}" "${snap_mount}" "${snap_type}"
RES="$?"
else
# cpio.gz snapshot
# Unfortunately klibc's cpio is incompatible with the
# rest of the world; everything else requires -u -d,
# while klibc doesn't implement them. Try to detect
# whether it's in use.
cpiopath="$(which cpio)" || true
if [ "$cpiopath" ] && grep -aq /lib/klibc "$cpiopath"
then
cpioargs=
else
cpioargs='--unconditional --make-directories'
fi
if [ -s "${snapback}/${snapfile}" ]
then
BEFOREDIR="$(pwd)"
cd "${snap_mount}" && zcat "${snapback}/${snapfile}" | $cpiopath $cpioargs --extract --preserve-modification-time --no-absolute-filenames --sparse 2>/dev/null
RES="$?"
cd "${BEFOREDIR}"
else
log_warning_msg "${snapback}/${snapfile} is empty, adding it for sync on reboot."
RES="0"
fi
if [ "${RES}" != "0" ]
then
log_warning_msg "failure to \"zcat ${snapback}/${snapfile} | $cpiopath $cpioargs --extract --preserve-modification-time --no-absolute-filenames --sparse\""
fi
fi
umount "${snapback}" || log_warning_msg "failure to \"umount ${snapback}\""
if [ "${RES}" != "0" ]
then
log_warning_msg "Impossible to include the ${snapfile} Snapshot file"
fi
elif [ -b "${snapdata}" ]
then
# Try to find if it could be a snapshot partition
dev="${snapdata}"
log_success_msg "found snapshot ${snap_type} device on ${dev}"
if echo "${dev}" | grep -qs loop
then
# strange things happens, user confused?
snaploop=$( losetup ${dev} | awk '{print $3}' | tr -d '()' )
snapfile=$(basename ${snaploop})
snapdev=$(awk -v pat="$( dirname ${snaploop})" '$2 == pat { print $1 }' /proc/mounts)
else
snapdev="${dev}"
fi
if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}"
then
log_warning_msg "Impossible to include the ${snap_type} Snapshot (i)"
return 1
else
if [ -n "${snapfile}" ]
then
# it was a loop device, user confused
umount ${snapdev}
fi
fi
else
log_warning_msg "Impossible to include the ${snap_type} Snapshot (o)"
return 1
fi
if [ -z ${PERSISTENCE_READONLY} ]
then
echo "export ${snap_type}SNAP=${snap_relpath}:${snapdev}:${snapfile}" >> snapshot.conf # for resync on reboot/halt
fi
return 0
}
|