X-Git-Url: http://git.grml.org/?a=blobdiff_plain;f=scripts%2Fboot%2F9990-misc-helpers.sh;h=f2814ecd80447d46a6800d697e9a7954b494ebc2;hb=deabeeebb6d02b144cc9002c14bb6fca33c95ceb;hp=c5bcaa09b6c9359e5de79b402798fae8f1a39d25;hpb=89adeb3c4d91d12062e6fca8a00978eea52fe67f;p=live-boot-grml.git diff --git a/scripts/boot/9990-misc-helpers.sh b/scripts/boot/9990-misc-helpers.sh index c5bcaa0..f2814ec 100755 --- a/scripts/boot/9990-misc-helpers.sh +++ b/scripts/boot/9990-misc-helpers.sh @@ -65,7 +65,8 @@ get_backing_device () match_files_in_dir () { # Does any files match pattern ${1} ? - local pattern="${1}" + local pattern + pattern="${1}" if [ "$(echo ${pattern})" != "${pattern}" ] then @@ -99,16 +100,7 @@ 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)" + if /sbin/udevadm test-builtin 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]$' @@ -378,24 +370,27 @@ really_export () is_in_list_separator_helper () { - local sep=${1} + local sep element list + sep=${1} shift - local element=${1} + element=${1} shift - local list=${*} + list=${*} echo ${list} | grep -qe "^\(.*${sep}\)\?${element}\(${sep}.*\)\?$" } is_in_space_sep_list () { - local element=${1} + local element + element=${1} shift is_in_list_separator_helper "[[:space:]]" "${element}" "${*}" } is_in_comma_sep_list () { - local element=${1} + local element + element=${1} shift is_in_list_separator_helper "," "${element}" "${*}" } @@ -512,25 +507,28 @@ trim_path () what_is_mounted_on () { - local dir="$(trim_path ${1})" + local dir + dir="$(trim_path ${1})" grep -m1 "^[^ ]\+ ${dir} " /proc/mounts | cut -d' ' -f1 } chown_ref () { - local reference="${1}" + local reference targets owner + reference="${1}" shift - local targets=${@} - local owner=$(stat -c %u:%g "${reference}") + targets=${@} + owner=$(stat -c %u:%g "${reference}") chown -h ${owner} ${targets} } chmod_ref () { - local reference="${1}" + local reference targets rights + reference="${1}" shift - local targets=${@} - local rights=$(stat -c %a "${reference}") + targets=${@} + rights=$(stat -c %a "${reference}") chmod ${rights} ${targets} } @@ -593,7 +591,7 @@ fs_size () size=$(expr ${size} + ${size} / 20 ) # FIXME: 5% more to be sure else # free space - size="$(df -k | grep -s ${mountp} | awk '{print $4}')" + size="$(df -kP | grep -s ${mountp} | awk '{print $4}')" fi if [ -n "${doumount}" ] @@ -610,18 +608,19 @@ load_keymap () # Load custom keymap if [ -x /bin/loadkeys -a -r /etc/boottime.kmap.gz ] then - loadkeys /etc/boottime.kmap.gz + loadkeys --quiet /etc/boottime.kmap.gz fi } setup_loop () { - local fspath=${1} - local module=${2} - local pattern=${3} - local offset=${4} - local encryption=${5} - local readonly=${6} + local fspath module pattern offset encryption readonly + fspath=${1} + module=${2} + pattern=${3} + offset=${4} + encryption=${5} + readonly=${6} # the output of setup_loop is evaluated in other functions, # modprobe leaks kernel options like "libata.dma=0" @@ -723,19 +722,25 @@ try_mount () fi } +# Try to mount $device to the place expected by live-boot. If $device +# is already mounted somewhere, move it to the expected place. If +# we're only probing $device (to check if it has custom persistence) +# $probe should be set, which suppresses warnings upon failure. On +# success, print the mount point for $device. mount_persistence_media () { - local device=${1} - local probe=${2} + local device probe backing old_backing fstype mount_opts + device=${1} + probe=${2} - local backing="/live/persistence/$(basename ${device})" + backing="/live/persistence/$(basename ${device})" mkdir -p "${backing}" - local old_backing="$(where_is_mounted ${device})" + old_backing="$(where_is_mounted ${device})" if [ -z "${old_backing}" ] then - local fstype="$(get_fstype ${device})" - local mount_opts="rw,noatime" + fstype="$(get_fstype ${device})" + mount_opts="rw,noatime" if [ -n "${PERSISTENCE_READONLY}" ] then mount_opts="ro,noatime" @@ -760,14 +765,19 @@ mount_persistence_media () rmdir "${backing}" return 1 fi + else + # This means that $device has already been mounted on + # the place expected by live-boot, so we're done. + echo ${backing} + return 0 fi - return 0 } close_persistence_media () { - local device=${1} - local backing="$(where_is_mounted ${device})" + local device backing + device=${1} + backing="$(where_is_mounted ${device})" if [ -d "${backing}" ] then @@ -833,22 +843,25 @@ open_luks_device () get_gpt_name () { - local dev="${1}" + local dev + dev="${1}" /sbin/blkid -s PART_ENTRY_NAME -p -o value ${dev} 2>/dev/null } is_gpt_device () { - local dev="${1}" + local dev + dev="${1}" [ "$(/sbin/blkid -s PART_ENTRY_SCHEME -p -o value ${dev} 2>/dev/null)" = "gpt" ] } probe_for_gpt_name () { - local overlays="${1}" - local dev="${2}" + local overlays dev gpt_dev gpt_name + overlays="${1}" + dev="${2}" - local gpt_dev="${dev}" + gpt_dev="${dev}" if is_active_luks_mapping ${dev} then # if $dev is an opened luks device, we need to check @@ -861,7 +874,7 @@ probe_for_gpt_name () return fi - local gpt_name=$(get_gpt_name ${gpt_dev}) + gpt_name=$(get_gpt_name ${gpt_dev}) for label in ${overlays} do if [ "${gpt_name}" = "${label}" ] @@ -873,8 +886,9 @@ probe_for_gpt_name () probe_for_fs_label () { - local overlays="${1}" - local dev="${2}" + local overlays dev + overlays="${1}" + dev="${2}" for label in ${overlays} do @@ -887,11 +901,12 @@ probe_for_fs_label () probe_for_file_name () { - local overlays="${1}" - local dev="${2}" + local overlays dev ret backing + overlays="${1}" + dev="${2}" - local ret="" - local backing="$(mount_persistence_media ${dev} probe)" + ret="" + backing="$(mount_persistence_media ${dev} probe)" if [ -z "${backing}" ] then return @@ -902,7 +917,8 @@ probe_for_file_name () path=${backing}/${PERSISTENCE_PATH}${label} if [ -f "${path}" ] then - local loopdev=$(setup_loop "${path}" "loop" "/sys/block/loop*") + local loopdev + loopdev=$(setup_loop "${path}" "loop" "/sys/block/loop*") ret="${ret} ${label}=${loopdev}" fi done @@ -936,17 +952,19 @@ find_persistence_media () # ${white_list_devices} is non-empty, only devices in it will be # scanned. - local overlays="${1}" - local white_listed_devices="${2}" - local ret="" + local overlays white_listed_devices ret black_listed_devices + overlays="${1}" + white_listed_devices="${2}" + ret="" - local black_listed_devices="$(what_is_mounted_on /live/image)" + black_listed_devices="$(what_is_mounted_on /live/medium)" for dev in $(storage_devices "${black_listed_devices}" "${white_listed_devices}") do - local result="" + local result luks_device + result="" - local luks_device="" + luks_device="" # Check if it's a luks device; we'll have to open the device # in order to probe any filesystem it contains, like we do # below. activate_custom_mounts() also depends on that any luks @@ -1122,11 +1140,12 @@ link_files () # is non-empty, remove mask from all source paths when # creating links (will be necessary if we change root, which # live-boot normally does (into $rootmnt)). + local src_dir dest_dir src_mask # remove multiple /:s and ensure ending on / - local src_dir="$(trim_path ${1})/" - local dest_dir="$(trim_path ${2})/" - local src_mask="${3}" + src_dir="$(trim_path ${1})/" + dest_dir="$(trim_path ${2})/" + src_mask="${3}" # This check can only trigger on the inital, non-recursive call since # we create the destination before recursive calls @@ -1139,7 +1158,8 @@ link_files () find "${src_dir}" -mindepth 1 -maxdepth 1 | \ while read src do - local dest="${dest_dir}$(basename "${src}")" + local dest final_src + dest="${dest_dir}$(basename "${src}")" if [ -d "${src}" ] then if [ -z "$(ls -A "${src}")" ] @@ -1154,7 +1174,7 @@ link_files () fi link_files "${src}" "${dest}" "${src_mask}" else - local final_src=${src} + final_src=${src} if [ -n "${src_mask}" ] then final_src="$(echo ${final_src} | sed "s|^${src_mask}||")" @@ -1168,10 +1188,12 @@ link_files () do_union () { - local unionmountpoint="${1}" # directory where the union is mounted - local unionrw="${2}" # branch where the union changes are stored - local unionro1="${3}" # first underlying read-only branch (optional) - local unionro2="${4}" # second underlying read-only branch (optional) + local unionmountpoint unionrw unionro + unionmountpoint="${1}" # directory where the union is mounted + shift + unionrw="${1}" # branch where the union changes are stored + shift + unionro="${*}" # space separated list of read-only branches (optional) case "${UNIONTYPE}" in aufs) @@ -1195,13 +1217,12 @@ do_union () unionfs-fuse) unionmountopts="-o cow -o noinitgroups -o default_permissions -o allow_other -o use_ino -o suid" unionmountopts="${unionmountopts} ${unionrw}=${rw_opt}" - if [ -n "${unionro1}" ] + if [ -n "${unionro}" ] then - unionmountopts="${unionmountopts}:${unionro1}=${ro_opt}" - fi - if [ -n "${unionro2}" ] - then - unionmountopts="${unionmountopts}:${unionro2}=${ro_opt}" + for rofs in ${unionro} + do + unionmountopts="${unionmountopts}:${rofs}=${ro_opt}" + done fi ( sysctl -w fs.file-max=391524 ; ulimit -HSn 16384 unionfs-fuse ${unionmountopts} "${unionmountpoint}" ) && \ @@ -1210,21 +1231,27 @@ do_union () ;; overlayfs) - # XXX: can unionro2 be used? (overlayfs only handles two dirs, but perhaps they can be chained?) - # XXX: and can unionro1 be optional? i.e. can overlayfs skip lowerdir? - unionmountopts="-o noatime,lowerdir=${unionro1},upperdir=${unionrw}" + # XXX: can multiple unionro be used? (overlayfs only handles two dirs, but perhaps they can be chained?) + # XXX: and can unionro be optional? i.e. can overlayfs skip lowerdir? + if echo ${unionro} | grep -q " " + then + panic "Multiple lower filesystems are currently not supported with overlayfs (unionro = ${unionro})." + elif [ -z "${unionro}" ] + then + panic "Overlayfs needs at least one lower filesystem (read-only branch)." + fi + unionmountopts="-o noatime,lowerdir=${unionro},upperdir=${unionrw}" mount -t ${UNIONTYPE} ${unionmountopts} ${UNIONTYPE} "${unionmountpoint}" ;; *) unionmountopts="-o noatime,${noxino_opt},dirs=${unionrw}=${rw_opt}" - if [ -n "${unionro1}" ] - then - unionmountopts="${unionmountopts}:${unionro1}=${ro_opt}" - fi - if [ -n "${unionro2}" ] + if [ -n "${unionro}" ] then - unionmountopts="${unionmountopts}:${unionro2}=${ro_opt}" + for rofs in ${unionro} + do + unionmountopts="${unionmountopts}:${rofs}=${ro_opt}" + done fi mount -t ${UNIONTYPE} ${unionmountopts} ${UNIONTYPE} "${unionmountpoint}" ;; @@ -1236,12 +1263,13 @@ get_custom_mounts () # Side-effect: leaves $devices with persistence.conf mounted in /live/persistence # Side-effect: prints info to file $custom_mounts - local custom_mounts=${1} + local custom_mounts devices bindings links + custom_mounts=${1} shift - local devices=${@} + devices=${@} - local bindings="/tmp/bindings.list" - local links="/tmp/links.list" + bindings="/tmp/bindings.list" + links="/tmp/links.list" rm -rf ${bindings} ${links} 2> /dev/null for device in ${devices} @@ -1251,16 +1279,21 @@ get_custom_mounts () continue fi - local device_name="$(basename ${device})" - local backing=$(mount_persistence_media ${device}) + local device_name backing include_list + device_name="$(basename ${device})" + backing=$(mount_persistence_media ${device}) if [ -z "${backing}" ] then continue fi - local include_list="${backing}/${persistence_list}" - if [ ! -r "${include_list}" ] + if [ -r "${backing}/${persistence_list}" ] then + include_list="${backing}/${persistence_list}" + elif [ -r "${backing}/${old_persistence_list}" ] + then + include_list="${backing}/${old_persistence_list}" + else continue fi @@ -1277,14 +1310,15 @@ get_custom_mounts () continue fi - if trim_path ${dir} | grep -q -e "^[^/]" -e "^/live\(/.*\)\?$" -e "^/\(.*/\)\?\.\.\?\(/.*\)\?$" + if trim_path ${dir} | grep -q -e "^[^/]" -e "^/lib" -e "^/lib/live\(/.*\)\?$" -e "^/\(.*/\)\?\.\.\?\(/.*\)\?$" then - log_warning_msg "Skipping unsafe custom mount ${dir}: must be an absolute path containing neither the \".\" nor \"..\" special dirs, and cannot be \"/live\" or any sub-directory therein." + log_warning_msg "Skipping unsafe custom mount ${dir}: must be an absolute path containing neither the \".\" nor \"..\" special dirs, and cannot be \"/lib\", or \"/lib/live\" or any of its sub-directories." continue fi - local opt_source="" - local opt_link="" + local opt_source opt_link source full_source full_dest + opt_source="" + opt_link="" for opt in $(echo ${options} | tr ',' ' '); do case "${opt}" in @@ -1303,7 +1337,7 @@ get_custom_mounts () esac done - local source="${dir}" + source="${dir}" if [ -n "${opt_source}" ] then if echo ${opt_source} | grep -q -e "^/" -e "^\(.*/\)\?\.\.\?\(/.*\)\?$" && [ "${opt_source}" != "." ] @@ -1315,8 +1349,8 @@ get_custom_mounts () fi fi - local full_source="$(trim_path ${backing}/${source})" - local full_dest="$(trim_path ${rootmnt}/${dir})" + full_source="$(trim_path ${backing}/${source})" + full_dest="$(trim_path ${rootmnt}/${dir})" if [ -n "${opt_link}" ] then echo "${device} ${full_source} ${full_dest} ${options}" >> ${links} @@ -1337,8 +1371,9 @@ get_custom_mounts () # We need to make sure that no two custom mounts have the same sources # or are nested; if that is the case, too much weird stuff can happen. - local prev_source="impossible source" # first iteration must not match - local prev_dest="" + local prev_source prev_dest + prev_source="impossible source" # first iteration must not match + prev_dest="" # This sort will ensure that a source /a comes right before a source # /a/b so we only need to look at the previous source sort -k2 -b ${custom_mounts} | @@ -1355,14 +1390,16 @@ get_custom_mounts () activate_custom_mounts () { - local custom_mounts="${1}" # the ouput from get_custom_mounts() - local used_devices="" + local custom_mounts used_devices + custom_mounts="${1}" # the ouput from get_custom_mounts() + used_devices="" while read device source dest options # < ${custom_mounts} do - local opt_bind="true" - local opt_link="" - local opt_union="" + local opt_bind opt_link opt_union + opt_bind="true" + opt_link="" + opt_union="" for opt in $(echo ${options} | tr ',' ' '); do case "${opt}" in @@ -1442,34 +1479,34 @@ activate_custom_mounts () fi # XXX: If CONFIG_AUFS_ROBR is added to the Debian kernel we can - # ignore the loop below and set rofs_dest_backing=$dest - local rofs_dest_backing="" - if [ -n "${opt_link}"] + # ignore the loop below and set rootfs_dest_backing=$dest + local rootfs_dest_backing + rootfs_dest_backing="" + if [ -n "${opt_link}" ] then - for d in /live/rofs/* + for d in /live/rootfs/* do if [ -n "${rootmnt}" ] then - rofs_dest_backing="${d}/$(echo ${dest} | sed -e "s|${rootmnt}||")" + fs="${d}/$(echo ${dest} | sed -e "s|${rootmnt}||")" else - rofs_dest_backing="${d}/${dest}" + fs="${d}/${dest}" fi - if [ -d "${rofs_dest_backing}" ] + if [ -d "${fs}" ] then - break - else - rofs_dest_backing="" + rootfs_dest_backing="${rootfs_dest_backing} ${fs}" fi done fi + local cow_dir links_source if [ -n "${opt_link}" ] && [ -z "${PERSISTENCE_READONLY}" ] then link_files ${source} ${dest} ${rootmnt} elif [ -n "${opt_link}" ] && [ -n "${PERSISTENCE_READONLY}" ] then - mkdir -p /live/persistence - local links_source=$(mktemp -d /live/persistence/links-source-XXXXXX) + mkdir -p ${rootmnt}/lib/live/mount/persistence + links_source=$(mktemp -d ${rootmnt}/lib/live/mount/persistence/links-source-XXXXXX) chown_ref ${source} ${links_source} chmod_ref ${source} ${links_source} # We put the cow dir in the below strange place to @@ -1477,31 +1514,24 @@ activate_custom_mounts () # has its own directory and isn't nested with some # other custom mount (if so that mount's files would # be linked, causing breakage. - local cow_dir="/live/overlay/live/persistence/$(basename ${links_source})" + cow_dir="/live/overlay/lib/live/mount/persistence/$(basename ${links_source})" mkdir -p ${cow_dir} chown_ref "${source}" "${cow_dir}" chmod_ref "${source}" "${cow_dir}" - do_union ${links_source} ${cow_dir} ${source} ${rofs_dest_backing} + do_union ${links_source} ${cow_dir} ${source} ${rootfs_dest_backing} link_files ${links_source} ${dest} ${rootmnt} elif [ -n "${opt_union}" ] && [ -z "${PERSISTENCE_READONLY}" ] then - do_union ${dest} ${source} ${rofs_dest_backing} + do_union ${dest} ${source} ${rootfs_dest_backing} elif [ -n "${opt_bind}" ] && [ -z "${PERSISTENCE_READONLY}" ] then mount --bind "${source}" "${dest}" elif [ -n "${opt_bind}" -o -n "${opt_union}" ] && [ -n "${PERSISTENCE_READONLY}" ] then # bind-mount and union mount are handled the same - # in read-only mode, but note that rofs_dest_backing + # in read-only mode, but note that rootfs_dest_backing # is non-empty (and necessary) only for unions - if [ -n "${rootmnt}" ] - then - local cow_dir="$(echo ${dest} | sed -e "s|^${rootmnt}|/live/overlay/|")" - else - # This is happens if persistence is activated - # post boot - local cow_dir="/live/overlay/${dest}" - fi + cow_dir="/live/overlay/${dest}" if [ -e "${cow_dir}" ] && [ -z "${opt_link}" ] then # If an earlier custom mount has files here @@ -1512,7 +1542,7 @@ activate_custom_mounts () mkdir -p ${cow_dir} chown_ref "${source}" "${cow_dir}" chmod_ref "${source}" "${cow_dir}" - do_union ${dest} ${cow_dir} ${source} ${rofs_dest_backing} + do_union ${dest} ${cow_dir} ${source} ${rootfs_dest_backing} fi PERSISTENCE_IS_ON="1" @@ -1527,31 +1557,6 @@ activate_custom_mounts () echo ${used_devices} } -fix_backwards_compatibility () -{ - local device=${1} - local dir=${2} - local opt=${3} - - if [ -n "${PERSISTENCE_READONLY}" ] - then - return - fi - - local backing="$(mount_persistence_media ${device})" - if [ -z "${backing}" ] - then - return - fi - - local include_list="${backing}/${persistence_list}" - if [ ! -r "${include_list}" ] - then - echo "# persistence backwards compatibility: -${dir} ${opt},source=." > "${include_list}" - fi -} - is_mountpoint () { directory="$1"