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)"
45 DEST="${MOUNTP}/live-sn.cpio.gz"
47 DESKTOP_LINK="/home/${USERNAME}/Desktop/live-snapshot"
52 echo "${PROGRAM}: error:" ${@}
63 echo "${PROGRAM} - utility to perform snapshots of Debian Live systems"
65 echo "usage: ${PROGRAM} [-c|--cow DIRECTORY] [-d|--device DEVICE] [-o|--output FILE] [-t|--type TYPE]"
66 echo " ${PROGRAM} [-r|--resync-string STRING]"
67 echo " ${PROGRAM} [-h|--help]"
68 echo " ${PROGRAM} [-u|--usage]"
69 echo " ${PROGRAM} [-v|--version]"
78 echo " -c, --cow: copy on write directory (default: ${SNAP_COW})."
79 echo " -d, --device: output snapshot device (default: ${SNAP_DEV:-auto})."
80 echo " -o, --output: output image file (default: ${DEST})."
81 echo " -r, --resync-string: internally used to resync previous made snapshots."
82 echo " -t, --type: snapshot filesystem type. Options: \"squashfs\", \"ext2\", \"ext3\", \"jffs2\" or \"cpio\".gz archive (default: ${SNAP_TYPE})"
84 echo "Look at live-snapshot(1) man page for more information."
94 echo "Try \"${PROGRAM} --help\" for more information."
103 echo "Copyright (C) 2006 Marco Amadori <marco.amadori@gmail.com>"
104 echo "Copyright (C) 2008 Chris Lamb <chris@chris-lamb.co.uk>"
106 echo "This program is free software; you can redistribute it and/or modify"
107 echo "it under the terms of the GNU General Public License as published by"
108 echo "the Free Software Foundation; either version 2 of the License, or"
109 echo "(at your option) any later version."
111 echo "This program is distributed in the hope that it will be useful,"
112 echo "but WITHOUT ANY WARRANTY; without even the implied warranty of"
113 echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
114 echo "GNU General Public License for more details."
116 echo "You should have received a copy of the GNU General Public License"
117 echo "along with this program; if not, write to the Free Software"
118 echo "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA"
120 echo "On Debian systems, the complete text of the GNU General Public License"
121 echo "can be found in /usr/share/common-licenses/GPL-2 file."
123 echo "Homepage: <http://debian-live.alioth.debian.org/>"
130 dir1="$(Base_path ${1})"
131 dir2="$(Base_path ${2})"
133 if [ "${dir1}" = "${dir2}" ]
145 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})"
147 eval set -- "${ARGUMENTS}"
173 SNAP_RESYNC_STRING="${2}"
195 Error "internal error."
204 # Parse resync string
205 if [ -n "${SNAP_RESYNC_STRING}" ]
207 SNAP_COW=$(echo "${SNAP_RESYNC_STRING}" | cut -f1 -d ':')
208 SNAP_DEV=$(echo "${SNAP_RESYNC_STRING}" | cut -f2 -d ':')
209 DEST=$(echo "${SNAP_RESYNC_STRING}" | cut -f3 -d ':')
228 Error "unrecognized resync string"
232 # Set target file based on image
233 case "${SNAP_TYPE}" in
235 DEST="${MOUNTP}/live-sn.cpio.gz"
239 DEST="${MOUNTP}/live-sn.${SNAP_TYPE}"
243 DEST="${MOUNTP}/live-sn.ext2"
251 case "${SNAP_TYPE}" in
252 cpio|squashfs|jffs2|ext2|ext3)
256 Error "invalid filesystem type \"${SNAP_TYPE}\""
260 if [ ! -d "${SNAP_COW}" ]
262 Error "${SNAP_COW} is not a directory"
265 if [ "$(id -u)" -ne 0 ]
267 Error "you are not root"
275 case "${SNAP_DEV}" in
278 mount -t tmpfs -o rw tmpfs "${MOUNTP}"
282 if [ -b "${SNAP_DEV}" ]
284 try_mount "${SNAP_DEV}" "${MOUNTP}" rw
292 case "${SNAP_TYPE}" in
294 EXCLUDE_LIST="$(mktemp -p ${SAFE_TMPDIR} live-snapshot-exclude-list.XXXXXX)"
295 echo "./${EXCLUDE_LIST}" > "${EXCLUDE_LIST}"
297 find . -name '*.wh.*' >> "${EXCLUDE_LIST}"
299 mksquashfs "${SNAP_COW}" "${DEST}" -ef "${EXCLUDE_LIST}"
300 rm -f "${EXCLUDE_LIST}"
304 ( cd "${SNAP_COW}" && find . -path '*.wh.*' -prune -o -print0 | cpio --quiet -o0 -H newc | gzip -9c > "${DEST}" ) || exit 1
308 DU_DIM="$(du -ks ${SNAP_COW} | cut -f1)"
309 REAL_DIM="$(expr ${DU_DIM} + ${DU_DIM} / 20)" # Just 5% more to be sure, need something more sophistcated here...
310 genext2fs --size-in-blocks=${REAL_DIM} --reserved-percentage=0 --root="${SNAP_COW}" "${DEST}"
314 mkfs.jffs2 --root="${SNAP_COW}" --output="${DEST}"
321 if echo "${DEST}" | grep -q "${MOUNTP}"
323 echo "${DEST} is present on ${MOUNTP}, therefore no automatic unmounting the latter." > /dev/null 1>&2