diff options
Diffstat (limited to 'scripts/live-helpers')
| -rw-r--r-- | scripts/live-helpers | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/scripts/live-helpers b/scripts/live-helpers new file mode 100644 index 0000000..8402d93 --- /dev/null +++ b/scripts/live-helpers @@ -0,0 +1,197 @@ +## Casper helper functions, used by casper on boot and by casper-snapshot + +if [ "${BUILD_SYSTEM}" = "Ubuntu" ]; then + MP_QUIET="-Q" +elif [ "${BUILD_SYSTEM}" = "Debian" ]; then + MP_QUIET="-q" +else + MP_QUIET="" +fi + +if [ ! -x "/bin/fstype" ]; then + # klibc not in path -> not in initramfs + export PATH="${PATH}:/usr/lib/klibc/bin" +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} +} + +get_fstype() { + local FSTYPE + local FSSIZE + eval $(fstype < $1) + if [ "$FSTYPE" != "unknown" ]; then + echo $FSTYPE + return 0 + fi + /lib/udev/vol_id -t $1 2>/dev/null +} + +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 +} + +fs_size () +{ + # Returns used/free fs kbytes + 5% more + # You could pass a block device as $1 or the mount point as $2 + + dev="${1}" + mountp="${2}" + used="${3}" + + 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 + + if [ "${used}" = "used" ]; then + size=$(du -ks ${mountp} | cut -f1) + size=$(expr ${size} + ${size} / 20 ) # FIXME: 5% more to be sure + else + # free space + size="$(df -k | grep -s ${mountp} | awk '{print $4}')" + fi + + if [ -n "${doumount}" ]; then + umount "${mountp}" + rmdir "${mountp}" + fi + echo "${size}" +} + +setup_loop() { + local fspath=$1 + local module=$2 + local pattern=$3 + local offset=$4 + + modprobe ${MP_QUIET} -b "$module" + udevsettle + + for loopdev in $pattern; do + if [ "$(cat $loopdev/size)" -eq 0 ]; then + dev=$(sys2dev "${loopdev}") + if [ -n "$offset" ]; then + losetup -o "$offset" "$dev" "$fspath" + else + losetup "$dev" "$fspath" + fi + 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 +} + + |
