Adding casper 1.77+debian-2. 1.77+debian-2
authorDaniel Baumann <daniel@debian.org>
Sun, 23 Sep 2007 12:46:26 +0000 (14:46 +0200)
committerDaniel Baumann <daniel@debian.org>
Sun, 23 Sep 2007 12:46:26 +0000 (14:46 +0200)
16 files changed:
bin/casper-snapshot
casper.conf
debian/casper.init
debian/changelog
debian/control
debian/control.debian
debian/control.ubuntu
debian/manpage/casper-snapshot.1
debian/manpage/casper.7
hooks/casper
scripts/casper
scripts/casper-bottom/02etc_casper_conf
scripts/casper-bottom/14locales
scripts/casper-bottom/18hostname
scripts/casper-bottom/19keyboard
scripts/casper-helpers [new file with mode: 0644]

index f90e563..d2cb9e8 100644 (file)
@@ -1,9 +1,10 @@
-#!/bin/sh
+#!/bin/bash
 
-# casper-snapshot - utility to do Debian Live systems snapshots
+# casper-snapshot - utility to manage Debian Live systems snapshots
 #
-#   This program mount a /tmpfs under ~/Desktop and save the /cow
-#   filesystem in it for reusing in another session.
+#   This program mount a device (fallback to /tmpfs under /mnt/snapshot
+#   and save the /cow (or a different dir) filesystem in it for reusing
+#   in another casper session. Look at manpage for more info.
 #
 # Copyright (C) 2006 Marco Amadori <marco.amadori@gmail.com>
 #
 PROGRAM="`basename ${0}`"
 VERSION=0.0.1
 
+
 # Source casper conf
 if [ -e /etc/casper.conf ]; then
        . /etc/casper.conf
 else
-       USERNAME=`cat /etc/passwd | grep "999" | cut -f1 -d ':'`
+       USERNAME=$(cat /etc/passwd | grep "999" | cut -f1 -d ':')
+       HOSTNAME=$(hostname)
+       BUILD_SYSTEM="Debian"
+fi
+
+export USERNAME USERFULLNAME HOSTNAME BUILD_SYSTEM
+
+# Source helper functions
+helpers="/usr/share/initramfs-tools/scripts/casper-helpers"
+if [ -e "${helpers}" ]; then
+       . "${helpers}"
+else
+       echo "Error: I cannot found helper functions \"${helpers}\"."
+       exit 1
 fi
 
+# Define LSB log_* functions.
+# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
+. /lib/lsb/init-functions
+
+# Some defaults:
+MOUNTP="/mnt/casper-snapshot"
+COW="/cow"
+DEV=""
+DEST="${MOUNTP}/casper-sn.cpio.gz"
+TYPE="cpio"
+DESKTOP_LINK=/home/$USERNAME/Desktop/casper-snapshot
+
 Header ()
 {
        echo "${PROGRAM} - utility to do Debian Live snapshots"
        echo
-       echo "Usage: ${PROGRAM} [-c|--cow DIRECTORY] [-d|--dest DIRECTORY] [-o|--output FILE] [-t|--type TYPE]"
+       echo "Usage: ${PROGRAM} [-c|--cow DIRECTORY] [-d|--device DEVICE] [-o|--output FILE] [-t|--type TYPE]"
+       echo "Usage: ${PROGRAM} [-r|--resync-string STRING]"
        echo "Usage: ${PROGRAM} [-h|--help]"
        echo "Usage: ${PROGRAM} [-u|--usage]"
        echo "Usage: ${PROGRAM} [-v|--version]"
@@ -66,7 +94,9 @@ Help ()
        echo "  -c, --cow: specifies the copy on write directory (default: /cow)."
        echo "  -d, --destination: specifies the output snapshot directory (default: /home/\$USERNAME/Desktop/casper-snapshot)."
        echo "  -o, --output: specifies the output image file (default: $type dependent)."
+    echo "  -r, --resync-string: internally used to resync previous made snapshots."
        echo "  -t,--type: specifies the snapshot type between \'squashfs\', \'ext2\' or \'cpio\'.gz archive (default: cpio)"
+    echo -e "\nLook at casper-snapshot(1) man page for more information."
        exit 0
 }
 
@@ -121,31 +151,6 @@ Do_snapshot ()
        esac
 }
 
-Lastline()
-{
-       while read lines ; do
-               line=${lines}
-       done
-       echo "${line}"
-}
-
-Base_path ()
-{
-       testpath="${1}"
-       mounts="`awk '{print $2}' /proc/mounts`"
-       testpath="`realpath ${testpath}`"
-
-       while true ; do
-               if echo "${mounts}" | grep -qs "^${testpath}" ; then
-                       set -- `echo "${mounts}" | grep "^${testpath}" | Lastline`
-                       echo ${1}
-                       break
-               else
-                       testpath=`dirname $testpath`
-               fi
-       done
-}
-
 Is_same_mount ()
 {
        dir1="`Base_path ${1}`"
@@ -174,12 +179,14 @@ Parse_args ()
                case "${1}" in
                        -c|--cow)
                                SNAP_COW="${2}"; shift 2 ;;
-                       -d|--destination)
-                               SNAP_DEST="${2}"; shift 2 ;;
+                       -d|--device)
+                               SNAP_DEV="${2}"; shift 2 ;;
                        -o|--output)
                                SNAP_OUTPUT="${2}"; shift 2 ;;
                        -t|--type)
                                SNAP_TYPE="${2}"; shift 2 ;;
+                       -r|--resync-string)
+                               SNAP_RSTRING="${2}"; break ;;
                        -h|--help)
                                Help; shift ;;
                        -u|--usage)
@@ -194,34 +201,85 @@ Parse_args ()
        done
 }
 
-Defaults ()
+Mount_device ()
 {
-       DEF_COW="/cow"
+       dev="${1}"
+
+       if [ ! -d "${MOUNTP}" ]; then
+               mkdir -p "${MOUNTP}"
+       fi
+
+       if [ -n "${dev}" ]; then
+               # create a temp
+               mount -t tmpfs -o rw tmpfs "${MOUNTP}"
+               if [ ! -L /home/$USERNAME/Desktop/casper-snapshot ]; then
+                       ln -s "${MOUNTP}" /home/$USERNAME/Desktop/casper-snapshot
+               fi
+       else
+               if [ -b "${dev}" ] ; then
+                       try_mount "${dev}" "${MOUNTP}" rw
+               fi
+       fi
+}
 
-       # Bad options handling
-       if [ -z "${SNAP_COW}" ]; then
-               COW="${DEF_COW}"
+Defaults ()
+{
+       if [ -n "${SNAP_RSTRING}" ]; then
+               COW=$(echo "${SNAP_RSTRING}" | cut -f1 -d ':')
+               DEV=$(echo "${SNAP_RSTRING}" | cut -f2 -d ':')
+               DEST=$(echo "${SNAP_RSTRING}" | cut -f3 -d ':')
+               
+               case "${DEST}" in
+                       *.cpio.gz|*.cpz|*.gz)
+                               TYPE="cpio" ;;
+                       *.squashfs|*.squ})
+                               TYPE="squashfs" ;;
+                       "")
+                               TYPE="ext2" ;;
+                       *.ext2|*.ext)
+                               TYPE="ext2" ;;
+                       *)
+                               Usage "Unregognized String" ;;
+               esac
        else
-               COW="${SNAP_COW}"
+               DEF_COW="/cow"
+               # Bad options handling
+               if [ -z "${SNAP_COW}" ]; then
+                       COW="${DEF_COW}"
+               else
+                       COW="${SNAP_COW}"
+               fi
+       
+               case "${SNAP_TYPE}" in
+                       "cpio"|"squashfs"|"ext2")
+                               TYPE="${SNAP_TYPE}"
+                               ;;
+                       "")
+                               TYPE="cpio" ;;
+                       *)
+                               Usage "Error: unrecognized snapshot type"
+                               ;;
+               esac
+               #if [ -d 
+               #if Is_same_mount 
        fi
+
+       Mount_device $DEV
+       DEST="${MOUNTP}/${DEST}"
+
+       # check vars
        if [ ! -d "${COW}" ]; then
                Usage "Error: ${COW} is not a directory"
        fi
+}
 
-       case "${SNAP_TYPE}" in
-               "cpio"|"squashfs"|"ext2")
-                       TYPE="${SNAP_TYPE}"
-                       ;;
-               "")
-                       TYPE="cpio" ;;
-               *)
-                       Usage "Error: unrecognized snapshot type"
-                       ;;
-       esac
-       
-       #if [ -d 
-       #if Is_same_mount 
-
+Clean ()
+{
+       if [ -n "$DEV" ]; then
+               umount "${MOUNTP}"
+               rmdir "${MOUNTP}"
+               rm 
+       fi
 }
 
 Main ()
@@ -229,6 +287,7 @@ Main ()
        Parse_args "${@}"
        Defaults
        Do_snapshot
+       Clean
 }
 
 Main "${@}"
index ba5101c..7974b05 100644 (file)
@@ -1,8 +1,8 @@
 # This file should go in /etc/casper.conf
 # Supported variables are:
-# USERNAME, USERFULLNAME, HOST, BUILD_SYSTEM
+# USERNAME, USERFULLNAME, HOSTNAME, BUILD_SYSTEM
 
 export USERNAME="casper"
 export USERFULLNAME="Live session user"
-export HOST="live"
+export HOSTNAME="live"
 export BUILD_SYSTEM="Debian"
index d6ec097..6817efd 100644 (file)
@@ -8,7 +8,8 @@
 # Default-Start:     1 2 3 4 5
 # Default-Stop:      0 6
 # Short-Description: Casper init script
-# Description:       Does the proper shutdown in a casper booted system.
+# Description:       Resyncs snapshots, evantually caches files in order
+#                    to let remove the media.
 ### END INIT INFO
 
 # Author: Tollef Fog Heen <tfheen@canonical.com>
@@ -16,7 +17,8 @@
 #
 PATH=/usr/sbin:/usr/bin:/sbin:/bin
 NAME=casper
-SCRIPTNAME=/etc/init.d/$NAME
+SCRIPTNAME=/etc/init.d/${NAME}
+DO_SNAPSHOT=/sbin/${NAME}-snapshot
 
 # Exit if system was not booted by casper
 grep -qs boot=casper /proc/cmdline || exit 0
@@ -50,34 +52,19 @@ cache_path() {
     fi
 }
 
-do_sync ()
-{
-    # copy the tmp media on the snapshot media
-    fromdir="${1}"
-    todev="${2}"
-    tmnt="/mnt/temp_snap"
-
-    mkdir "${tmnt}" && \
-    mount "${todev}" "${tmnt}" -o rw && \
-    cd "${fromdir}" && \
-    find . -print0 | cpio -pumd0 "${tmnt}" && \
-    umount "${tmnt}" && \
-    rmdir "${tmnt}"
-}
-
 do_stop ()
 {
-    # check for netboot
-    if [ ! -z "${NETBOOT}" ] || grep -qs netboot /proc/cmdline || grep -qsi root=/dev/nfs /proc/cmdline  || grep -qsi root=/dev/cifs /proc/cmdline ; then
-        return 0
-    fi
-
     if [ ! -z "${ROOTSNAP}" ]; then
-        do_sync "/cow" "${ROOTSNAP}"
+        $DO_SNAPSHOT --resync-string="${ROOTSNAP}"
     fi
 
     if [ ! -z "${HOMESNAP}" ]; then
-        do_sync "/home" "${HOMESNAP}"
+        $DO_SNAPSHOT --resync-string="${HOMESNAP}"
+    fi
+
+    # check for netboot
+    if [ ! -z "${NETBOOT}" ] || grep -qs netboot /proc/cmdline || grep -qsi root=/dev/nfs /proc/cmdline  || grep -qsi root=/dev/cifs /proc/cmdline ; then
+        return 0
     fi
 
     for path in $(which halt) $(which reboot) /etc/rc?.d /etc/default; do
@@ -89,9 +76,9 @@ do_stop ()
     # XXX - i18n
     echo "Please remove the disc and close the tray (if any) then press ENTER: "
     if [ -x /sbin/usplash_write ]; then
-           /sbin/usplash_write "TIMEOUT 86400"
-           /sbin/usplash_write "TEXT-URGENT Please remove the disc, close the tray (if any)"
-           /sbin/usplash_write "TEXT-URGENT and press ENTER to continue"
+        /sbin/usplash_write "TIMEOUT 86400"
+        /sbin/usplash_write "TEXT-URGENT Please remove the disc, close the tray (if any)"
+        /sbin/usplash_write "TEXT-URGENT and press ENTER to continue"
     fi
 
     read x < /dev/console
@@ -102,7 +89,7 @@ case "$1" in
         [ "$VERBOSE" != no ] && log_end_msg 0
         ;;
     stop)
-        log_begin_msg "Caching reboot files..."
+        log_begin_msg "${NAME} is resyncing snapshots and caching reboot files..."
         do_stop
         case "$?" in
             0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
@@ -114,4 +101,3 @@ case "$1" in
         exit 3
         ;;
 esac
-
index 6887ad3..c2ca6ca 100644 (file)
@@ -1,3 +1,24 @@
+casper (1.77+debian-2) unstable; urgency=medium
+
+  [ Marco Amadori ]
+  * Improved snapshotting (but still experimental).
+  * Renamed "host=" boot parameter to "hostname=" and shell variable "HOST" to
+    "HOSTNAME" for consistence, with linux and with username/USERNAME, as
+    requested by many people.
+  * Fixed a "keyb=" typo.
+  * Added dependence on lsb-base (used by init-script and
+    casper-snapshot).
+  * Removed DM support (obsolete).
+  * Changed a bit locale and keyboard handling.
+  * Fixed locale generation.
+  * Urgency is set to medium to try reaching Etch with important
+    features/bugfixes.
+  [ Otavio Salvador ]
+  * Really lowered usplash conflicts since Debian doesn't has 0.4.
+
+ -- Marco Amadori <marco.amadori@gmail.com>  Mon, 30 Oct 2006 17:06:48 +0100
+
 casper (1.77+debian-1) unstable; urgency=low
 
   * New upstream release.
index 95a6edd..0ebb148 100644 (file)
@@ -8,10 +8,10 @@ Standards-Version: 3.7.2
 
 Package: casper
 Architecture: any
-Depends: initramfs-tools (>= 0.40), user-setup, sudo
-Conflicts: usplash (<< 0.4-0)
+Depends: initramfs-tools (>= 0.40), user-setup, sudo, lsb-base (>= 3.0-6)
+Conflicts: usplash (<< 0.3-0)
 Recommends: live-package
-Suggests: dmsetup, squashft-tools, genext2fs
+Suggests: squashfs-tools, genext2fs
 Tag: admin::boot, admin::filesystem, implemented-in::shell, protocol::smb, role::plugin, scope::utility, special::completely-tagged, works-with-format::iso9660
 Description: Debian Live initramfs generator
  Casper provides an initramfs generator suited for booting a Debian Live systems
index 95a6edd..0ebb148 100644 (file)
@@ -8,10 +8,10 @@ Standards-Version: 3.7.2
 
 Package: casper
 Architecture: any
-Depends: initramfs-tools (>= 0.40), user-setup, sudo
-Conflicts: usplash (<< 0.4-0)
+Depends: initramfs-tools (>= 0.40), user-setup, sudo, lsb-base (>= 3.0-6)
+Conflicts: usplash (<< 0.3-0)
 Recommends: live-package
-Suggests: dmsetup, squashft-tools, genext2fs
+Suggests: squashfs-tools, genext2fs
 Tag: admin::boot, admin::filesystem, implemented-in::shell, protocol::smb, role::plugin, scope::utility, special::completely-tagged, works-with-format::iso9660
 Description: Debian Live initramfs generator
  Casper provides an initramfs generator suited for booting a Debian Live systems
index 77c9cb2..88e4c09 100644 (file)
@@ -9,7 +9,7 @@ Package: casper
 Architecture: any
 Section: misc
 Priority: extra
-Depends: initramfs-tools (>= 0.40ubuntu11), dmsetup, user-setup, sudo
+Depends: initramfs-tools (>= 0.40ubuntu11), user-setup, sudo
 Conflicts: usplash (<< 0.4-27)
 Tag: admin::boot, admin::filesystem, implemented-in::shell, protocol::smb, role::plugin, scope::utility, special::completely-tagged, works-with-format::iso9660
 Description: Run a "live" preinstalled system from read-only media
index 1e17251..3cd5309 100644 (file)
@@ -7,24 +7,30 @@ casper-snapshot \- a simple script to ease persistence usage.
 .B casper-snapshot
 .RB [\| \-c \||\| \-\-cow
 .IR DIRECTORY \|]
-.RB [\| \-d \||\| \-\-destination
-.IR DIRECTORY \||\| FILE \|]
+.RB [\| \-d \||\| \-\-device
+.IR DEVICE \|]
+.RB [\| \-e \||\| \-\-exclude\-list
+.IR FILE \|]
 .RB [\| \-o \||\| \-\-output
 .IR FILE \|]
 .RB [\| \-t \||\| \-\-type
 .IR TYPE \|]
 .PP
-.B make-live
+.B casper-snapshot
+.RB \-r \||\| \-\-resync\-string
+.IR STRING
+.br
+.B casper-snapshot
 .RB \-h \||\| \-\-help
 .br
-.B make-live
+.B casper-snapshot
 .RB \-u \||\| \-\-usage
 .br
-.B make-live
+.B casper-snapshot
 .RB \-v \||\| \-\-version
 
 .SH DESCRIPTION
-Casper-snapshot is a script useful to build the right types of persistent image files supported by casper.
+Casper-snapshot is a script useful to build the right types of persistent image files supported by casper, it is also used on exit by the casper init script to resync the boot-found snapshots devices.
 
 .SH OPTIONS
 .TP
@@ -32,9 +38,17 @@ Casper-snapshot is a script useful to build the right types of persistent image
 specifies the input directory to be cloned in the image file.
 This parameters often does not need to be specified as the default of "/cow" for it should be right for most uses, however it could be handy to specify "/home" and type ext2 for the type to prepare an image file suited to be directly mounted by casper as home.
 .TP
-.BI "\-d, \-\-destination" DIRECTORY
+.BI "\-d, \-\-device" DEVICE
+the device on where the media which the snapshot/persistence file/partition will be put. If not specified a tmpfs will be used and linked on user's desktop to move it where he/her wants. If the device has not a filesystem on it, an ext2 fs will be created in it and labeled like --output options or with a sane default.
+.TP
+.BI "\-e, \-\-exclude\-list" FILE
+you could pass a list of filenames/path that should not be saved. This exclude list will be remebered on the target snapshotting media for reuse.
 .TP
 .BI "\-o, \-\-output" FILE
+the filename/label to be used for the output file/partition, if left blank it could search for a proper file on the device or use the whole partition.
+.TP
+.BI "\-r, \-\-resync\-string" STRING
+internally used on resyncs.
 .TP
 .BI "\-t, \-\-type" TYPE
 
index 89f1cf2..794ee0d 100644 (file)
@@ -1,7 +1,7 @@
 .TH CASPER 7 "Thu,  28 Sep 2006" "1.69" "Initramfs-tools hook"
 
 .SH NAME
-casper \- an hook for initramfs-tools to boot live systems.
+casper \- a hook for initramfs-tools to boot live systems.
 
 .SH SYNOPSIS
 .B BOOT=casper
@@ -15,11 +15,11 @@ Casper is an hook for initramfs-tools used to generate initramfs able to boot li
 .B casper-getty
 This enable a special serial login shell (experimental).
 .TP
-.BI "host=" HOSTNAME " , userfullname=" USERFULLNAME " , username=" USERNAME
+.BI "hostname=" HOSTNAME " , userfullname=" USERFULLNAME " , username=" USERNAME
 Those parameters lets you override values read from the config file.
 .TP
-.BI "keyb=" KEYBOARD " | kbd-chooser/method=" KEYBOARD ";  console-setup/layoutcode=" LAYOUT ", console-setup/variantcode=" VARIANT
-Configure the running keyboard as specified, if this one misses casper behave as "keyb=us" was specified. (It will be interfered from "locale=" somewhere in the future). You could also specify layout and variant (no defaults).
+.BI "keyb=" KEYBOARD " | kbd-chooser/method=" KEYBOARD " ;  console-setup/layoutcode=" LAYOUT " , console-setup/variantcode=" VARIANT " , console-setup/modelcode" CODE
+Configure the running keyboard as specified, if this one misses casper behave as "keyb=us" was specified. It will be interfered from "locale=" if locale is only 2 lowecase letters as a special case. You could also specify layout, variant, and code (no defaults).
 .TP
 .BI ip= IFACE,ADDRESS,NETMASK,GATEWAY [ :IFACE,ADDRESS,NETMASK,GATEWAY "]*"
 Let you specify the name(s) and the options of the interface(s) that should be configured at boot time. Do not specify it if you want to use dhcp (default).
@@ -28,7 +28,7 @@ Let you specify the name(s) and the options of the interface(s) that should be c
 This way dhcp and static configuration is just skipped and the system will use the (must be) media-preconfigured /etc/network/interfaces instead.
 .TP
 .BI "locale=" LOCALE " | debian-installer/locale=" LOCALE
-Configure the running locale as specified, if not present the live-media rootfs configured locale will be used and if also this one misses casper behave as "locale=en_US.UTF-8" was specified.
+Configure the running locale as specified, if not present the live-media rootfs configured locale will be used and if also this one misses casper behave as "locale=en_US.UTF-8" was specified. If only 2 lowercase letter are specified (like "it"), the "maybe wanted" locale is generated (like it:IT.UTF-8), in this case if also "keyb=" is unspecified is set with those 2 lowercase letters (keyb=it).
 .TP
 .BI live-media= DEVICE " | bootfrom=" DEVICE
 If you specify one of this two equivalent forms, casper will try first to look on this device for the "/casper" directory where it should lie the read-only root filesystem, if it did not find it, the normal scan for block devices will be performed.
index 2ebd188..be7f959 100755 (executable)
@@ -27,14 +27,6 @@ if [ -e /etc/casper.conf ]; then
     cp /etc/casper.conf ${DESTDIR}/etc
 fi
 
-# Needed for devmapper
-if [ -e /sbin/dmsetup ]; then
-    manual_add_modules cloop
-    copy_exec /sbin/blockdev /sbin
-    copy_exec /sbin/dmsetup /sbin
-    manual_add_modules dm-snapshot
-fi
-
 # We need losetup
 copy_exec /sbin/losetup /sbin
 
@@ -85,5 +77,6 @@ manual_add_modules ohci1394
 copy_exec /usr/lib/casper/casper-md5check /bin
 
 cp /usr/share/initramfs-tools/scripts/casper-functions $DESTDIR/scripts
+cp /usr/share/initramfs-tools/scripts/casper-helpers $DESTDIR/scripts
 
 auto_add_modules net
index 3a5e0ca..558a29b 100644 (file)
@@ -8,25 +8,20 @@ mountpoint=/live_media
 
 root_persistence="casper-rw"
 home_persistence="home-rw"
-root_snapshot="casper-sn"
-home_snapshot="home-sn"
+root_snapshot_label="casper-sn"
+home_snapshot_label="home-sn"
 
 USERNAME="casper"
 USERFULLNAME="Live session user"
-HOST="live"
+HOSTNAME="live"
 BUILD_SYSTEM="Debian"
 
 mkdir -p $mountpoint
 
 [ -f /etc/casper.conf ] && . /etc/casper.conf
+export USERNAME USERFULLNAME HOSTNAME BUILD_SYSTEM
 
-export USERNAME USERFULLNAME HOST BUILD_SYSTEM
-
-if [ "${BUILD_SYSTEM}" == "Ubuntu" ]; then
-    MP_QUIET="-Q"
-else
-    MP_QUIET="-q"
-fi
+. /scripts/casper-helpers
 
 parse_cmdline ()
 {
@@ -37,8 +32,8 @@ parse_cmdline ()
                 export USERFULLNAME=${x#userfullname=}
                 export CASPERCONF="changed"
                 ;;
-            host=*)
-                export HOST=${x#host=}
+            hostname=*)
+                export HOSTNAME=${x#hostname=}
                 export CASPERCONF="changed"
                 ;;
             username=*)
@@ -76,7 +71,7 @@ parse_cmdline ()
             kbd-chooser/method=*)
                 export KBD=${x#kbd-chooser/method=} ;;
             keyb=*)
-                export KBD=${x#kbd=} ;;
+                export KBD=${x#keyb=} ;;
             console-setup/layoutcode=*)
                 export CSLAYOUT=${x#console-setup/layoutcode=} ;;
             console-setup/variantcode=*)
@@ -101,8 +96,7 @@ parse_cmdline ()
 is_casper_path() {
     path=$1
     if [ -d "$path/casper" ]; then
-        if [ "$(echo $path/casper/*.cloop)" != "$path/casper/*.cloop" ] ||
-            [ "$(echo $path/casper/*.squashfs)" != "$path/casper/*.squashfs" ] ||
+        if [ "$(echo $path/casper/*.squashfs)" != "$path/casper/*.squashfs" ] ||
             [ "$(echo $path/casper/*.ext2)" != "$path/casper/*.ext2" ] ||
             [ "$(echo $path/casper/*.dir)" != "$path/casper/*.dir" ]; then
             return 0
@@ -111,22 +105,8 @@ is_casper_path() {
     return 1
 }
 
-subdevices() {
-    sysblock=$1
-    r=""
-    for dev in "${sysblock}" "${sysblock}"/*; do
-        if [ -e "${dev}/dev" ]; then
-            r="${r} ${dev}"
-        fi
-    done
-    echo ${r}
-}
-
 get_backing_device() {
     case "$1" in
-        *.cloop)
-            echo $(setup_loop "$1" "cloop" "/sys/block/cloop*")
-            ;;
         *.squashfs|*.ext2)
             echo $(setup_loop "$1" "loop" "/sys/block/loop*")
             ;;
@@ -152,10 +132,7 @@ match_files_in_dir() {
 mount_images_in_directory() {
     directory="$1"
     rootmnt="$2"
-    if match_files_in_dir "$directory/casper/*.cloop"; then
-        # Let's hope there's just one matching *.cloop... FIXME
-        setup_devmapper $(get_backing_device "$directory/casper/*.cloop") "$rootmnt"
-    elif match_files_in_dir "$directory/casper/*.squashfs" || 
+    if match_files_in_dir "$directory/casper/*.squashfs" ||
         match_files_in_dir "$directory/casper/*.ext2" ||
         match_files_in_dir "$directory/casper/*.dir"; then
         setup_unionfs "$directory/casper" "$rootmnt"
@@ -164,30 +141,6 @@ mount_images_in_directory() {
     fi
 }
 
-sys2dev() {
-    sysdev=${1#/sys}
-    echo "/dev/$(udevinfo -q name -p ${sysdev} 2>/dev/null|| echo ${sysdev##*/})"
-}
-
-setup_loop() {
-    local fspath=$1
-    local module=$2
-    local pattern=$3
-
-    modprobe "${MP_QUIET}" -b "$module"
-    udevsettle
-
-    for loopdev in $pattern; do
-        if [ "$(cat $loopdev/size)" -eq 0 ]; then
-            dev=$(sys2dev "${loopdev}")
-            losetup "$dev" "$fspath"
-            echo "$dev"
-            return 0
-        fi
-    done
-    panic "No loop devices available"
-}
-
 get_fstype() {
     local FSTYPE
     local FSSIZE
@@ -199,36 +152,6 @@ get_fstype() {
     /lib/udev/vol_id -t $1 2>/dev/null
 }
 
-setup_devmapper() {
-    backdev="$1"
-    rootmnt="$2"
-
-    modprobe "${MP_QUIET}" -b dm-mod
-    COW_DEVICE=/dev/ram1
-    COW_NAME="casper-cow"
-
-    BACKING_FILE_SIZE=$(blockdev --getsize "$backdev")
-    MAX_COW_SIZE=$(blockdev --getsize "$COW_DEVICE")
-    CHUNK_SIZE=8 # sectors
-
-    if [ -z "$COW_SIZE" -o "$COW_SIZE" -gt "$MAX_COW_SIZE" ]; then
-        COW_SIZE=$MAX_COW_SIZE
-    fi
-
-    echo "0 $COW_SIZE linear $COW_DEVICE 0" | dmsetup create $COW_NAME
-
-    echo "0 $BACKING_FILE_SIZE snapshot $backdev /dev/mapper/$COW_NAME p $CHUNK_SIZE" | \
-        dmsetup create casper-snapshot
-    if [ "$(get_fstype $backdev)" = "unknown" ]; then
-        panic "Unknown file system type on $backdev"
-    fi
-    mount -t $(get_fstype "$backdev") /dev/mapper/casper-snapshot $rootmnt || panic "Can not mount /dev/mapper/casper/snapshot on $rootmnt"
-
-    mkdir -p "$rootmnt/rofs"
-    echo "0 $BACKING_FILE_SIZE linear $backdev 0" | dmsetup create casper-backing
-    mount -t $(get_fstype "$backdev") /dev/mapper/casper-backing "$rootmnt/rofs"
-}
-
 is_nice_device() {
     sysfs_path="${1#/sys}"
     if /lib/udev/path_id "${sysfs_path}" | grep -E -q "ID_PATH=(usb|pci-[^-]*-[ide|scsi|usb])"; then
@@ -249,45 +172,6 @@ is_supported_fs ()
     return 1
 }
 
-where_is_mounted() {
-    device=$1
-    if grep -q "^$device " /proc/mounts; then
-        grep "^$device " /proc/mounts | read d mountpoint rest
-        echo $mountpoint
-        return 0
-    fi
-    return 1
-}
-
-used_fs_size ()
-{
-    # Returns used fs kbytes + 5% more
-    # You could pass a block device as $1 or the mount point as $2
-
-    dev="${1}"
-    mountp="${2}"
-
-    if [ -z "${mountp}" ]; then
-        mountp=$(where_is_mounted "${dev}")
-        if [ "$?" -gt 0 ]; then
-            mountp=/mnt/tmp_fs_size
-            mkdir -p "${mountp}"
-            mount -t $(get_fstype "${dev}") -o ro "${dev}" "${mountp}"
-            doumount=1
-        fi
-    fi
-
-    size=$(du -ks ${mountp} | cut -f1)
-    size=$(expr ${size} + ${size}/20 ) # FIXME: 5% more to be sure
-    needed_space=$(expr ${size} * 1024)
-
-    if [ ! -z "${doumount}" ]; then
-        umount "${mountp}"
-        rmdir "${mountp}"
-    fi
-    echo "${needed_space}"
-}
-
 copy_live_to() {
     copyfrom="${1}"
     copytodev="${2}"
@@ -331,68 +215,6 @@ copy_live_to() {
     return 0
 }
 
-try_mount ()
-{
-    dev="${1}"
-    mountp="${2}"
-    opts="${3}"
-
-    if where_is_mounted ${dev} > /dev/null; then
-        mount -o remount,"${opts}" ${dev} $(where_is_mounted ${dev}) || panic "Remounting failed"
-        mount -o bind $(where_is_mounted ${dev}) ${mountp} || panic "Cannot bind-mount"
-    else
-        mount -t $(get_fstype "${dev}") -o "${opts}" "${dev}" "${mountp}" || panic "Cannot mount ${dev} on ${mountp}"
-    fi
-}
-
-find_cow_device() {
-    pers_label="${1}"
-    cow_backing="/${pers_label}-backing"
-    for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do
-        for dev in $(subdevices "${sysblock}"); do
-            devname=$(sys2dev "${dev}")
-            if [ "$(/lib/udev/vol_id -l $devname 2>/dev/null)" = "${pers_label}" ]; then
-                echo "$devname"
-                return
-            elif [ "$(get_fstype ${devname})" = "vfat" ]; then # FIXME: all supported block devices should be scanned
-                mkdir -p "${cow_backing}"
-                try_mount "${devname}" "${cow_backing}" "rw"
-                if [ -e "${cow_backing}/${pers_label}" ]; then
-                    echo $(setup_loop "${cow_backing}/${pers_label}" "loop" "/sys/block/loop*")
-                    return 0
-                else
-                    umount ${cow_backing}
-                fi
-            fi
-        done
-    done
-}
-
-find_files()
-# return the first of $filenames found on vfat and ext2 devices
-# FIXME: merge with above function
-{
-    filenames="${1}"
-    snap_backing="/snap-backing"
-    for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do
-        for dev in $(subdevices "${sysblock}"); do
-            devname=$(sys2dev "${dev}")
-            devfstype="$(get_fstype ${devname})"
-            if [ "${devfstype}" = "vfat" ] ||  [ "${devfstype}" = "ext2" ] ; then # FIXME: all supported block devices should be scanned
-                mkdir -p "${snap_backing}"
-                try_mount "${devname}" "${snap_backing}" "ro"
-                for filename in ${filenames}; do
-                    if [ -e "${snap_backing}/${filename}" ]; then
-                        echo "${devname} ${snap_backing} ${filename}"
-                        return 0
-                    fi
-                done
-                umount ${snap_backing}
-            fi
-        done
-    done
-}
-
 do_netmount() {
     rc=1
 
@@ -459,25 +281,36 @@ do_snap_copy ()
     todir="${2}"
     snap_type="${3}"
 
-    size=$(used_fs_size "${fromdev}")
+    #size=$(used_fs_size "${fromdev}")
 
     if [ -b "${fromdev}" ]; then
         # look for free mem
-        if [ ! -z "${HOMEMOUNTED}" ] && [ "${snap_type}" = "HOME" ]; then
-            freespace="$(df -k ${copytodev} | grep -s ${copytodev} | awk '{print $4}')"
+        if [ -n "${HOMEMOUNTED}" -a "${snap_type}" = "HOME" ]; then
+            todev=$(cat /proc/mounts | grep -s " $(base_path ${todir}) " | awk '{print $1}' )
+            freespace=$(df -k  | grep -s ${todev} | awk '{print $4}')
         else
             freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( cat /proc/meminfo | grep Cached | head -n 1 | awk '/Cached/{print $2}' - ))
         fi
+
         tomount="/mnt/tmpsnap"
-        mkdir -p "${tomount}"
-        mount -t $(get_fstype "${fromdev}") -o ro "${fromdev}" "${tomount}"
-        cp -a "${tomount}"/* ${todir}
-        umount "${tomount}"
+        if [ ! -d "${tomount}" ] ; then
+            mkdir -p "${tomount}"
+        fi
 
-        if echo ${fromdev} | grep -qs loop; then
-            losetup -d "${fromdev}"
+        fstype=$(get_fstype "${fromdev}")
+        if [ -n "${fstype}" ]; then
+            # Copying stuff...
+            mount -t "${fstype}" -o ro "${fromdev}" "${tomount}"
+            cp -a "${tomount}"/* ${todir}
+            umount "${tomount}"
+        else
+            log_warning_msg "Unrecognized fstype: ${fstype} on ${fromdev}:${snap_type}"
         fi
 
+        rmdir "${tomount}"
+        if echo ${fromdev} | grep -qs loop; then
+           losetup -d "${fromdev}"
+        fi
         return 0
     else
         return 1
@@ -487,56 +320,62 @@ do_snap_copy ()
 
 try_snap ()
 {
+    # Look for $snap_label.* in block devices and copy the contents to $snap_mount
+    #   and remember the device and filename for resync on exit in casper.init
+
     snap_label="${1}"
     snap_mount="${2}"
     snap_type="${3}"
 
-    snapdata=$(find_files "${snap_label}.squashfs ${snap_label}.cpio.gz ${snap_label}.cpz ${snap_label}.gz")
+    snapdata=$(find_files "${snap_label}.squashfs ${snap_label}.cpio.gz ${snap_label}.ext2")
     if [ ! -z "${snapdata}" ]; then
-        snapdev=$(echo ${snapdata} | cut -f1 -d ' ')
-        snapback=$(echo ${snapdata} | cut -f2 -d ' ')
-        snapfile=$(echo ${snapdata} | cut -f3 -d ' ')
-        if echo "${snapfile}" | grep -qs "squashfs" ; then
-            # squashfs snapshot
-            if ! do_snap_copy $( get_backing_device "${snapback}/${snapfile}" ) "${snap_mount}" "${snap_type}"; then
+        snapdev="$(echo ${snapdata} | cut -f1 -d ' ')"
+        snapback="$(echo ${snapdata} | cut -f2 -d ' ')"
+        snapfile="$(echo ${snapdata} | cut -f3 -d ' ')"
+        if echo "${snapfile}" | grep -qs '\(squashfs\|ext2\)'; then
+            # squashfs or ext2 snapshot
+            dev=$(get_backing_device "${snapback}/${snapfile}")
+            if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}"; then
                  log_warning_msg "Impossible to include the ${snapfile} Snapshot"
                  return 1
             fi
         else
             # cpio.gz snapshot
-            if ! (cd "${snap_mount}" && zcat "${snapback}/${snapfile}" | cpio -i -u -d ) ; then
+            if ! (cd "${snap_mount}" && zcat "${snapback}/${snapfile}" | cpio -i -u -d 2>/dev/null) ; then
                 log_warning_msg "Impossible to include the ${snapfile} Snapshot"
                 return 1
             fi
         fi
         umount "${snapback}"
-    else # try pure snapshot device better elif.. rework all that routine
-        if ! do_snap_copy $(find_cow_device "${snap_label}") "${snap_mount}" "${snap_type}"; then
+    else
+        dev=$(find_cow_device "${snap_label}")
+        if [ -b ${dev} ]; then
+            if echo "${dev}" | grep -qs loop; then
+                # strange things happens, user confused?
+                snaploop=$( losetup ${dev} | awk '{print $3}' | tr -d '()' )
+                snapfile=$(basename ${snaploop})
+                snapdev=$(cat /proc/mounts | awk '{print $2,$1}' | grep -es "^$( dirname ${snaploop} )" | cut -f2 -d ' ')
+            else
+                snapdev="${dev}"
+            fi
+            if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}" ; then
+                log_warning_msg "Impossible to include the ${snap_label} Snapshot"
+                return 1
+            else
+                if [ -n "${snapfile}" ]; then
+                     # it was a loop device, user confused
+                     umount ${snapdev}
+                fi
+            fi
+        else
             log_warning_msg "Impossible to include the ${snap_label} Snapshot"
             return 1
         fi
     fi
-    echo "export ${snap_type}SNAP=${snapdev}:${snapfile}" >> /etc/casper.conf # for resync on reboot/halt
+    echo "export ${snap_type}SNAP="${snap_mount}":${snapdev}:${snapfile}" >> /etc/casper.conf # for resync on reboot/halt
     return 0
 }
 
-do_others_persistences ()
-{
-    # directly mount /home
-    # FIXME: add a custom mounts configurable system
-    homecow=$(find_cow_device "${home_persistence}" )
-    if [ -b "${homecow}" ]; then
-        mount ${homecow} -t $(get_fstype "${homecow}") -o rw "${rootmnt}/home"
-        export HOMEMOUNTED=1
-    else
-        [ "$quiet" != "y" ] && log_warning_msg "Unable to find the persistent home medium"
-    fi
-
-    # Look for snapshots to copy in
-    try_snap "${root_snapshot}" "${rootmnt}" "ROOT"
-    try_snap "${home_snapshot}" "${rootmnt}/home" "HOME"
-}
-
 setup_unionfs() {
     image_directory="$1"
     rootmnt="$2"
@@ -585,7 +424,7 @@ setup_unionfs() {
     cow_fstype="tmpfs"
 
     # Looking for "${root_persistence}" device or file
-    if [ ! -z "${PERSISTENT}" ]; then
+    if [ -n "${PERSISTENT}" ]; then
         cowprobe=$(find_cow_device "${root_persistence}")
         if [ -b "${cowprobe}" ]; then
             cowdevice=${cowprobe}
@@ -600,11 +439,22 @@ setup_unionfs() {
     mount -t unionfs -o dirs=/cow=rw:$rofsstring unionfs "$rootmnt" || panic "Unionfs mount failed"
 
     # Adding other custom mounts
-    if [ ! -z "${PERSISTENT}" ]; then
-        do_others_persistences
+    if [ -n "${PERSISTENT}" ]; then
+        # directly mount /home
+        # FIXME: add a custom mounts configurable system
+        homecow=$(find_cow_device "${home_persistence}" )
+        if [ -b "${homecow}" ]; then
+            mount -t $(get_fstype "${homecow}") -o rw "${homecow}" "${rootmnt}/home"
+            export HOMEMOUNTED=1 # used to proper calculate free space in do_snap_copy()
+        else
+            [ "$quiet" != "y" ] && log_warning_msg "Unable to find the persistent home medium"
+        fi
+        # Look for other snapshots to copy in
+        try_snap "${root_snapshot_label}" "${rootmnt}" "ROOT"
+        try_snap "${home_snapshot_label}" "${rootmnt}/home" "HOME"
     fi
 
-    if [ ! -z "${SHOWMOUNTS}" ]; then
+    if [ -n "${SHOWMOUNTS}" ]; then
         for d in ${rofslist}; do
             mkdir -p "${rootmnt}/casper/${d##*/}"
             case d in
@@ -617,8 +467,8 @@ setup_unionfs() {
     fi
 
     # shows cow fs on /cow for use by casper-snapshot
-    mkdir -p "$rootmnt/cow"
-    mount -o bind /cow "$rootmnt/cow"
+    mkdir -p "${rootmnt}/cow"
+    mount -o bind /cow "${rootmnt}/cow"
 }
 
 check_dev ()
index 7c4d08d..9e6deff 100644 (file)
@@ -1,6 +1,9 @@
 #!/bin/sh
 
 PREREQ=""
+DESCRIPTION="Copying config on real root fs..."
+
+. /scripts/casper-functions
 
 prereqs()
 {
@@ -15,13 +18,14 @@ prereqs)
        ;;
 esac
 
+log_begin_msg "$DESCRIPTION"
+
 if [ -f /etc/casper.conf ] ; then 
        if [ ! -z "${CASPERCONF}" ]; then
                # Updating casper.conf
                sed -i -e 's/\(USERNAME="\).*"/\1'"${USERNAME}"'"/g' \
                    -e 's/\(USERFULLNAME="\).*"/\1'"${USERFULLNAME}"'"/g' \
-                   -e 's/\(HOST="\).*"/\1'"${HOST}"'"/g' /etc/casper.conf
+                   -e 's/\(HOSTNAME="\).*"/\1'"${HOSTNAME}"'"/g' /etc/casper.conf
        fi
        cp -p /etc/casper.conf /root/etc/casper.conf
 
@@ -29,7 +33,7 @@ else
        cat <<EOF >/root/etc/casper.conf
 export USERNAME="$USERNAME"
 export USERFULLNAME="$USERFULLNAME"
-export HOST="$HOST"
+export HOSTNAME="$HOSTNAME"
 EOF
 
 fi
index 5080df6..12cfc4b 100755 (executable)
@@ -26,7 +26,7 @@ elif [ -e /root/etc/environment ]; then # Old locales policy
     grep_file=/root/etc/environment
 fi
 
-if [ ! -z "${grep_file}" ]; then
+if [ -n "${grep_file}" ]; then
     locale=$(grep -s 'LANG=' ${grep_file} | sed s/'LANG='// | tr -d '"' )
 else
     grep_file=/root/etc/default/locale
@@ -45,11 +45,27 @@ if [ -z "${locale}" ]; then
 fi
 
 if [ "${set_locale}" ]; then
+    if echo "${locale}" | grep -sqE '^[[:lower:]]{2}$' ; then
+        # input is like "locale=it", so we will convert and setup also the keyboard
+        if [ -z "${KBD}" ]; then
+            # FIXME: look if this keyb is supported
+            KBD="${locale}"
+        fi
+        uploc=$(echo "${locale}" | tr '[a-z]' '[A-Z]')
+        locale="${locale}_${uploc}.UTF-8"
+    fi
     LANG=$(grep "^${locale}" /root/usr/share/i18n/SUPPORTED | grep UTF-8 |sed -e 's, .*,,' -e q)
-    printf 'LANG="%s"\n' "${LANG}" >> "${grep_file}"
+
+    if [ -z "${LANG}" ]; then
+        log_warning_message "Locale ${locale} is unsupported."
+    fi
+
     if [ "${BUILD_SYSTEM}" == "Debian" ]; then
+        printf 'LANG=%s\n' "${LANG}" >> "${grep_file}"
+        printf '%s UTF-8\n' "${LANG}" >> /root/etc/locale.gen
         chroot /root /usr/sbin/locale-gen
     else
+        printf 'LANG="%s"\n' "${LANG}" > "${grep_file}"
         chroot /root /usr/sbin/locale-gen "${LANG}"
     fi
 fi
index 19ac61f..a616488 100755 (executable)
@@ -20,10 +20,10 @@ esac
 
 log_begin_msg "$DESCRIPTION"
 
-echo "$HOST" > /root/etc/hostname
+echo "$HOSTNAME" > /root/etc/hostname
 cat > /root/etc/hosts <<EOF
 127.0.0.1 localhost
-127.0.1.1 $HOST
+127.0.1.1 $HOSTNAME
 
 # The following lines are desirable for IPv6 capable hosts
 ::1     ip6-localhost ip6-loopback
index 7acc4e4..81cce72 100755 (executable)
@@ -26,16 +26,16 @@ csvariant=
 csmodel=
 
 # commandline
-if [ ! -z "${KBD}" ]; then
+if [ -n "${KBD}" ]; then
     kbd="${KBD}"
 fi
-if [ ! -z "${CSLAYOUT}" ]; then
+if [ -n "${CSLAYOUT}" ]; then
     cslayout="${CSLAYOUT}"
 fi
-if [ ! -z "${CSVARIANT}" ]; then
+if [ -n "${CSVARIANT}" ]; then
     csvariant="${CSVARIANT}"
 fi
-if [ ! -z "${CSMODEL}" ]; then
+if [ -n "${CSMODEL}" ]; then
     csmodel="${CSMODEL}"
 fi
 
diff --git a/scripts/casper-helpers b/scripts/casper-helpers
new file mode 100644 (file)
index 0000000..61d8019
--- /dev/null
@@ -0,0 +1,169 @@
+## Casper helper functions, used by casper on boot and by casper-snapshot
+
+if [ "${BUILD_SYSTEM}" == "Ubuntu" ]; then
+    MP_QUIET="-Q"
+else
+    MP_QUIET="-q"
+fi
+
+sys2dev() {
+    sysdev=${1#/sys}
+    echo "/dev/$(udevinfo -q name -p ${sysdev} 2>/dev/null|| echo ${sysdev##*/})"
+}
+
+subdevices() {
+    sysblock=$1
+    r=""
+    for dev in "${sysblock}" "${sysblock}"/*; do
+        if [ -e "${dev}/dev" ]; then
+            r="${r} ${dev}"
+        fi
+    done
+    echo ${r}
+}
+
+where_is_mounted() {
+    device=$1
+    if grep -q "^$device " /proc/mounts; then
+        grep "^$device " /proc/mounts | read d mountpoint rest
+        echo $mountpoint
+        return 0
+    fi
+    return 1
+}
+
+lastline() {
+    while read lines ; do
+        line=${lines}
+    done
+    echo "${line}"
+}
+
+base_path ()
+{
+    testpath="${1}"
+    mounts="$(awk '{print $2}' /proc/mounts)"
+    testpath="$(busybox realpath ${testpath})"
+
+    while true ; do
+        if echo "${mounts}" | grep -qs "^${testpath}" ; then
+            set -- `echo "${mounts}" | grep "^${testpath}" | lastline`
+            echo ${1}
+            break
+        else
+            testpath=`dirname $testpath`
+        fi
+    done
+}
+
+used_fs_size ()
+{
+    # Returns used fs kbytes + 5% more
+    # You could pass a block device as $1 or the mount point as $2
+
+    dev="${1}"
+    mountp="${2}"
+
+    if [ -z "${mountp}" ]; then
+        mountp=$(where_is_mounted "${dev}")
+        if [ "$?" -gt 0 ]; then
+            mountp=/mnt/tmp_fs_size
+            mkdir -p "${mountp}"
+            mount -t $(get_fstype "${dev}") -o ro "${dev}" "${mountp}"
+            doumount=1
+        fi
+    fi
+
+    size=$(du -ks ${mountp} | cut -f1)
+    size=$(expr ${size} + ${size}/20 ) # FIXME: 5% more to be sure
+    needed_space=$(expr ${size} * 1024)
+
+    if [ ! -z "${doumount}" ]; then
+        umount "${mountp}"
+        rmdir "${mountp}"
+    fi
+    echo "${needed_space}"
+}
+
+setup_loop() {
+    local fspath=$1
+    local module=$2
+    local pattern=$3
+
+    modprobe "${MP_QUIET}" -b "$module"
+    udevsettle
+
+    for loopdev in $pattern; do
+        if [ "$(cat $loopdev/size)" -eq 0 ]; then
+            dev=$(sys2dev "${loopdev}")
+            losetup "$dev" "$fspath"
+            echo "$dev"
+            return 0
+        fi
+    done
+    panic "No loop devices available"
+}
+
+try_mount ()
+{
+    dev="${1}"
+    mountp="${2}"
+    opts="${3}"
+
+    if where_is_mounted ${dev} > /dev/null; then
+        mount -o remount,"${opts}" ${dev} $(where_is_mounted ${dev}) || panic "Remounting failed"
+        mount -o bind $(where_is_mounted ${dev}) ${mountp} || panic "Cannot bind-mount"
+    else
+        mount -t $(get_fstype "${dev}") -o "${opts}" "${dev}" "${mountp}" || panic "Cannot mount ${dev} on ${mountp}"
+    fi
+}
+
+find_cow_device() {
+    pers_label="${1}"
+    cow_backing="/${pers_label}-backing"
+    for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do
+        for dev in $(subdevices "${sysblock}"); do
+            devname=$(sys2dev "${dev}")
+            if [ "$(/lib/udev/vol_id -l $devname 2>/dev/null)" = "${pers_label}" ]; then
+                echo "$devname"
+                return
+            elif [ "$(get_fstype ${devname})" = "vfat" ]; then # FIXME: all supported block devices should be scanned
+                mkdir -p "${cow_backing}"
+                try_mount "${devname}" "${cow_backing}" "rw"
+                if [ -e "${cow_backing}/${pers_label}" ]; then
+                    echo $(setup_loop "${cow_backing}/${pers_label}" "loop" "/sys/block/loop*")
+                    return 0
+                else
+                    umount ${cow_backing}
+                fi
+            fi
+        done
+    done
+}
+
+find_files()
+# return the first of $filenames found on vfat and ext2 devices
+# FIXME: merge with above function
+{
+    filenames="${1}"
+    snap_backing="/snap-backing"
+    for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop); do
+        for dev in $(subdevices "${sysblock}"); do
+            devname=$(sys2dev "${dev}")
+            devfstype="$(get_fstype ${devname})"
+            if [ "${devfstype}" = "vfat" ] ||  [ "${devfstype}" = "ext2" ] ; then # FIXME: all supported block devices should be scanned
+                mkdir -p "${snap_backing}"
+                try_mount "${devname}" "${snap_backing}" "ro"
+                for filename in ${filenames}; do
+                    if [ -e "${snap_backing}/${filename}" ]; then
+                        echo "${devname} ${snap_backing} ${filename}"
+                        return 0
+                    fi
+                done
+                umount ${snap_backing}
+            fi
+        done
+    done
+}
+
+