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)"
46 DEST="${MOUNTP}/live-sn.cpio.gz"
48 DESKTOP_LINK="/home/${USERNAME}/Desktop/live-snapshot"
53 echo "${PROGRAM}: error:" ${@}
64 echo "${PROGRAM} - utility to perform snapshots of Debian Live systems"
66 echo "usage: ${PROGRAM} [-c|--cow DIRECTORY] [-d|--device DEVICE] [-o|--output FILE] [-t|--type TYPE]"
67 echo " ${PROGRAM} [-r|--resync-string STRING]"
68 echo " ${PROGRAM} [-h|--help]"
69 echo " ${PROGRAM} [-u|--usage]"
70 echo " ${PROGRAM} [-v|--version]"
79 echo " -c, --cow: copy on write directory (default: ${SNAP_COW})."
80 echo " -d, --device: output snapshot device (default: ${SNAP_DEV:-auto})."
81 echo " -o, --output: output image file (default: ${DEST})."
82 echo " -r, --resync-string: internally used to resync previous made snapshots."
83 echo " -t, --type: snapshot filesystem type. Options: \"squashfs\", \"ext2\", \"ext3\", \"jffs2\" or \"cpio\".gz archive (default: ${SNAP_TYPE})"
85 echo "Look at live-snapshot(1) man page for more information."
95 echo "Try \"${PROGRAM} --help\" for more information."
104 echo "Copyright (C) 2006 Marco Amadori <marco.amadori@gmail.com>"
105 echo "Copyright (C) 2008 Chris Lamb <chris@chris-lamb.co.uk>"
107 echo "This program is free software; you can redistribute it and/or modify"
108 echo "it under the terms of the GNU General Public License as published by"
109 echo "the Free Software Foundation; either version 2 of the License, or"
110 echo "(at your option) any later version."
112 echo "This program is distributed in the hope that it will be useful,"
113 echo "but WITHOUT ANY WARRANTY; without even the implied warranty of"
114 echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
115 echo "GNU General Public License for more details."
117 echo "You should have received a copy of the GNU General Public License"
118 echo "along with this program; if not, write to the Free Software"
119 echo "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA"
121 echo "On Debian systems, the complete text of the GNU General Public License"
122 echo "can be found in /usr/share/common-licenses/GPL-2 file."
124 echo "Homepage: <http://debian-live.alioth.debian.org/>"
133 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})"
135 eval set -- "${ARGUMENTS}"
161 SNAP_RESYNC_STRING="${2}"
183 Error "internal error."
192 # Parse resync string
193 if [ -n "${SNAP_RESYNC_STRING}" ]
195 SNAP_COW=$(echo "${SNAP_RESYNC_STRING}" | cut -f1 -d ':')
196 SNAP_DEV=$(echo "${SNAP_RESYNC_STRING}" | cut -f2 -d ':')
197 DEST="${MOUNTP}/$(echo ${SNAP_RESYNC_STRING} | cut -f3 -d ':')"
216 Error "unrecognized resync string"
219 elif [ -z "${SNAP_OUTPUT}" ]
221 # Set target file based on image
222 case "${SNAP_TYPE}" in
224 DEST="${MOUNTP}/live-sn.cpio.gz"
228 DEST="${MOUNTP}/live-sn.${SNAP_TYPE}"
232 DEST="${MOUNTP}/live-sn.ext2"
236 DEST="${SNAP_OUTPUT}"
242 case "${SNAP_TYPE}" in
243 cpio|squashfs|jffs2|ext2|ext3)
247 Error "invalid filesystem type \"${SNAP_TYPE}\""
251 if [ ! -d "${SNAP_COW}" ]
253 Error "${SNAP_COW} is not a directory"
256 if [ "$(id -u)" -ne 0 ]
258 Error "you are not root"
264 case "${SNAP_DEV}" in
267 mount -t tmpfs -o rw tmpfs "${MOUNTP}"
271 if [ -b "${SNAP_DEV}" ]
273 try_mount "${SNAP_DEV}" "${MOUNTP}" rw
281 case "${SNAP_TYPE}" in
283 EXCLUDE_LIST="$(mktemp -p ${SAFE_TMPDIR} live-snapshot-exclude-list.XXXXXX)"
284 echo "./${EXCLUDE_LIST}" > "${EXCLUDE_LIST}"
286 find . -name '*.wh.*' >> "${EXCLUDE_LIST}"
288 mksquashfs "${SNAP_COW}" "${DEST}" -ef "${EXCLUDE_LIST}"
289 rm -f "${EXCLUDE_LIST}"
293 ( cd "${SNAP_COW}" && find . -path '*.wh.*' -prune -o -print0 | cpio --quiet -o0 -H newc | gzip -9c > "${DEST}" ) || exit 1
297 DU_DIM="$(du -ks ${SNAP_COW} | cut -f1)"
298 REAL_DIM="$(expr ${DU_DIM} + ${DU_DIM} / 20)" # Just 5% more to be sure, need something more sophistcated here...
299 genext2fs --size-in-blocks=${REAL_DIM} --reserved-percentage=0 --root="${SNAP_COW}" "${DEST}"
303 mkfs.jffs2 --root="${SNAP_COW}" --output="${DEST}"
310 if [ -z "${SNAP_RESYNC_STRING}" ] && echo "${DEST}" | grep -q "${MOUNTP}"
312 echo "${DEST} is present on ${MOUNTP}, therefore no automatic unmounting the latter." > /dev/null 1>&2