3 # live-snapshot - utility to manage Debian Live systems snapshots
5 # This program mount a device (fallback to /tmpfs under $MOUNTP
6 # and save the /live/cow (or a different dir) filesystem in it for reusing
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)"
39 # Needs to be available at run and reboot time
42 # Permits multiple runs
43 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."
103 echo "${PROGRAM}, version ${VERSION}"
105 echo "Copyright (C) 2006 Marco Amadori <marco.amadori@gmail.com>"
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/>"
131 dir1="$(Base_path ${1})"
132 dir2="$(Base_path ${2})"
134 if [ "${dir1}" = "${dir2}" ]
146 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})"
148 eval set -- "${ARGUMENTS}"
174 SNAP_RESYNC_STRING="${2}"
196 Error "internal error."
206 # Parse resync string
207 if [ -n "${SNAP_RESYNC_STRING}" ]
209 SNAP_COW=$(echo "${SNAP_RESYNC_STRING}" | cut -f1 -d ':')
210 SNAP_DEV=$(echo "${SNAP_RESYNC_STRING}" | cut -f2 -d ':')
211 DEST=$(echo "${SNAP_RESYNC_STRING}" | cut -f3 -d ':')
230 Error "unrecognized resync string"
235 # Set target file based on image
236 case "${SNAP_TYPE}" in
238 DEST="${MOUNTP}/live-sn.cpio.gz"
242 DEST="${MOUNTP}/live-sn.${SNAP_TYPE}"
246 DEST="${MOUNTP}/live-sn.ext2"
255 case "${SNAP_TYPE}" in
256 cpio|squashfs|jffs2|ext2|ext3)
259 Error "invalid filesystem type \"${SNAP_TYPE}\""
263 if [ ! -d "${SNAP_COW}" ]
265 Error "${SNAP_COW} is not a directory"
268 if [ "$(id -u)" -ne 0 ]
270 Error "you are not root"
278 case "${SNAP_DEV}" in
281 mount -t tmpfs -o rw tmpfs "${MOUNTP}"
284 if [ -b "${SNAP_DEV}" ]
286 try_mount "${SNAP_DEV}" "${MOUNTP}" rw
294 case "${SNAP_TYPE}" in
296 EXCLUDE_LIST="$(mktemp -p ${SAFE_TMPDIR} live-snapshot-exclude-list.XXXXXX)"
297 echo "./${EXCLUDE_LIST}" > "${EXCLUDE_LIST}"
299 find . -name '*.wh.*' >> "${EXCLUDE_LIST}"
301 mksquashfs "${SNAP_COW}" "${DEST}" -ef "${EXCLUDE_LIST}"
302 rm -f "${EXCLUDE_LIST}"
306 ( cd "${SNAP_COW}" && find . -path '*.wh.*' -prune -o -print0 | cpio --quiet -o0 -H newc | gzip -9c > "${DEST}" ) || exit 1
310 DU_DIM="$(du -ks ${SNAP_COW} | cut -f1)"
311 REAL_DIM="$(expr ${DU_DIM} + ${DU_DIM} / 20)" # Just 5% more to be sure, need something more sophistcated here...
312 genext2fs --size-in-blocks=${REAL_DIM} --reserved-percentage=0 --root="${SNAP_COW}" "${DEST}"
316 mkfs.jffs2 --root="${SNAP_COW}" --output="${DEST}"
323 if echo "${DEST}" | grep -q "${MOUNTP}"
325 echo "${DEST} is present on ${MOUNTP}, therefore no automatic unmounting the latter." > /dev/null 1>&2