X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=scripts%2Fboot%2Fmisc-helpers.sh;h=cc39fcbb230984b267b9d4f1ded11f126c98bc36;hb=6344cfe5b9a0921dbf8fd92feb52991b0ba07d7f;hp=abb2dd218ebc22134f18595de6d8e7b76a465fc8;hpb=dc6d1a0b26dae2b2197631bb4f94738a289e7b8a;p=live-boot-grml.git diff --git a/scripts/boot/misc-helpers.sh b/scripts/boot/misc-helpers.sh index abb2dd2..cc39fcb 100755 --- a/scripts/boot/misc-helpers.sh +++ b/scripts/boot/misc-helpers.sh @@ -2,6 +2,365 @@ #set -e +is_live_path () +{ + DIRECTORY="${1}" + + if [ -d "${DIRECTORY}"/"${LIVE_MEDIA_PATH}" ] + then + 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 + panic "No supported filesystem images found at /${LIVE_MEDIA_PATH}." + fi +} + +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 +} + +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 + ;; + + /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 + ;; + 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}" @@ -17,7 +376,8 @@ really_export () eval export "${STRING}"="${VALUE}" } -is_in_list_separator_helper () { +is_in_list_separator_helper () +{ local sep=${1} shift local element=${1} @@ -26,13 +386,15 @@ is_in_list_separator_helper () { echo ${list} | grep -qe "^\(.*${sep}\)\?${element}\(${sep}.*\)\?$" } -is_in_space_sep_list () { +is_in_space_sep_list () +{ local element=${1} shift is_in_list_separator_helper "[[:space:]]" "${element}" "${*}" } -is_in_comma_sep_list () { +is_in_comma_sep_list () +{ local element=${1} shift is_in_list_separator_helper "," "${element}" "${*}" @@ -141,10 +503,11 @@ where_is_mounted () grep -m1 "^${device} " /proc/mounts | cut -f2 -d ' ' } -trim_path () { - # remove all unnecessary /:s in the path, including last one (except - # if path is just "/") - echo ${1} | sed 's|//\+|/|g' | sed 's|^\(.*[^/]\)/$|\1|' +trim_path () +{ + # remove all unnecessary /:s in the path, including last one (except + # if path is just "/") + echo ${1} | sed 's|//\+|/|g' | sed 's|^\(.*[^/]\)/$|\1|' } what_is_mounted_on () @@ -401,7 +764,8 @@ mount_persistence_media () return 0 } -close_persistence_media () { +close_persistence_media () +{ local device=${1} local backing="$(where_is_mounted ${device})" @@ -482,8 +846,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} @@ -499,7 +862,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 @@ -511,10 +874,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 @@ -526,8 +888,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)" @@ -545,17 +906,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 @@ -567,19 +917,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. @@ -589,8 +935,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)" @@ -604,8 +949,7 @@ find_persistence_media () # in order to probe any filesystem it contains, like we do # below. activate_custom_mounts() also depends on that any luks # device already has been opened. - if is_in_comma_sep_list luks ${PERSISTENCE_ENCRYPTION} && \ - is_luks_partition ${dev} + if is_in_comma_sep_list luks ${PERSISTENCE_ENCRYPTION} && is_luks_partition ${dev} then if luks_device=$(open_luks_device "${dev}") then @@ -623,14 +967,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}" @@ -641,7 +985,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}" @@ -650,8 +994,7 @@ find_persistence_media () fi # Close luks device if it isn't used - if [ -z "${result}" ] && [ -n "${luks_device}" ] && \ - is_active_luks_mapping "${luks_device}" + if [ -z "${result}" ] && [ -n "${luks_device}" ] && is_active_luks_mapping "${luks_device}" then /sbin/cryptsetup luksClose "${luks_device}" fi @@ -693,7 +1036,8 @@ is_active_luks_mapping () /sbin/cryptsetup status "${device}" 1>/dev/null 2>&1 } -get_luks_backing_device () { +get_luks_backing_device () +{ device=${1} cryptsetup status ${device} 2> /dev/null | \ awk '{if ($1 == "device:") print $2}' @@ -712,16 +1056,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) @@ -790,7 +1134,9 @@ link_files () return fi - find "${src_dir}" -mindepth 1 -maxdepth 1 | while read src; do + find "${src_dir}" -mindepth 1 -maxdepth 1 | \ + while read src + do local dest="${dest_dir}$(basename "${src}")" if [ -d "${src}" ] then @@ -825,19 +1171,23 @@ do_union () local unionro1="${3}" # first underlying read-only branch (optional) local unionro2="${4}" # second underlying read-only branch (optional) - if [ "${UNIONTYPE}" = "aufs" ] - then - rw_opt="rw" - ro_opt="rr+wh" - noxino_opt="noxino" - elif [ "${UNIONTYPE}" = "unionfs-fuse" ] - then - rw_opt="RW" - ro_opt="RO" - else - rw_opt="rw" - ro_opt="ro" - fi + case "${UNIONTYPE}" in + aufs) + rw_opt="rw" + ro_opt="rr+wh" + noxino_opt="noxino" + ;; + + unionfs-fuse) + rw_opt="RW" + ro_opt="RO" + ;; + + *) + rw_opt="rw" + ro_opt="ro" + ;; + esac case "${UNIONTYPE}" in unionfs-fuse) @@ -940,7 +1290,7 @@ get_custom_mounts () opt_source=${opt#source=} ;; link) - opt_link="yes" + opt_link="true" ;; union|bind) ;; @@ -1008,22 +1358,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