3 # live-snapshot - utility to manage Debian Live systems snapshots
5 # This program mounts a device (fallback to /tmpfs under $MOUNTP
6 # and saves the /live/cow (or a different dir) filesystem in it for reuse
7 # in another live-initramfs session. Look at manpage for more info.
9 # Copyright (C) 2006-2008 Marco Amadori <marco.amadori@gmail.com>
10 # Copyright (C) 2008 Chris Lamb <chris@chris-lamb.co.uk>
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU General Public License as published by
14 # the Free Software Foundation; either version 2 of the License, or
15 # (at your option) any later version.
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 # On Debian systems, the complete text of the GNU General Public License
27 # can be found in /usr/share/common-licenses/GPL-2 file.
29 # declare here two vars from /etc/live.conf because of "set -u"
35 . /usr/share/initramfs-tools/scripts/live-helpers
37 LIVE_CONF="/etc/live.conf"
40 export USERNAME USERFULLNAME HOSTNAME
43 PROGRAM=$(basename "${EXECUTABLE}")
45 # Needs to be available at run and reboot time
48 # Permits multiple runs
49 MOUNTP="$(mktemp -d -p ${SAFE_TMPDIR} live-snapshot-mnt.XXXXXX)"
50 DEST="${MOUNTP}/live-sn.cpio.gz"
52 # Command line defaults and declarations
61 echo "${PROGRAM}: error:" ${@}
72 echo "${PROGRAM} - utility to perform snapshots of Debian Live systems"
74 echo "usage: ${PROGRAM} [-c|--cow DIRECTORY] [-d|--device DEVICE] [-o|--output FILE] [-t|--type TYPE]"
75 echo " ${PROGRAM} [-r|--resync-string STRING]"
76 echo " ${PROGRAM} [-f|--refresh]"
77 echo " ${PROGRAM} [-h|--help]"
78 echo " ${PROGRAM} [-u|--usage]"
79 echo " ${PROGRAM} [-v|--version]"
88 echo " -c, --cow: copy on write directory (default: ${SNAP_COW})."
89 echo " -d, --device: output snapshot device (default: ${SNAP_DEV:-auto})."
90 echo " -o, --output: output image file (default: ${DEST})."
91 echo " -r, --resync-string: internally used to resync previous made snapshots."
92 echo " -f, --refresh: try to sync a running snapshot."
93 echo " -t, --type: snapshot filesystem type. Options: \"squashfs\", \"ext2\", \"ext3\", \"jffs2\" or \"cpio\".gz archive (default: ${SNAP_TYPE})"
95 echo "Look at live-snapshot(1) man page for more information."
105 echo "Try \"${PROGRAM} --help\" for more information."
114 echo "Copyright (C) 2006 Marco Amadori <marco.amadori@gmail.com>"
115 echo "Copyright (C) 2008 Chris Lamb <chris@chris-lamb.co.uk>"
117 echo "This program is free software; you can redistribute it and/or modify"
118 echo "it under the terms of the GNU General Public License as published by"
119 echo "the Free Software Foundation; either version 2 of the License, or"
120 echo "(at your option) any later version."
122 echo "This program is distributed in the hope that it will be useful,"
123 echo "but WITHOUT ANY WARRANTY; without even the implied warranty of"
124 echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
125 echo "GNU General Public License for more details."
127 echo "You should have received a copy of the GNU General Public License"
128 echo "along with this program; if not, write to the Free Software"
129 echo "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA"
131 echo "On Debian systems, the complete text of the GNU General Public License"
132 echo "can be found in /usr/share/common-licenses/GPL-2 file."
134 echo "Homepage: <http://debian-live.alioth.debian.org/>"
142 if [ -n "${ROOTSNAP}" ]; then
143 "${EXECUTABLE}" --resync-string="${ROOTSNAP}"
147 if [ -n "${HOMESNAP}" ]; then
148 "${EXECUTABLE}" --resync-string="${HOMESNAP}"
154 echo "No autoconfigured snapshots found at boot;" > /dev/null 1>&2
155 echo "(no resync string in ${LIVE_CONF})." > /dev/null 1>&2
164 ARGUMENTS="$(getopt --longoptions cow:,device:,output,resync-string:,refresh,type:,help,usage,version --name=${PROGRAM} --options c:d:o:t:r:fhuv --shell sh -- ${ARGS})"
166 eval set -- "${ARGUMENTS}"
192 SNAP_RESYNC_STRING="${2}"
219 Error "internal error."
228 # Parse resync string
229 if [ -n "${SNAP_RESYNC_STRING}" ]
231 SNAP_COW=$(echo "${SNAP_RESYNC_STRING}" | cut -f1 -d ':')
232 SNAP_DEV=$(echo "${SNAP_RESYNC_STRING}" | cut -f2 -d ':')
233 DEST="${MOUNTP}/$(echo ${SNAP_RESYNC_STRING} | cut -f3 -d ':')"
252 Error "unrecognized resync string"
255 elif [ -z "${SNAP_OUTPUT}" ]
257 # Set target file based on image
258 case "${SNAP_TYPE}" in
260 DEST="${MOUNTP}/live-sn.cpio.gz"
264 DEST="${MOUNTP}/live-sn.${SNAP_TYPE}"
268 DEST="${MOUNTP}/live-sn.ext2"
272 DEST="${SNAP_OUTPUT}"
278 case "${SNAP_TYPE}" in
279 cpio|squashfs|jffs2|ext2|ext3)
283 Error "invalid filesystem type \"${SNAP_TYPE}\""
287 if [ ! -d "${SNAP_COW}" ]
289 Error "${SNAP_COW} is not a directory"
292 if [ "$(id -u)" -ne 0 ]
294 Error "you are not root"
300 case "${SNAP_DEV}" in
303 mount -t tmpfs -o rw tmpfs "${MOUNTP}"
307 if [ -b "${SNAP_DEV}" ]
309 try_mount "${SNAP_DEV}" "${MOUNTP}" rw
317 case "${SNAP_TYPE}" in
319 EXCLUDE_LIST="$(mktemp -p ${SAFE_TMPDIR} live-snapshot-exclude-list.XXXXXX)"
320 echo "./${EXCLUDE_LIST}" > "${EXCLUDE_LIST}"
322 find . -name '*.wh.*' >> "${EXCLUDE_LIST}"
324 mksquashfs "${SNAP_COW}" "${DEST}" -ef "${EXCLUDE_LIST}"
325 rm -f "${EXCLUDE_LIST}"
329 ( cd "${SNAP_COW}" && find . -path '*.wh.*' -prune -o -print0 | cpio --quiet -o0 -H newc | gzip -9c > "${DEST}" ) || exit 1
333 DU_DIM="$(du -ks ${SNAP_COW} | cut -f1)"
334 REAL_DIM="$(expr ${DU_DIM} + ${DU_DIM} / 20)" # Just 5% more to be sure, need something more sophistcated here...
335 genext2fs --size-in-blocks=${REAL_DIM} --reserved-percentage=0 --root="${SNAP_COW}" "${DEST}"
339 mkfs.jffs2 --root="${SNAP_COW}" --output="${DEST}"
346 if [ -z "${SNAP_RESYNC_STRING}" ] && echo "${DEST}" | grep -q "${MOUNTP}"
348 echo "${DEST} is present on ${MOUNTP}, therefore no automatic unmounting the latter." > /dev/null 1>&2