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)"
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."
104 echo "Copyright (C) 2006 Marco Amadori <marco.amadori@gmail.com>"
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."
205 # Parse resync string
206 if [ -n "${SNAP_RESYNC_STRING}" ]
208 SNAP_COW=$(echo "${SNAP_RESYNC_STRING}" | cut -f1 -d ':')
209 SNAP_DEV=$(echo "${SNAP_RESYNC_STRING}" | cut -f2 -d ':')
210 DEST=$(echo "${SNAP_RESYNC_STRING}" | cut -f3 -d ':')
229 Error "unrecognized resync string"
234 # Set target file based on image
235 case "${SNAP_TYPE}" in
237 DEST="${MOUNTP}/live-sn.cpio.gz"
241 DEST="${MOUNTP}/live-sn.${SNAP_TYPE}"
245 DEST="${MOUNTP}/live-sn.ext2"
254 case "${SNAP_TYPE}" in
255 cpio|squashfs|jffs2|ext2|ext3)
258 Error "invalid filesystem type \"${SNAP_TYPE}\""
262 if [ ! -d "${SNAP_COW}" ]
264 Error "${SNAP_COW} is not a directory"
267 if [ "$(id -u)" -ne 0 ]
269 Error "you are not root"
277 case "${SNAP_DEV}" in
280 mount -t tmpfs -o rw tmpfs "${MOUNTP}"
283 if [ -b "${SNAP_DEV}" ]
285 try_mount "${SNAP_DEV}" "${MOUNTP}" rw
293 case "${SNAP_TYPE}" in
295 EXCLUDE_LIST="$(mktemp -p ${SAFE_TMPDIR} live-snapshot-exclude-list.XXXXXX)"
296 echo "./${EXCLUDE_LIST}" > "${EXCLUDE_LIST}"
298 find . -name '*.wh.*' >> "${EXCLUDE_LIST}"
300 mksquashfs "${SNAP_COW}" "${DEST}" -ef "${EXCLUDE_LIST}"
301 rm -f "${EXCLUDE_LIST}"
305 ( cd "${SNAP_COW}" && find . -path '*.wh.*' -prune -o -print0 | cpio --quiet -o0 -H newc | gzip -9c > "${DEST}" ) || exit 1
309 DU_DIM="$(du -ks ${SNAP_COW} | cut -f1)"
310 REAL_DIM="$(expr ${DU_DIM} + ${DU_DIM} / 20)" # Just 5% more to be sure, need something more sophistcated here...
311 genext2fs --size-in-blocks=${REAL_DIM} --reserved-percentage=0 --root="${SNAP_COW}" "${DEST}"
315 mkfs.jffs2 --root="${SNAP_COW}" --output="${DEST}"
322 if echo "${DEST}" | grep -q "${MOUNTP}"
324 echo "${DEST} is present on ${MOUNTP}, therefore no automatic unmounting the latter." > /dev/null 1>&2