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'