From 004cec5bd33025412df84f07590b6c5452d70ab6 Mon Sep 17 00:00:00 2001 From: Petr Stodulka Date: Wed, 17 Apr 2024 09:58:00 +0200 Subject: [PATCH 02/55] 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). IOW, let's get as close to the standard booting procedure when speaking about the storage, as possible. Note that the booting is still broken in this commit and needs additional changes made in followup commits. But due to complexity of the solution, keeping this separated. jira: RHEL-3344, RHEL-35446 --- .../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 d73060cb..45f98148 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 9366ac13..00000000 --- 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 --sysinit -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 00000000..d24e0ef0 --- /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 06479fb5..30ae57b3 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 366b5cab..d2bf7313 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 -- 2.51.1