From 1fd6b1c31efe71fffa4d6a45cdcc7dff0ceb80b5 Mon Sep 17 00:00:00 2001 From: Petr Stodulka Date: Wed, 17 Apr 2024 09:58:00 +0200 Subject: [PATCH] Upgrade dracut module: Update /usr mounting solution Originally we had implemented our own mount_usr.sh script, which took care about mounting the /usr when it is present on separate partition / mountpoint. It took care also about LVM activation. However, it has been problematic in various cases (e.g. when device needed more time for initialisation - e.g. when connected using FC). Let's use instead existing system solutions, starting the upgrade.target after initrd-fs.target (instead of just basic.target). TBD jira: RHEL-3344 --- .../85sys-upgrade-redhat/module-setup.sh | 1 - .../dracut/85sys-upgrade-redhat/mount_usr.sh | 148 ------------------ .../initrd-cleanup-override.conf | 3 + .../dracut/90sys-upgrade/module-setup.sh | 11 ++ .../files/dracut/90sys-upgrade/upgrade.target | 4 +- 5 files changed, 16 insertions(+), 151 deletions(-) delete mode 100755 repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/mount_usr.sh create mode 100644 repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/initrd-cleanup-override.conf diff --git a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/module-setup.sh b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/module-setup.sh index d73060cb91..45f9814806 100755 --- a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/module-setup.sh +++ b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/module-setup.sh @@ -102,7 +102,6 @@ install() { inst_binary grep # script to actually run the upgrader binary - inst_hook upgrade 49 "$_moddir/mount_usr.sh" inst_hook upgrade 50 "$_moddir/do-upgrade.sh" #NOTE: some clean up?.. ideally, everything should be inside the leapp* diff --git a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/mount_usr.sh b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/mount_usr.sh deleted file mode 100755 index 84f4857d8d..0000000000 --- a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/85sys-upgrade-redhat/mount_usr.sh +++ /dev/null @@ -1,148 +0,0 @@ -#!/bin/sh -# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- -# ex: ts=8 sw=4 sts=4 et filetype=sh - -type info >/dev/null 2>&1 || . /lib/dracut-lib.sh - -export NEWROOT=${NEWROOT:-"/sysroot"} - -filtersubvol() { - _oldifs="$IFS" - IFS="," - set "$@" - IFS="$_oldifs" - while [ $# -gt 0 ]; do - case $1 in - subvol=*) :;; - *) printf '%s' "${1}," ;; - esac - shift - done -} - -mount_usr() -{ - # - # mount_usr [true | false] - # Expected a "true" value for the last attempt to mount /usr. On the last - # attempt, in case of failure drop to shell. - # - # Return 0 when everything is all right - # In case of failure and /usr has been detected: - # return 2 when $1 is "true" (drop to shell invoked) - # (note: possibly it's nonsense, but to be sure..) - # return 1 otherwise - # - _last_attempt="$1" - # check, if we have to mount the /usr filesystem - while read -r _dev _mp _fs _opts _freq _passno; do - [ "${_dev%%#*}" != "$_dev" ] && continue - if [ "$_mp" = "/usr" ]; then - case "$_dev" in - LABEL=*) - _dev="$(echo "$_dev" | sed 's,/,\\x2f,g')" - _dev="/dev/disk/by-label/${_dev#LABEL=}" - ;; - UUID=*) - _dev="${_dev#block:}" - _dev="/dev/disk/by-uuid/${_dev#UUID=}" - ;; - esac - - # shellcheck disable=SC2154 # Variable root is assigned by dracut - _root_dev=${root#block:} - - if strstr "$_opts" "subvol=" && \ - [ "$(stat -c '%D:%i' "$_root_dev")" = "$(stat -c '%D:%i' "$_dev")" ] && \ - [ -n "$rflags" ]; then - # for btrfs subvolumes we have to mount /usr with the same rflags - rflags=$(filtersubvol "$rflags") - rflags=${rflags%%,} - _opts="${_opts:+${_opts},}${rflags}" - elif getargbool 0 ro; then - # if "ro" is specified, we want /usr to be mounted read-only - _opts="${_opts:+${_opts},}ro" - elif getargbool 0 rw; then - # if "rw" is specified, we want /usr to be mounted read-write - _opts="${_opts:+${_opts},}rw" - fi - echo "$_dev ${NEWROOT}${_mp} $_fs ${_opts} $_freq $_passno" - _usr_found="1" - break - fi - done < "${NEWROOT}/etc/fstab" >> /etc/fstab - - if [ "$_usr_found" = "" ]; then - # nothing to do - return 0 - fi - - info "Mounting /usr with -o $_opts" - mount "${NEWROOT}/usr" 2>&1 | vinfo - mount -o remount,rw "${NEWROOT}/usr" - - if ismounted "${NEWROOT}/usr"; then - # success!! - return 0 - fi - - if [ "$_last_attempt" = "true" ]; then - warn "Mounting /usr to ${NEWROOT}/usr failed" - warn "*** Dropping you to a shell; the system will continue" - warn "*** when you leave the shell." - action_on_fail - return 2 - fi - - return 1 -} - - -try_to_mount_usr() { - _last_attempt="$1" - if [ ! -f "${NEWROOT}/etc/fstab" ]; then - warn "File ${NEWROOT}/etc/fstab doesn't exist." - return 1 - fi - - # In case we have the LVM command available try make it activate all partitions - if command -v lvm 2>/dev/null 1>/dev/null; then - lvm vgchange -a y || { - warn "Detected problem when tried to activate LVM VG." - if [ "$_last_attempt" != "true" ]; then - # this is not last execution, retry - return 1 - fi - # NOTE(pstodulk): - # last execution, so call mount_usr anyway - # I am not 100% about lvm vgchange exit codes and I am aware of - # possible warnings, in this last run, let's keep it on mount_usr - # anyway.. - } - fi - - mount_usr "$1" -} - -_sleep_timeout=15 -_last_attempt="false" -for i in 0 1 2 3 4 5 6 7 8 9 10 11; do - info "Storage initialisation: Attempt $i of 11. Wait $_sleep_timeout seconds." - sleep $_sleep_timeout - if [ $i -eq 11 ]; then - _last_attempt="true" - fi - try_to_mount_usr "$_last_attempt" && break - - # something is wrong. In some cases, storage needs more time for the - # initialisation - especially in case of SAN. - - if [ "$_last_attempt" = "true" ]; then - warn "The last attempt to initialize storage has not been successful." - warn "Unknown state of the storage. It is possible that upgrade will be stopped." - break - fi - - warn "Failed attempt to initialize the storage. Retry..." -done - diff --git a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/initrd-cleanup-override.conf b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/initrd-cleanup-override.conf new file mode 100644 index 0000000000..d24e0ef0f4 --- /dev/null +++ b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/initrd-cleanup-override.conf @@ -0,0 +1,3 @@ +[Service] +ExecStart= +ExecStart=-/usr/bin/true diff --git a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/module-setup.sh b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/module-setup.sh index 06479fb515..30ae57b3b9 100755 --- a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/module-setup.sh +++ b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/module-setup.sh @@ -54,6 +54,17 @@ install() { ln -sf "../${s}.service" "$upgrade_wantsdir" done + # Setup modified initrd-cleanup.service in the upgrade initramfs to enable + # storage initialisation using systemd-fstab-generator. We want to run the + # initrd-parse-etc.service but this one triggers also the initrd-cleanup.service + # which triggers the switch-root and isolated actions that basically kills + # the original upgrade service when used. + # The initrd-parse-etc.service has different content across RHEL systems, + # so we override rather initrd-cleanup.service instead as we do not need + # that one for the upgrade process. + mkdir -p "${unitdir}/initrd-cleanup.service.d" + inst_simple "${_moddir}/initrd-cleanup-override.conf" "${unitdir}/initrd-cleanup.service.d/initrd-cleanup-override.conf" + # just try : set another services into the wantsdir # sysroot.mount \ # dracut-mount \ diff --git a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/upgrade.target b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/upgrade.target index 366b5cabc2..d2bf731385 100644 --- a/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/upgrade.target +++ b/repos/system_upgrade/common/actors/commonleappdracutmodules/files/dracut/90sys-upgrade/upgrade.target @@ -2,7 +2,7 @@ Description=System Upgrade Documentation=man:upgrade.target(7) # ##sysinit.target sockets.target initrd-root-fs.target initrd-root-device.target initrd-fs.target -Wants=initrd-root-fs.target initrd-root-device.target initrd-fs.target initrd-usr-fs.target +Wants=initrd-root-fs.target initrd-root-device.target initrd-fs.target initrd-usr-fs.target initrd-parse-etc.service Requires=basic.target sysroot.mount -After=basic.target sysroot.mount +After=basic.target sysroot.mount initrd-fs.target AllowIsolate=yes