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 directory) filesystem in it
7 # for reuse in another live-initramfs session.
8 # Look at the manpage for more informations.
10 # Copyright (C) 2006-2008 Marco Amadori <marco.amadori@gmail.com>
11 # Copyright (C) 2008 Chris Lamb <chris@chris-lamb.co.uk>
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 # On Debian systems, the complete text of the GNU General Public License
27 # can be found in /usr/share/common-licenses/GPL-3 file.
29 # declare here two vars from /etc/live.conf because of "set -u"
35 . /usr/share/initramfs-tools/scripts/live-helpers
37 LIVE_CONF="/etc/live.conf"
40 export USERNAME USERFULLNAME HOSTNAME
43 PROGRAM=$(basename "${EXECUTABLE}")
45 # Needs to be available at run and reboot time
48 # Permits multiple runs
49 MOUNTP="$(mktemp -d -p ${SAFE_TMPDIR} live-snapshot-mnt.XXXXXX)"
50 DEST="${MOUNTP}/live-sn.cpio.gz"
52 # Command line defaults and declarations
61 echo "${PROGRAM}: error:" ${@}
72 echo "${PROGRAM} - utility to perform snapshots of Debian Live systems"
74 echo "usage: ${PROGRAM} [-c|--cow DIRECTORY] [-d|--device DEVICE] [-o|--output FILE] [-t|--type TYPE]"
75 echo " ${PROGRAM} [-r|--resync-string STRING]"
76 echo " ${PROGRAM} [-f|--refresh]"
77 echo " ${PROGRAM} [-h|--help]"
78 echo " ${PROGRAM} [-u|--usage]"
79 echo " ${PROGRAM} [-v|--version]"
88 echo " -c, --cow: copy on write directory (default: ${SNAP_COW})."
89 echo " -d, --device: output snapshot device (default: ${SNAP_DEV:-auto})."
90 echo " -o, --output: output image file (default: ${DEST})."
91 echo " -r, --resync-string: internally used to resync previous made snapshots."
92 echo " -f, --refresh: try to sync a running snapshot."
93 echo " -t, --type: snapshot filesystem type. Options: \"squashfs\", \"ext2\", \"ext3\", \"jffs2\" or \"cpio\".gz archive (default: ${SNAP_TYPE})"
95 echo "Look at live-snapshot(1) man page for more information."
105 echo "Try \"${PROGRAM} --help\" for more information."
114 echo "Copyright (C) 2006 Marco Amadori <marco.amadori@gmail.com>"
115 echo "Copyright (C) 2008 Chris Lamb <chris@chris-lamb.co.uk>"
117 echo "This program is free software; you can redistribute it and/or modify"
118 echo "it under the terms of the GNU General Public License as published by"
119 echo "the Free Software Foundation; either version 2 of the License, or"
120 echo "(at your option) any later version."
122 echo "This program is distributed in the hope that it will be useful,"
123 echo "but WITHOUT ANY WARRANTY; without even the implied warranty of"
124 echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
125 echo "GNU General Public License for more details."
127 echo "You should have received a copy of the GNU General Public License"
128 echo "along with this program; if not, write to the Free Software"
129 echo "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA"
131 echo "On Debian systems, the complete text of the GNU General Public License"
132 echo "can be found in /usr/share/common-licenses/GPL-2 file."
134 echo "Homepage: <http://debian-live.alioth.debian.org/>"
142 if [ -n "${ROOTSNAP}" ]; then
143 "${EXECUTABLE}" --resync-string="${ROOTSNAP}"
147 if [ -n "${HOMESNAP}" ]; then
148 "${EXECUTABLE}" --resync-string="${HOMESNAP}"
154 echo "No autoconfigured snapshots found at boot;" > /dev/null 1>&2
155 echo "(no resync string in ${LIVE_CONF})." > /dev/null 1>&2
164 ARGUMENTS="$(getopt --longoptions cow:,device:,output,resync-string:,refresh,type:,help,usage,version --name=${PROGRAM} --options c:d:o:t:r:fhuv --shell sh -- ${ARGS})"
166 eval set -- "${ARGUMENTS}"
192 SNAP_RESYNC_STRING="${2}"
219 Error "internal error."
228 # Parse resync string
229 if [ -n "${SNAP_RESYNC_STRING}" ]
231 SNAP_COW=$(echo "${SNAP_RESYNC_STRING}" | cut -f1 -d ':')
232 SNAP_DEV=$(echo "${SNAP_RESYNC_STRING}" | cut -f2 -d ':')
233 DEST="${MOUNTP}/$(echo ${SNAP_RESYNC_STRING} | cut -f3 -d ':')"
252 Error "unrecognized resync string"
255 elif [ -z "${SNAP_OUTPUT}" ]
257 # Set target file based on image
258 case "${SNAP_TYPE}" in
260 DEST="${MOUNTP}/live-sn.cpio.gz"
264 DEST="${MOUNTP}/live-sn.${SNAP_TYPE}"
268 DEST="${MOUNTP}/live-sn.ext2"
272 DEST="${SNAP_OUTPUT}"
278 case "${SNAP_TYPE}" in
279 cpio|squashfs|jffs2|ext2|ext3)
283 Error "invalid filesystem type \"${SNAP_TYPE}\""
287 if [ ! -d "${SNAP_COW}" ]
289 Error "${SNAP_COW} is not a directory"
292 if [ "$(id -u)" -ne 0 ]
294 Error "you are not root"
300 case "${SNAP_DEV}" in
303 mount -t tmpfs -o rw tmpfs "${MOUNTP}"
307 if [ -b "${SNAP_DEV}" ]
309 try_mount "${SNAP_DEV}" "${MOUNTP}" rw
317 case "${SNAP_TYPE}" in
319 EXCLUDE_LIST="$(mktemp -p ${SAFE_TMPDIR} live-snapshot-exclude-list.XXXXXX)"
320 echo "./${EXCLUDE_LIST}" > "${EXCLUDE_LIST}"
322 find . -name '*.wh.*' >> "${EXCLUDE_LIST}"
324 mksquashfs "${SNAP_COW}" "${DEST}" -ef "${EXCLUDE_LIST}"
325 rm -f "${EXCLUDE_LIST}"
329 ( cd "${SNAP_COW}" && find . -path '*.wh.*' -prune -o -print0 | cpio --quiet -o0 -H newc | gzip -9c > "${DEST}" ) || exit 1
333 DU_DIM="$(du -ks ${SNAP_COW} | cut -f1)"
334 REAL_DIM="$(expr ${DU_DIM} + ${DU_DIM} / 20)" # Just 5% more to be sure, need something more sophistcated here...
335 genext2fs --size-in-blocks=${REAL_DIM} --reserved-percentage=0 --root="${SNAP_COW}" "${DEST}"
339 mkfs.jffs2 --root="${SNAP_COW}" --output="${DEST}"
346 if [ -z "${SNAP_RESYNC_STRING}" ] && echo "${DEST}" | grep -q "${MOUNTP}"
348 echo "${DEST} is present on ${MOUNTP}, therefore no automatic unmounting the latter." > /dev/null 1>&2
357 if [ -z "${SNAP_RESYNC_STRING}" ]
361 echo "Please move ${DEST} (if is not already in it)" > /dev/null 1>&2
362 echo "in a supported writable partition (e.g ext3, vfat)." > /dev/null 1>&2
366 echo "To use ${DEST} you need to rebuild your media or add it" > /dev/null 1>&2
367 echo "to your multisession disc under the \"/live\" directory." > /dev/null 1>&2
371 echo "Please cat or flashcp ${DEST} to your partition in order to start using it." > /dev/null 1>&2
375 if grep -qv persistent /proc/cmdline
377 echo "Remember to boot this live system with \"persistent\" specified at boot prompt." > /dev/null 1>&2