Reordered persistence lookups and boundaries (Closes: #500672).
authorMarco Amadori <marco.amadori@gmail.com>
Thu, 18 Sep 2008 21:37:27 +0000 (23:37 +0200)
committerDaniel Baumann <daniel@debian.org>
Wed, 9 Mar 2011 16:48:02 +0000 (17:48 +0100)
* This finally enables "live-rw" partition persistence, yes it works, it
  is still ugly and slow, but make it work first and let optimize it
  later, hopefully in one of the next commits.
  To rush test it, 'mkfs.ext2 -L "live-rw" /dev/XhdX' on a qemu drive
  and reboot the live with "persistent" on.

scripts/live
scripts/live-helpers

index f9e4fe2..7e0b100 100755 (executable)
@@ -855,7 +855,7 @@ do_snap_copy ()
                if [ -n "${fstype}" ]
                then
                        # Copying stuff...
                if [ -n "${fstype}" ]
                then
                        # Copying stuff...
-                       mount -t "${fstype}" -o ro,noatime "${fromdev}" "${tomount}" || log_warning_msg "Error in mount -t ${fstype} -o ro,noatime ${fromdev} ${tomount}"
+                       mount -o ro -t "${fstype}" "${fromdev}" "${tomount}" || log_warning_msg "Error in mount -t ${fstype} -o ro ${fromdev} ${tomount}"
                        cp -a "${tomount}"/* ${todir}
                        umount "${tomount}"
                else
                        cp -a "${tomount}"/* ${todir}
                        umount "${tomount}"
                else
@@ -877,15 +877,26 @@ do_snap_copy ()
        fi
 }
 
        fi
 }
 
+find_snap ()
+{
+       # Look for ${snap_label}.* in block devices
+       snap_label="${1}"
+       snapdata=$(find_files "${snap_label}.squashfs ${snap_label}.cpio.gz ${snap_label}.ext2 ${snap_label}.ext3 ${snap_label}.jffs2")
+       if [ -z "${snapdata}" ]
+       then
+               snapdata=$(find_cow_device "${snap_label}")
+       fi
+       echo "${snapdata}"
+}
+
 try_snap ()
 {
 try_snap ()
 {
-       # Look for ${snap_label}.* in block devices and copy the contents to ${snap_mount}
+        # copy the contents of previously found snapshot to ${snap_mount}
        # and remember the device and filename for resync on exit in live-initramfs.init
 
        # and remember the device and filename for resync on exit in live-initramfs.init
 
-       snap_label="${1}"
+       snapdata="${1}"
        snap_mount="${2}"
        snap_type="${3}"
        snap_mount="${2}"
        snap_type="${3}"
-       snapdata=$(find_files "${snap_label}.squashfs ${snap_label}.cpio.gz ${snap_label}.ext2 ${snap_label}.ext3 ${snap_label}.jffs2")
 
        if [ ! -z "${snapdata}" ]
        then
 
        if [ ! -z "${snapdata}" ]
        then
@@ -895,6 +906,10 @@ try_snap ()
                snapfile="$(echo ${snapdata} | cut -f3 -d ' ')"
 
                RES=""
                snapfile="$(echo ${snapdata} | cut -f3 -d ' ')"
 
                RES=""
+               if ! try_mount "${snapdev}" "${snapback}" "ro"
+               then
+                       break
+               fi
 
                if echo "${snapfile}" | grep -qs '\(squashfs\|ext2\|ext3\|jffs2\)'
                then
 
                if echo "${snapfile}" | grep -qs '\(squashfs\|ext2\|ext3\|jffs2\)'
                then
@@ -922,38 +937,36 @@ try_snap ()
                        log_warning_msg "Impossible to include the ${snapfile} Snapshot file"
                fi
 
                        log_warning_msg "Impossible to include the ${snapfile} Snapshot file"
                fi
 
-       else
-               # Try to find if it could be a snapshot partition
-               dev=$(find_cow_device "${snap_label}")
 
 
-               if [ -b "${dev}" ]
+       elif [ -b "${snapdata}" ]
+       then
+               # Try to find if it could be a snapshot partition
+               dev="${snapdata}"
+               log_success_msg "found snapshot device on ${dev}"
+               if echo "${dev}" | grep -qs loop
                then
                then
-                       log_success_msg "found snapshot device on ${dev}"
-                       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
+                       # 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}"
+               if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}"
+               then
+                       log_warning_msg "Impossible to include the ${snap_type} Snapshot"
+                       return 1
+               else
+                       if [ -n "${snapfile}" ]
                        then
                        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
+                               # 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
+       else
+               log_warning_msg "Impossible to include the ${snap_type} Snapshot"
+               return 1
        fi
 
        echo "export ${snap_type}SNAP="${snap_mount}":${snapdev}:${snapfile}" >> /etc/live.conf # for resync on reboot/halt
        fi
 
        echo "export ${snap_type}SNAP="${snap_mount}":${snapdev}:${snapfile}" >> /etc/live.conf # for resync on reboot/halt
@@ -1114,7 +1127,21 @@ setup_unionfs ()
                        fi
                done
 
                        fi
                done
 
+               # search for label and files (this could be hugely optimized)
                cowprobe=$(find_cow_device "${root_persistence}")
                cowprobe=$(find_cow_device "${root_persistence}")
+               if [ -b "${cowprobe}" ]
+               then
+                       # Blacklist /cow device, to avoid inconsistent setups for overlapping snapshots
+                       # makes sense to have both persistence for /cow and /home mounted, maybe also with
+                       # snapshots to be sure to really store some e.g key config files,
+                       # but not on the same media
+                       blacklistdev="${cowprobe}"
+               fi
+               # homecow just mount something on /home, this should be generalized some way
+               homecow=$(find_cow_device "${home_persistence}" "${blacklistdev}")
+               root_snapdata=$(find_snap "${root_snapshot_label}" "${blacklistdev}")
+               # This second type should be removed when snapshot grow smarter
+               home_snapdata=$(find_snap "${home_snapshot_label}" "${blacklistdev}")
 
                if [ -b "${cowprobe}" ]
                then
 
                if [ -b "${cowprobe}" ]
                then
@@ -1203,7 +1230,6 @@ setup_unionfs ()
        then
                # directly mount /home
                # FIXME: add a custom mounts configurable system
        then
                # directly mount /home
                # FIXME: add a custom mounts configurable system
-               homecow=$(find_cow_device "${home_persistence}" )
 
                if [ -b "${homecow}" ]
                then
 
                if [ -b "${homecow}" ]
                then
@@ -1214,8 +1240,9 @@ setup_unionfs ()
                fi
 
                # Look for other snapshots to copy in
                fi
 
                # Look for other snapshots to copy in
-               try_snap "${root_snapshot_label}" "${rootmnt}" "ROOT"
-               try_snap "${home_snapshot_label}" "${rootmnt}/home" "HOME"
+               try_snap "${root_snapdata}" "${rootmnt}" "ROOT"
+               # This second type should be removed when snapshot grow smarter
+               try_snap "${home_snapdata}" "${rootmnt}/home" "HOME"
        fi
 
        if [ -n "${SHOWMOUNTS}" ]
        fi
 
        if [ -n "${SHOWMOUNTS}" ]
index 2641487..44bb12a 100644 (file)
@@ -288,8 +288,12 @@ try_mount ()
 
 find_cow_device ()
 {
 
 find_cow_device ()
 {
+       # Returns a device containing a partition labeled "${pers_label}" or containing a file named the same way
+       #  in the latter case the partition containing the file is left mounted
+       #  if is not in black_listed_devices
        pers_label="${1}"
        cow_backing="/${pers_label}-backing"
        pers_label="${1}"
        cow_backing="/${pers_label}-backing"
+       black_listed_devices="${2}"
 
        for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram | grep -v fd)
        do
 
        for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram | grep -v fd)
        do
@@ -297,6 +301,12 @@ find_cow_device ()
                do
                        devname=$(sys2dev "${dev}")
 
                do
                        devname=$(sys2dev "${dev}")
 
+                       if echo "${black_listed_devices}" | grep -q "${devname}"
+                       then
+                               # skip this device enterely
+                               break
+                       fi
+
                        if [ "$(/lib/udev/vol_id -l ${devname} 2>/dev/null)" = "${pers_label}" ]
                        then
                                echo "${devname}"
                        if [ "$(/lib/udev/vol_id -l ${devname} 2>/dev/null)" = "${pers_label}" ]
                        then
                                echo "${devname}"
@@ -306,7 +316,10 @@ find_cow_device ()
                        case "$(get_fstype ${devname})" in
                                vfat|ext2|ext3|jffs2)
                                        mkdir -p "${cow_backing}"
                        case "$(get_fstype ${devname})" in
                                vfat|ext2|ext3|jffs2)
                                        mkdir -p "${cow_backing}"
-                                       try_mount "${devname}" "${cow_backing}" "rw"
+                                       if ! try_mount "${devname}" "${cow_backing}" "rw"
+                                       then
+                                               break
+                                       fi
 
                                        if [ -f "${cow_backing}/${pers_label}" ]
                                        then
 
                                        if [ -f "${cow_backing}/${pers_label}" ]
                                        then
@@ -325,11 +338,12 @@ find_cow_device ()
 
 find_files ()
 {
 
 find_files ()
 {
-       # return the first of ${filenames} found on vfat and ext2/ext3 devices
+       # return the a string composed by device name, mountpoint an the first of ${filenames} found on a supported partition
        # FIXME: merge with above function
 
        filenames="${1}"
        snap_backing="/snap-backing"
        # FIXME: merge with above function
 
        filenames="${1}"
        snap_backing="/snap-backing"
+       black_listed_devices="${2}"
 
        for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram | grep -v fd)
        do
 
        for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -v loop | grep -v ram | grep -v fd)
        do
@@ -338,6 +352,12 @@ find_files ()
                        devname=$(sys2dev "${dev}")
                        devfstype="$(get_fstype ${devname})"
 
                        devname=$(sys2dev "${dev}")
                        devfstype="$(get_fstype ${devname})"
 
+                       if echo "${black_listed_devices}" | grep -q "${devname}"
+                       then
+                               # skip this device enterely
+                               break
+                       fi
+
                        if is_supported_fs ${devfstype}
                        then
                                mkdir -p "${snap_backing}"
                        if is_supported_fs ${devfstype}
                        then
                                mkdir -p "${snap_backing}"
@@ -349,7 +369,7 @@ find_files ()
                                                if [ -f "${snap_backing}/${filename}" ]
                                                then
                                                        echo "${devname} ${snap_backing} ${filename}"
                                                if [ -f "${snap_backing}/${filename}" ]
                                                then
                                                        echo "${devname} ${snap_backing} ${filename}"
-                                                       # return without mounting, it will be umounted later
+                                                       umount ${snap_backing}
                                                        return 0
                                                fi
                                        done
                                                        return 0
                                                fi
                                        done