live-snapshot: honour "-o|--output FILE".
[live-boot-grml.git] / bin / live-snapshot
index 141d266..03245ea 100755 (executable)
@@ -2,11 +2,11 @@
 
 # live-snapshot - utility to manage Debian Live systems snapshots
 #
-#   This program mount a device (fallback to /tmpfs under /mnt/snapshot
-#   and save the /live/cow (or a different dir) filesystem in it for reusing
+#   This program mounts a device (fallback to /tmpfs under $MOUNTP
+#   and saves the /live/cow (or a different dir) filesystem in it for reuse
 #   in another live-initramfs session. Look at manpage for more info.
 #
-# Copyright (C) 2006 Marco Amadori <marco.amadori@gmail.com>
+# Copyright (C) 2006-2008 Marco Amadori <marco.amadori@gmail.com>
 # Copyright (C) 2008 Chris Lamb <chris@chris-lamb.co.uk>
 #
 # This program is free software; you can redistribute it and/or modify
@@ -34,11 +34,15 @@ set -eu
 export USERNAME USERFULLNAME HOSTNAME
 
 PROGRAM="$(basename $0)"
-VERSION=0.0.2
 
-MOUNTP="/mnt/live-snapshot"
+# Needs to be available at run and reboot time
+SAFE_TMPDIR="/live"
+
+# Permits multiple runs
+MOUNTP="$(mktemp -d -p ${SAFE_TMPDIR} live-snapshot-mnt.XXXXXX)"
 SNAP_COW="/live/cow"
 SNAP_DEV=""
+SNAP_OUTPUT=""
 DEST="${MOUNTP}/live-sn.cpio.gz"
 SNAP_TYPE="cpio"
 DESKTOP_LINK="/home/${USERNAME}/Desktop/live-snapshot"
@@ -92,13 +96,13 @@ Usage ()
 
        exit 0
 }
-       
 
 Version ()
 {
-       echo "${PROGRAM}, version ${VERSION}"
+       echo "${PROGRAM}"
        echo
        echo "Copyright (C) 2006 Marco Amadori <marco.amadori@gmail.com>"
+       echo "Copyright (C) 2008 Chris Lamb <chris@chris-lamb.co.uk>"
        echo
        echo "This program is free software; you can redistribute it and/or modify"
        echo "it under the terms of the GNU General Public License as published by"
@@ -122,19 +126,6 @@ Version ()
        exit 0
 }
 
-Is_same_mount ()
-{
-       dir1="$(Base_path ${1})"
-       dir2="$(Base_path ${2})"
-
-       if [ "${dir1}" = "${dir2}" ]
-       then
-               return 0
-       else
-               return 1
-       fi
-}
-
 Parse_args ()
 {
        # Parse command line
@@ -194,7 +185,6 @@ Parse_args ()
 
                esac
        done
-
 }
 
 Defaults ()
@@ -204,7 +194,7 @@ Defaults ()
        then
                SNAP_COW=$(echo "${SNAP_RESYNC_STRING}" | cut -f1 -d ':')
                SNAP_DEV=$(echo "${SNAP_RESYNC_STRING}" | cut -f2 -d ':')
-               DEST=$(echo "${SNAP_RESYNC_STRING}" | cut -f3 -d ':')
+               DEST="${MOUNTP}/$(echo ${SNAP_RESYNC_STRING} | cut -f3 -d ':')"
 
                case "${DEST}" in
                        *.cpio.gz)
@@ -226,8 +216,8 @@ Defaults ()
                                Error "unrecognized resync string"
                                ;;
                esac
-
-       else
+       elif [ -z "${SNAP_OUTPUT}" ]
+       then
                # Set target file based on image
                case "${SNAP_TYPE}" in
                        cpio)
@@ -242,15 +232,17 @@ Defaults ()
                                DEST="${MOUNTP}/live-sn.ext2"
                                ;;
                esac
+       else
+               DEST="${SNAP_OUTPUT}"
        fi
-
 }
 
 Validate_input ()
 {
-       case "${SNAP_TYPE}" in 
+       case "${SNAP_TYPE}" in
                cpio|squashfs|jffs2|ext2|ext3)
                        ;;
+
                *)
                        Error "invalid filesystem type \"${SNAP_TYPE}\""
                        ;;
@@ -269,13 +261,12 @@ Validate_input ()
 
 Mount_device ()
 {
-       mkdir -p "${MOUNTP}"
-
        case "${SNAP_DEV}" in
                "")
                        # create a temp
                        mount -t tmpfs -o rw tmpfs "${MOUNTP}"
                        ;;
+
                *)
                        if [ -b "${SNAP_DEV}" ]
                        then
@@ -289,10 +280,13 @@ Do_snapshot ()
 {
        case "${SNAP_TYPE}" in
                squashfs)
-                       echo "./tmp/exclude_list" > /tmp/exclude_list
-                       ( cd "${SNAP_COW}" && find . -name '*.wh.*' >> /tmp/exclude_list )
-                       mksquashfs "${SNAP_COW}" "${DEST}" -ef /tmp/exclude_list
-                       rm /tmp/exclude_list
+                       EXCLUDE_LIST="$(mktemp -p ${SAFE_TMPDIR} live-snapshot-exclude-list.XXXXXX)"
+                       echo "./${EXCLUDE_LIST}" > "${EXCLUDE_LIST}"
+                       cd "${SNAP_COW}"
+                       find . -name '*.wh.*' >> "${EXCLUDE_LIST}"
+                       cd "${OLDPWD}"
+                       mksquashfs "${SNAP_COW}" "${DEST}" -ef "${EXCLUDE_LIST}"
+                       rm -f "${EXCLUDE_LIST}"
                        ;;
 
                cpio)
@@ -302,7 +296,7 @@ Do_snapshot ()
                ext2|ext3)
                        DU_DIM="$(du -ks ${SNAP_COW} | cut -f1)"
                        REAL_DIM="$(expr ${DU_DIM} + ${DU_DIM} / 20)" # Just 5% more to be sure, need something more sophistcated here...
-                       genext2fs --size-in-blocks=${REAL_DIM} --reserved-blocks=0 --root="${SNAP_COW}" "${DEST}"
+                       genext2fs --size-in-blocks=${REAL_DIM} --reserved-percentage=0 --root="${SNAP_COW}" "${DEST}"
                        ;;
 
                jffs2)
@@ -313,8 +307,13 @@ Do_snapshot ()
 
 Clean ()
 {
-       umount "${MOUNTP}"
-       rmdir "${MOUNTP}"
+       if echo "${DEST}" | grep -q "${MOUNTP}"
+       then
+               echo "${DEST} is present on ${MOUNTP}, therefore no automatic unmounting the latter." > /dev/null 1>&2
+       else
+               umount "${MOUNTP}"
+               rmdir "${MOUNTP}"
+       fi
 }
 
 Main ()
@@ -322,7 +321,7 @@ Main ()
        Parse_args "${@}"
        Defaults
        Validate_input
-       trap 'Clean' EXIT 
+       trap 'Clean' EXIT
        Mount_device
        Do_snapshot
 }