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 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>"
105 echo "This program is free software; you can redistribute it and/or modify"
106 echo "it under the terms of the GNU General Public License as published by"
107 echo "the Free Software Foundation; either version 2 of the License, or"
108 echo "(at your option) any later version."
110 echo "This program is distributed in the hope that it will be useful,"
111 echo "but WITHOUT ANY WARRANTY; without even the implied warranty of"
112 echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
113 echo "GNU General Public License for more details."
115 echo "You should have received a copy of the GNU General Public License"
116 echo "along with this program; if not, write to the Free Software"
117 echo "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA"
119 echo "On Debian systems, the complete text of the GNU General Public License"
120 echo "can be found in /usr/share/common-licenses/GPL-2 file."
122 echo "Homepage: <http://debian-live.alioth.debian.org/>"
129 dir1="$(Base_path ${1})"
130 dir2="$(Base_path ${2})"
132 if [ "${dir1}" = "${dir2}" ]
144 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})"
146 eval set -- "${ARGUMENTS}"
172 SNAP_RESYNC_STRING="${2}"
194 Error "internal error."
203 # Parse resync string
204 if [ -n "${SNAP_RESYNC_STRING}" ]
206 SNAP_COW=$(echo "${SNAP_RESYNC_STRING}" | cut -f1 -d ':')
207 SNAP_DEV=$(echo "${SNAP_RESYNC_STRING}" | cut -f2 -d ':')
208 DEST=$(echo "${SNAP_RESYNC_STRING}" | cut -f3 -d ':')
227 Error "unrecognized resync string"
231 # Set target file based on image
232 case "${SNAP_TYPE}" in
234 DEST="${MOUNTP}/live-sn.cpio.gz"
238 DEST="${MOUNTP}/live-sn.${SNAP_TYPE}"
242 DEST="${MOUNTP}/live-sn.ext2"
250 case "${SNAP_TYPE}" in
251 cpio|squashfs|jffs2|ext2|ext3)
255 Error "invalid filesystem type \"${SNAP_TYPE}\""
259 if [ ! -d "${SNAP_COW}" ]
261 Error "${SNAP_COW} is not a directory"
264 if [ "$(id -u)" -ne 0 ]
266 Error "you are not root"
274 case "${SNAP_DEV}" in
277 mount -t tmpfs -o rw tmpfs "${MOUNTP}"
281 if [ -b "${SNAP_DEV}" ]
283 try_mount "${SNAP_DEV}" "${MOUNTP}" rw
291 case "${SNAP_TYPE}" in
293 EXCLUDE_LIST="$(mktemp -p ${SAFE_TMPDIR} live-snapshot-exclude-list.XXXXXX)"
294 echo "./${EXCLUDE_LIST}" > "${EXCLUDE_LIST}"
296 find . -name '*.wh.*' >> "${EXCLUDE_LIST}"
298 mksquashfs "${SNAP_COW}" "${DEST}" -ef "${EXCLUDE_LIST}"
299 rm -f "${EXCLUDE_LIST}"
303 ( cd "${SNAP_COW}" && find . -path '*.wh.*' -prune -o -print0 | cpio --quiet -o0 -H newc | gzip -9c > "${DEST}" ) || exit 1
307 DU_DIM="$(du -ks ${SNAP_COW} | cut -f1)"
308 REAL_DIM="$(expr ${DU_DIM} + ${DU_DIM} / 20)" # Just 5% more to be sure, need something more sophistcated here...
309 genext2fs --size-in-blocks=${REAL_DIM} --reserved-percentage=0 --root="${SNAP_COW}" "${DEST}"
313 mkfs.jffs2 --root="${SNAP_COW}" --output="${DEST}"
320 if echo "${DEST}" | grep -q "${MOUNTP}"
322 echo "${DEST} is present on ${MOUNTP}, therefore no automatic unmounting the latter." > /dev/null 1>&2