commit: 8458d98a5d16efedb9a027d929a13062676b6827 Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org> AuthorDate: Thu Jul 18 00:16:00 2019 +0000 Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org> CommitDate: Thu Jul 18 00:16:00 2019 +0000 URL: https://gitweb.gentoo.org/proj/genkernel.git/commit/?id=8458d98a
Rework --mountboot handling - Move code to own function. - Use same logic like mount-boot.eclass. - Ensure to restore state of boot partition on exit/error. Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org> gen_funcs.sh | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- genkernel | 44 +--------------- 2 files changed, 167 insertions(+), 46 deletions(-) diff --git a/gen_funcs.sh b/gen_funcs.sh index 15548d3..c453962 100755 --- a/gen_funcs.sh +++ b/gen_funcs.sh @@ -325,10 +325,6 @@ get_indent() { echo "${_indent}" } -is_boot_ro() { - return $(awk '( $2 == "'${BOOTDIR}'" && $4 ~ /(^|,)ro(,|$)/){ I=1; exit }END{print !I }' /proc/mounts); -} - setup_cache_dir() { if [ ! -d "${GK_V_CACHEDIR}" ] then @@ -1058,6 +1054,7 @@ trap_cleanup() { print_error 1 "Genkernel was unexpectedly terminated${signal_msg}." print_error 1 "Please consult '${LOGFILE}' for more information and any" print_error 1 "errors that were reported above." + restore_boot_mount_state silent cleanup exit 1 } @@ -1343,6 +1340,88 @@ set_config_with_override() { eval ${CfgVar}=\"${Result}\" } +# @FUNCTION: restore_boot_mount_state +# @USAGE: [<silent>] +# @DESCRIPTION: +# Restores mount state of boot partition to state before genkernel start. +# +# <silent> When set makes umount errors non-fatal and will use a loglevel +# of 5 for any output. +restore_boot_mount_state() { + local silent=no + [ -n "${1}" ] && silent=yes + + isTrue "${MOUNTBOOT}" || return + + if [ -f "${TEMP}/.bootdir.remount" ] + then + local msg="mount: >> Automatically remounting boot partition as read-only on '${BOOTDIR}' as it was previously ..." + if isTrue "${silent}" + then + print_info 5 "${msg}" + else + print_info 1 '' 1 0 + print_info 1 "${msg}" + fi + + mount -o remount,ro "${BOOTDIR}" &>/dev/null + if [ $? -ne 0 ] + then + local error_msg="Failed to restore read-only state of boot partition on '${BOOTDIR}'!" + if isTrue "${silent}" + then + print_error 1 "${error_msg}" + return + else + gen_die "${error_msg}" + fi + else + rm "${TEMP}/.bootdir.remount" \ + || gen_die "Failed to remove bootdir state file '${TEMP}/.bootdir.remount'!" + fi + elif [ -f "${TEMP}/.bootdir.mount" ] + then + local msg="mount: >> Automatically unmounting boot partition from '${BOOTDIR}' as it was previously ..." + if isTrue "${silent}" + then + print_info 5 "${msg}" + else + print_info 1 '' 1 0 + print_info 1 "${msg}" + fi + + umount "${BOOTDIR}" &>/dev/null + if [ $? -ne 0 ] + then + local error_msg="Failed to restore mount state of boot partition on '${BOOTDIR}'!" + if isTrue "${silent}" + then + print_error 1 "${error_msg}" + return + else + gen_die "${error_msg}" + fi + else + rm "${TEMP}/.bootdir.mount" \ + || gen_die "Failed to remove bootdir state file '${TEMP}/.bootdir.mount'!" + fi + else + local msg="mount: >> Boot partition state on '${BOOTDIR}' was not changed; Skipping restore boot partition state ..." + if [ -f "${TEMP}/.bootdir.no_boot_partition" ] + then + msg="mount: >> '${BOOTDIR}' is not a mountpoint; Nothing to restore ..." + fi + + print_info 5 '' 1 0 + print_info 5 "${msg}" + + rm "${TEMP}/.bootdir.no_boot_partition" \ + || gen_die "Failed to remove bootdir state file '${TEMP}/.bootdir.no_boot_partition'!" + + return + fi +} + rootfs_type_is() { local fstype=$1 @@ -1465,5 +1544,87 @@ kconfig_set_opt() { fi } +make_bootdir_writable() { + [ -z "${BOOTDIR}" ] && gen_die "--bootdir is not set!" + + local bootdir_status=unknown + + # Based on mount-boot.eclass code + local fstabstate=$(awk "!/^#|^[[:blank:]]+#|^${BOOTDIR//\//\\/}/ {print \$2}" /etc/fstab 2>/dev/null | egrep "^${BOOTDIR}$" ) + local procstate=$(awk "\$2 ~ /^${BOOTDIR//\//\\/}\$/ {print \$2}" /proc/mounts 2>/dev/null) + local proc_ro=$(awk '{ print $2 " ," $4 "," }' /proc/mounts 2>/dev/null | sed -n "/${BOOTDIR//\//\\/} .*,ro,/p") + + if [ -n "${fstabstate}" ] && [ -n "${procstate}" ] + then + if [ -n "${proc_ro}" ] + then + bootdir_status=1 + else + bootdir_status=0 + fi + elif [ -n "${fstabstate}" ] && [ -z "${procstate}" ] + then + bootdir_status=2 + else + bootdir_status=3 + fi + + case "${bootdir_status}" in + 0) + # Nothing to do -- just pimp the logfile output + print_info 5 '' 1 0 + print_info 5 "mount: >> Boot partition is already mounted in read-write mode on '${BOOTDIR}'." + ;; + 1) # Remount it rw. + if ! isTrue "${MOUNTBOOT}" + then + gen_die "Boot partition is mounted read-only on '${BOOTDIR}' and I am not allowed to remount due to set --no-mountboot option!" + fi + + mount -o remount,rw "${BOOTDIR}" &>/dev/null + if [ $? -eq 0 ] + then + print_info 1 "mount: >> Boot partition was temporarily remounted in read-write mode on '${BOOTDIR}' ..." + + touch "${TEMP}"/.bootdir.remount + else + gen_die "Failed to remount boot partition in read-write mode on '${BOOTDIR}'!" + fi + ;; + 2) # Mount it rw. + if ! isTrue "${MOUNTBOOT}" + then + gen_die "Boot partition is not mounted on '${BOOTDIR}' and I am not allowed to mount due to set --no-mountboot option!" + fi + + mount "${BOOTDIR}" -o rw &>/dev/null + if [ $? -eq 0 ] + then + print_info 1 '' 1 0 + print_info 1 "mount: >> Boot partition was temporarily mounted on '${BOOTDIR}' ..." + + touch "${TEMP}"/.bootdir.mount + else + gen_die "Failed to mount set bootdir '${BOOTDIR}'!" + fi + ;; + 3) + # Nothing really to do + print_info 5 '' 1 0 + print_info 5 "mount: >> '${BOOTDIR}' is not a mountpoint; Assuming no separate boot partition ..." + + touch "${TEMP}"/.bootdir.no_boot_partition + ;; + *) + gen_die "Internal error: BOOTDIR status ${bootdir_status} is unknown!" + ;; + esac + + if [ ! -w "${BOOTDIR}" ] + then + gen_die "Cannot write to bootdir '${BOOTDIR}'!" + fi +} + unset GK_DEFAULT_IFS declare -r GK_DEFAULT_IFS="${IFS}" diff --git a/genkernel b/genkernel index 470dd05..bb53452 100755 --- a/genkernel +++ b/genkernel @@ -166,47 +166,7 @@ then print_info 1 "" fi -# Check if BOOTDIR is mounted -if ! isTrue "${CMD_INSTALL}" -then - isTrue "${MOUNTBOOT}" && print_info 2 'Skipping automatic mount of boot' -else - [[ -d ${BOOTDIR} ]] || gen_die "${BOOTDIR} is not a directory" - - if ! egrep -q "[[:space:]]${BOOTDIR}[[:space:]]" /proc/mounts - then - if egrep -q "^[^#].+[[:space:]]${BOOTDIR}[[:space:]]" /etc/fstab - then - if isTrue "${MOUNTBOOT}" - then - if ! mount ${BOOTDIR} - then - print_warning 1 "${BOLD}WARNING${NORMAL}: Failed to mount ${BOOTDIR}!" - print_warning 1 '' 1 0 - else - print_info 1 "mount: ${BOOTDIR} mounted successfully!" - fi - else - print_warning 1 "${BOLD}WARNING${NORMAL}: No mounted ${BOOTDIR} partition detected!" - print_warning 1 "$(get_indent 1)Run ``mount ${BOOTDIR}`` to mount it!" - print_warning 1 '' 1 0 - fi - fi - elif is_boot_ro - then - if isTrue "${MOUNTBOOT}" - then - if ! mount -o remount,rw ${BOOTDIR} - then - print_warning 1 "${BOLD}WARNING${NORMAL}: Failed to remount ${BOOTDIR} RW!" - print_warning 1 '' 1 0 - else - print_info 1 "mount: ${BOOTDIR} remounted read/write successfully!" - BOOTRW="yes" - fi - fi - fi -fi +isTrue "${CMD_INSTALL}" && make_bootdir_writable if isTrue "${BUILD_KERNEL}" && ! isTrue "${KERNCACHE_IS_VALID}" then @@ -456,7 +416,7 @@ then unset CONFGREP fi -isTrue "${BOOTRW}" && mount -o remount,ro ${BOOTDIR} +isTrue "${CMD_INSTALL}" && restore_boot_mount_state print_info 1 '' 1 0 print_info 1 'Do NOT report kernel bugs as genkernel bugs unless your bug'