+## 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
+}
+
+