X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=scripts%2Fboot%2Fmisc-helpers.sh;h=241bba1709f9de520e72e672311ac31a851568cf;hb=refs%2Ftags%2Fdebian%2F3.0_a33-1;hp=3f2d7fbf2ea43e0831e093407b12f06b8e5f320e;hpb=27ebf6d2b60a0ce4acac11794203c9ddc20706e2;p=live-boot-grml.git diff --git a/scripts/boot/misc-helpers.sh b/scripts/boot/misc-helpers.sh index 3f2d7fb..241bba1 100755 --- a/scripts/boot/misc-helpers.sh +++ b/scripts/boot/misc-helpers.sh @@ -2,48 +2,379 @@ #set -e -really_export () +is_live_path () { - STRING="${1}" - VALUE="$(eval echo -n \${$STRING})" + DIRECTORY="${1}" - if [ -f /live.vars ] && grep -sq "export ${STRING}" /live.vars + if [ -d "${DIRECTORY}"/"${LIVE_MEDIA_PATH}" ] then - sed -i -e 's/\('${STRING}'=\).*$/\1'${VALUE}'/' /live.vars + for FILESYSTEM in squashfs ext2 ext3 ext4 xfs dir jffs2 + do + if [ "$(echo ${DIRECTORY}/${LIVE_MEDIA_PATH}/*.${FILESYSTEM})" != "${DIRECTORY}/${LIVE_MEDIA_PATH}/*.${FILESYSTEM}" ] + then + return 0 + fi + done + fi + + return 1 +} + +matches_uuid () +{ + if [ "${IGNORE_UUID}" ] || [ ! -e /conf/uuid.conf ] + then + return 0 + fi + + path="${1}" + uuid="$(cat /conf/uuid.conf)" + + for try_uuid_file in "${path}/.disk/live-uuid"* + do + [ -e "${try_uuid_file}" ] || continue + + try_uuid="$(cat "${try_uuid_file}")" + + if [ "${uuid}" = "${try_uuid}" ] + then + return 0 + fi + done + + return 1 +} + +get_backing_device () +{ + case "${1}" in + *.squashfs|*.ext2|*.ext3|*.ext4|*.jffs2) + echo $(setup_loop "${1}" "loop" "/sys/block/loop*" '0' "${LIVE_MEDIA_ENCRYPTION}" "${2}") + ;; + + *.dir) + echo "directory" + ;; + + *) + panic "Unrecognized live filesystem: ${1}" + ;; + esac +} + +match_files_in_dir () +{ + # Does any files match pattern ${1} ? + local pattern="${1}" + + if [ "$(echo ${pattern})" != "${pattern}" ] + then + return 0 + fi + + return 1 +} + +mount_images_in_directory () +{ + directory="${1}" + rootmnt="${2}" + mac="${3}" + + + if match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.squashfs" || + match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext2" || + match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext3" || + match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.ext4" || + match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.jffs2" || + match_files_in_dir "${directory}/${LIVE_MEDIA_PATH}/*.dir" + then + [ -n "${mac}" ] && adddirectory="${directory}/${LIVE_MEDIA_PATH}/${mac}" + setup_unionfs "${directory}/${LIVE_MEDIA_PATH}" "${rootmnt}" "${adddirectory}" else - echo "export ${STRING}=\"${VALUE}\"" >> /live.vars + panic "No supported filesystem images found at /${LIVE_MEDIA_PATH}." fi +} - eval export "${STRING}"="${VALUE}" +is_nice_device () +{ + sysfs_path="${1#/sys}" + + if [ -e /lib/udev/path_id ] + then + # squeeze + PATH_ID="/lib/udev/path_id" + else + # wheezy/sid (udev >= 174) + PATH_ID="/sbin/udevadm test-builtin path_id" + fi + + if ${PATH_ID} "${sysfs_path}" | egrep -q "ID_PATH=(usb|pci-[^-]*-(ide|sas|scsi|usb|virtio)|platform-sata_mv|platform-orion-ehci|platform-mmc|platform-mxsdhci)" + then + return 0 + elif echo "${sysfs_path}" | grep -q '^/block/vd[a-z]$' + then + return 0 + elif echo ${sysfs_path} | grep -q "^/block/dm-" + then + return 0 + elif echo ${sysfs_path} | grep -q "^/block/mtdblock" + then + return 0 + fi + + return 1 } -lang2locale() { - langpart="${1%%_*}" - if [ "$1" != "C" ]; then - # Match the language code with 3rd field in languagelist - line=$(grep -v "^#" /usr/share/live-boot/languagelist | cut -f1,3,6 -d\; | grep -v ';C$' | grep "^$langpart;") - if [ -n "$line" ]; then - if [ "$(echo "$line" | grep -c '')" -gt 1 ]; then - # More than one match; try matching the - # country as well. - countrypart="${1#*_}" - if [ "$countrypart" = "$1" ]; then - countryline="$(echo "$line" | head -n1)" - echo "${countryline##*;}" - return +check_dev () +{ + sysdev="${1}" + devname="${2}" + skip_uuid_check="${3}" + + # support for fromiso=.../isofrom=.... + if [ -n "$FROMISO" ] + then + ISO_DEVICE=$(dirname $FROMISO) + if ! [ -b $ISO_DEVICE ] + then + # to support unusual device names like /dev/cciss/c0d0p1 + # as well we have to identify the block device name, let's + # do that for up to 15 levels + i=15 + while [ -n "$ISO_DEVICE" ] && [ "$i" -gt 0 ] + do + ISO_DEVICE=$(dirname ${ISO_DEVICE}) + [ -b "$ISO_DEVICE" ] && break + i=$(($i -1)) + done + fi + + if [ "$ISO_DEVICE" = "/" ] + then + echo "Warning: device for bootoption fromiso= ($FROMISO) not found.">>/boot.log + else + fs_type=$(get_fstype "${ISO_DEVICE}") + if is_supported_fs ${fs_type} + then + mkdir /live/fromiso + mount -t $fs_type "$ISO_DEVICE" /live/fromiso + ISO_NAME="$(echo $FROMISO | sed "s|$ISO_DEVICE||")" + loopdevname=$(setup_loop "/live/fromiso/${ISO_NAME}" "loop" "/sys/block/loop*" "" '') + devname="${loopdevname}" + else + echo "Warning: unable to mount $ISO_DEVICE." >>/boot.log + fi + fi + fi + + if [ -z "${devname}" ] + then + devname=$(sys2dev "${sysdev}") + fi + + if [ -d "${devname}" ] + then + mount -o bind "${devname}" $mountpoint || continue + + if is_live_path $mountpoint + then + echo $mountpoint + return 0 + else + umount $mountpoint + fi + fi + + IFS="," + for device in ${devname} + do + case "$device" in + *mapper*) + # Adding lvm support + if [ -x /scripts/local-top/lvm2 ] + then + ROOT="$device" resume="" /scripts/local-top/lvm2 fi - countrypart="${countrypart%%[@.]*}" - countryline="$(echo "$line" | grep ";$countrypart;" | head -n1 || true)" - if [ "$countryline" ]; then - echo "${countryline##*;}" - return + ;; + + /dev/md*) + # Adding raid support + if [ -x /scripts/local-top/mdadm ] + then + cp /conf/conf.d/md /conf/conf.d/md.orig + echo "MD_DEVS=$device " >> /conf/conf.d/md + /scripts/local-top/mdadm + mv /conf/conf.d/md.orig /conf/conf.d/md + fi + ;; + esac + done + unset IFS + + [ -n "$device" ] && devname="$device" + + [ -e "$devname" ] || continue + + if [ -n "${LIVE_MEDIA_OFFSET}" ] + then + loopdevname=$(setup_loop "${devname}" "loop" "/sys/block/loop*" "${LIVE_MEDIA_OFFSET}" '') + devname="${loopdevname}" + fi + + fstype=$(get_fstype "${devname}") + + if is_supported_fs ${fstype} + then + devuid=$(blkid -o value -s UUID "$devname") + [ -n "$devuid" ] && grep -qs "\<$devuid\>" $tried && continue + mount -t ${fstype} -o ro,noatime "${devname}" ${mountpoint} || continue + [ -n "$devuid" ] && echo "$devuid" >> $tried + + if [ -n "${FINDISO}" ] + then + if [ -f ${mountpoint}/${FINDISO} ] + then + umount ${mountpoint} + mkdir -p /live/findiso + mount -t ${fstype} -o ro,noatime "${devname}" /live/findiso + loopdevname=$(setup_loop "/live/findiso/${FINDISO}" "loop" "/sys/block/loop*" 0 "") + devname="${loopdevname}" + mount -t iso9660 -o ro,noatime "${devname}" ${mountpoint} + else + umount ${mountpoint} + fi + fi + + if is_live_path ${mountpoint} && \ + ([ "${skip_uuid_check}" ] || matches_uuid ${mountpoint}) + then + echo ${mountpoint} + return 0 + else + umount ${mountpoint} 2>/dev/null + fi + fi + + if [ -n "${LIVE_MEDIA_OFFSET}" ] + then + losetup -d "${loopdevname}" + fi + + return 1 +} + +find_livefs () +{ + timeout="${1}" + + # don't start autodetection before timeout has expired + if [ -n "${LIVE_MEDIA_TIMEOUT}" ] + then + if [ "${timeout}" -lt "${LIVE_MEDIA_TIMEOUT}" ] + then + return 1 + fi + fi + + # first look at the one specified in the command line + case "${LIVE_MEDIA}" in + removable-usb) + for sysblock in $(removable_usb_dev "sys") + do + for dev in $(subdevices "${sysblock}") + do + if check_dev "${dev}" + then + return 0 + fi + done + done + return 1 + ;; + + removable) + for sysblock in $(removable_dev "sys") + do + for dev in $(subdevices "${sysblock}") + do + if check_dev "${dev}" + then + return 0 + fi + done + done + return 1 + ;; + + *) + if [ ! -z "${LIVE_MEDIA}" ] + then + if check_dev "null" "${LIVE_MEDIA}" "skip_uuid_check" + then + return 0 fi fi - echo "${line##*;}" + ;; + esac + + # or do the scan of block devices + # prefer removable devices over non-removable devices, so scan them first + devices_to_scan="$(removable_dev 'sys') $(non_removable_dev 'sys')" + + for sysblock in $devices_to_scan + do + devname=$(sys2dev "${sysblock}") + [ -e "$devname" ] || continue + fstype=$(get_fstype "${devname}") + + if /lib/udev/cdrom_id ${devname} > /dev/null + then + if check_dev "null" "${devname}" + then + return 0 + fi + elif is_nice_device "${sysblock}" + then + for dev in $(subdevices "${sysblock}") + do + if check_dev "${dev}" + then + return 0 + fi + done + elif [ "${fstype}" = "squashfs" -o \ + "${fstype}" = "btrfs" -o \ + "${fstype}" = "ext2" -o \ + "${fstype}" = "ext3" -o \ + "${fstype}" = "ext4" -o \ + "${fstype}" = "jffs2" ] + then + # This is an ugly hack situation, the block device has + # an image directly on it. It's hopefully + # live-boot, so take it and run with it. + ln -s "${devname}" "${devname}.${fstype}" + echo "${devname}.${fstype}" + return 0 fi + done + + return 1 +} + +really_export () +{ + STRING="${1}" + VALUE="$(eval echo -n \${$STRING})" + + if [ -f /live.vars ] && grep -sq "export ${STRING}" /live.vars + then + sed -i -e 's/\('${STRING}'=\).*$/\1'${VALUE}'/' /live.vars else - echo "C" + echo "export ${STRING}=\"${VALUE}\"" >> /live.vars fi + + eval export "${STRING}"="${VALUE}" } is_in_list_separator_helper () { @@ -511,8 +842,7 @@ is_gpt_device () probe_for_gpt_name () { local overlays="${1}" - local snapshots="${2}" - local dev="${3}" + local dev="${2}" local gpt_dev="${dev}" if is_active_luks_mapping ${dev} @@ -528,7 +858,7 @@ probe_for_gpt_name () fi local gpt_name=$(get_gpt_name ${gpt_dev}) - for label in ${overlays} ${snapshots} + for label in ${overlays} do if [ "${gpt_name}" = "${label}" ] then @@ -540,10 +870,9 @@ probe_for_gpt_name () probe_for_fs_label () { local overlays="${1}" - local snapshots="${2}" - local dev="${3}" + local dev="${2}" - for label in ${overlays} ${snapshots} + for label in ${overlays} do if [ "$(/sbin/blkid -s LABEL -o value $dev 2>/dev/null)" = "${label}" ] then @@ -555,8 +884,7 @@ probe_for_fs_label () probe_for_file_name () { local overlays="${1}" - local snapshots="${2}" - local dev="${3}" + local dev="${2}" local ret="" local backing="$(mount_persistence_media ${dev} probe)" @@ -574,17 +902,6 @@ probe_for_file_name () ret="${ret} ${label}=${loopdev}" fi done - for label in ${snapshots} - do - for ext in squashfs cpio.gz ext2 ext3 ext4 jffs2 - do - path="${PERSISTENCE_PATH}${label}.${ext}" - if [ -f "${backing}/${path}" ] - then - ret="${ret} ${label}=${dev}:${backing}:${path}" - fi - done - done if [ -n "${ret}" ] then @@ -596,19 +913,15 @@ probe_for_file_name () find_persistence_media () { - # Scans devices for overlays and snapshots, and returns a whitespace + # Scans devices for overlays, and returns a whitespace # separated list of how to use them. Only overlays with a partition - # label or file name in ${overlays} are returned, and ditto for - # snapshots with labels in ${snapshots}. + # label or file name in ${overlays} are returned. # # When scanning a LUKS device, the user will be asked to enter the # passphrase; on failure to enter it, or if no persistence partitions # or files were found, the LUKS device is closed. # - # For a snapshot file the return value is ${label}=${snapdata}", where - # ${snapdata} is the parameter used for try_snap(). - # - # For all other cases (overlay/snapshot partition and overlay file) the + # For all other cases (overlay partition and overlay file) the # return value is "${label}=${device}", where ${device} a device that # can mount the content. In the case of an overlay file, the device # containing the file will remain mounted as a side-effect. @@ -618,8 +931,7 @@ find_persistence_media () # scanned. local overlays="${1}" - local snapshots="${2}" - local white_listed_devices="${3}" + local white_listed_devices="${2}" local ret="" local black_listed_devices="$(what_is_mounted_on /live/image)" @@ -652,14 +964,14 @@ find_persistence_media () # Probe for matching GPT partition names or filesystem labels if is_in_comma_sep_list filesystem ${PERSISTENCE_STORAGE} then - result=$(probe_for_gpt_name "${overlays}" "${snapshots}" ${dev}) + result=$(probe_for_gpt_name "${overlays}" ${dev}) if [ -n "${result}" ] then ret="${ret} ${result}" continue fi - result=$(probe_for_fs_label "${overlays}" "${snapshots}" ${dev}) + result=$(probe_for_fs_label "${overlays}" ${dev}) if [ -n "${result}" ] then ret="${ret} ${result}" @@ -670,7 +982,7 @@ find_persistence_media () # Probe for files with matching name on mounted partition if is_in_comma_sep_list file ${PERSISTENCE_STORAGE} then - result=$(probe_for_file_name "${overlays}" "${snapshots}" ${dev}) + result=$(probe_for_file_name "${overlays}" ${dev}) if [ -n "${result}" ] then ret="${ret} ${result}" @@ -741,16 +1053,16 @@ removable_dev () then if [ -z "${want_usb}" ] then - dev_ok="yes" + dev_ok="true" else if readlink ${sysblock} | grep -q usb then - dev_ok="yes" + dev_ok="true" fi fi fi - if [ "${dev_ok}" = "yes" ] + if [ "${dev_ok}" = "true" ] then case "${output_format}" in sys) @@ -969,7 +1281,7 @@ get_custom_mounts () opt_source=${opt#source=} ;; link) - opt_link="yes" + opt_link="true" ;; union|bind) ;; @@ -1037,22 +1349,22 @@ activate_custom_mounts () while read device source dest options # < ${custom_mounts} do - local opt_bind="yes" + local opt_bind="true" local opt_link="" local opt_union="" for opt in $(echo ${options} | tr ',' ' '); do case "${opt}" in bind) - opt_bind="yes" + opt_bind="true" unset opt_link opt_union ;; link) - opt_link="yes" + opt_link="true" unset opt_bind opt_union ;; union) - opt_union="yes" + opt_union="true" unset opt_bind opt_link ;; esac