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.
31 . /usr/share/initramfs-tools/scripts/live-helpers
34 export USERNAME USERFULLNAME HOSTNAME
36 PROGRAM="$(basename $0)"
38 # Needs to be available at run and reboot time
41 # Permits multiple runs
42 MOUNTP="$(mktemp -d -p ${SAFE_TMPDIR} live-snapshot-mnt.XXXXXX)"
43 DEST="${MOUNTP}/live-sn.cpio.gz"
45 # Command line defaults and declarations
54 echo "${PROGRAM}: error:" ${@}
65 echo "${PROGRAM} - utility to perform snapshots of Debian Live systems"
67 echo "usage: ${PROGRAM} [-c|--cow DIRECTORY] [-d|--device DEVICE] [-o|--output FILE] [-t|--type TYPE]"
68 echo " ${PROGRAM} [-r|--resync-string STRING]"
69 echo " ${PROGRAM} [-h|--help]"
70 echo " ${PROGRAM} [-u|--usage]"
71 echo " ${PROGRAM} [-v|--version]"
80 echo " -c, --cow: copy on write directory (default: ${SNAP_COW})."
81 echo " -d, --device: output snapshot device (default: ${SNAP_DEV:-auto})."
82 echo " -o, --output: output image file (default: ${DEST})."
83 echo " -r, --resync-string: internally used to resync previous made snapshots."
84 echo " -t, --type: snapshot filesystem type. Options: \"squashfs\", \"ext2\", \"ext3\", \"jffs2\" or \"cpio\".gz archive (default: ${SNAP_TYPE})"
86 echo "Look at live-snapshot(1) man page for more information."
96 echo "Try \"${PROGRAM} --help\" for more information."
105 echo "Copyright (C) 2006 Marco Amadori <marco.amadori@gmail.com>"
106 echo "Copyright (C) 2008 Chris Lamb <chris@chris-lamb.co.uk>"
108 echo "This program is free software; you can redistribute it and/or modify"
109 echo "it under the terms of the GNU General Public License as published by"
110 echo "the Free Software Foundation; either version 2 of the License, or"
111 echo "(at your option) any later version."
113 echo "This program is distributed in the hope that it will be useful,"
114 echo "but WITHOUT ANY WARRANTY; without even the implied warranty of"
115 echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
116 echo "GNU General Public License for more details."
118 echo "You should have received a copy of the GNU General Public License"
119 echo "along with this program; if not, write to the Free Software"
120 echo "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA"
122 echo "On Debian systems, the complete text of the GNU General Public License"
123 echo "can be found in /usr/share/common-licenses/GPL-2 file."
125 echo "Homepage: <http://debian-live.alioth.debian.org/>"
134 ARGUMENTS="$(getopt --longoptions cow:,device:,output,resync-string:,type:,help,usage,version --name=${PROGRAM} --options c:d:o:t:r:,h,u,v --shell sh -- ${ARGS})"
136 eval set -- "${ARGUMENTS}"
162 SNAP_RESYNC_STRING="${2}"
184 Error "internal error."
193 # Parse resync string
194 if [ -n "${SNAP_RESYNC_STRING}" ]
196 SNAP_COW=$(echo "${SNAP_RESYNC_STRING}" | cut -f1 -d ':')
197 SNAP_DEV=$(echo "${SNAP_RESYNC_STRING}" | cut -f2 -d ':')
198 DEST="${MOUNTP}/$(echo ${SNAP_RESYNC_STRING} | cut -f3 -d ':')"
217 Error "unrecognized resync string"
220 elif [ -z "${SNAP_OUTPUT}" ]
222 # Set target file based on image
223 case "${SNAP_TYPE}" in
225 DEST="${MOUNTP}/live-sn.cpio.gz"
229 DEST="${MOUNTP}/live-sn.${SNAP_TYPE}"
233 DEST="${MOUNTP}/live-sn.ext2"
237 DEST="${SNAP_OUTPUT}"
243 case "${SNAP_TYPE}" in
244 cpio|squashfs|jffs2|ext2|ext3)
248 Error "invalid filesystem type \"${SNAP_TYPE}\""
252 if [ ! -d "${SNAP_COW}" ]
254 Error "${SNAP_COW} is not a directory"
257 if [ "$(id -u)" -ne 0 ]
259 Error "you are not root"
265 case "${SNAP_DEV}" in
268 mount -t tmpfs -o rw tmpfs "${MOUNTP}"
272 if [ -b "${SNAP_DEV}" ]
274 try_mount "${SNAP_DEV}" "${MOUNTP}" rw
282 case "${SNAP_TYPE}" in
284 EXCLUDE_LIST="$(mktemp -p ${SAFE_TMPDIR} live-snapshot-exclude-list.XXXXXX)"
285 echo "./${EXCLUDE_LIST}" > "${EXCLUDE_LIST}"
287 find . -name '*.wh.*' >> "${EXCLUDE_LIST}"
289 mksquashfs "${SNAP_COW}" "${DEST}" -ef "${EXCLUDE_LIST}"
290 rm -f "${EXCLUDE_LIST}"
294 ( cd "${SNAP_COW}" && find . -path '*.wh.*' -prune -o -print0 | cpio --quiet -o0 -H newc | gzip -9c > "${DEST}" ) || exit 1
298 DU_DIM="$(du -ks ${SNAP_COW} | cut -f1)"
299 REAL_DIM="$(expr ${DU_DIM} + ${DU_DIM} / 20)" # Just 5% more to be sure, need something more sophistcated here...
300 genext2fs --size-in-blocks=${REAL_DIM} --reserved-percentage=0 --root="${SNAP_COW}" "${DEST}"
304 mkfs.jffs2 --root="${SNAP_COW}" --output="${DEST}"
311 if [ -z "${SNAP_RESYNC_STRING}" ] && echo "${DEST}" | grep -q "${MOUNTP}"
313 echo "${DEST} is present on ${MOUNTP}, therefore no automatic unmounting the latter." > /dev/null 1>&2