差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン 前のリビジョン
linux:fedora:update_rescue_kernel [2024/02/04 13:48] – 削除 - 外部編集 (Unknown date) 非ログインユーザーlinux:fedora:update_rescue_kernel [2024/02/04 13:48] (現在) – ↷ linux:fedora_update_rescue_kernel から linux:fedora:update_rescue_kernel へページの移動と名称変更しました。 ともやん
行 1: 行 1:
 +====== Fedora Rescue カーネルのアップデート ======
 +Fedora のレスキュー用のカーネル(vmlinuz) と RAM ディスク(initramfs) を更新する方法を記載する。\\
 +\\
 +結論から言うと以下のコマンドを実行すると Fedora 29 では上手く行きました。\\
 +<code>
 +$ sudo rm /boot/*rescue*
 +$ sudo kernel-install add $(uname -r) /lib/modules/$(uname -r)/vmlinuz
 +$ sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
 +</code>
 +※**grub2-mkconfig -o** で指定する grub.cfg の位置は UEFI ブート環境の場合 OS によって違います。\\
 + UEFIブート環境以外場合は **/boot/grub2/grub.cfg** です。\\
 + UEFIブート環境の場合、RHEL では **/boot/efi/EFI/redhat/grub.cfg** です。\\
 + UEFIブート環境の場合、CentOS では **/boot/efi/EFI/centos/grub.cfg** です。\\
 +\\
 +[[https://bugzilla.redhat.com/show_bug.cgi?id=1581478|1581478 – dnf system upgrade does not upgrade rescue kernel]] によるとレスキューカーネルは dracut が生成するものであるとの事が書かれている。\\
 +また、以下の kernel-install スクリプトによって dracut-config-rescue パッケージのスクリプトが呼び出されて、レスキューカーネルが生成される様である。\\
 +<code>
 +$ kernel-install add 4.17.5-200.fc28.x86_64 /lib/modules/4.17.5-200.fc28.x86_64/vmlinuz
 +</code>
 +kernel-install スクリプトは /usr/bin にありました。\\
 +<code>
 +$ which kernel-install
 +/usr/bin/kernel-install
 +$ cat /usr/bin/kernel-install
 +</code>
 +<file bash /usr/bin/kernel-install>
 +#!/usr/bin/bash
 +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
 +# ex: ts=8 sw=4 sts=4 et filetype=sh
 +# SPDX-License-Identifier: LGPL-2.1+
 +#
 +# This file is part of systemd.
 +#
 +# Copyright © 2013 Harald Hoyer
 +#
 +# systemd is free software; you can redistribute it and/or modify it
 +# under the terms of the GNU Lesser General Public License as published by
 +# the Free Software Foundation; either version 2.1 of the License, or
 +# (at your option) any later version.
 +#
 +# systemd is distributed in the hope that it will be useful, but
 +# WITHOUT ANY WARRANTY; without even the implied warranty of
 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +# General Public License for more details.
 +#
 +# You should have received a copy of the GNU Lesser General Public License
 +# along with systemd; If not, see <http://www.gnu.org/licenses/>.
 +
 +SKIP_REMAINING=77
 +
 +usage()
 +{
 +    echo "Usage:"
 +    echo "        $0 add KERNEL-VERSION KERNEL-IMAGE"
 +    echo "        $0 remove KERNEL-VERSION"
 +}
 +
 +dropindirs_sort()
 +{
 +    local suffix=$1; shift
 +    local -a files
 +    local f d i
 +
 +    readarray -t files <<<"$(
 +        for d in "$@"; do
 +            for i in "$d/"*"$suffix"; do
 +                if [[ -e "$i" ]]; then
 +                    echo "${i##*/}"
 +                fi
 +            done
 +        done | sort -Vu
 +    )"
 +
 +    for f in "${files[@]}"; do
 +        for d in "$@"; do
 +            if [[ -e "$d/$f" ]]; then
 +                echo "$d/$f"
 +                continue 2
 +            fi
 +        done
 +    done
 +}
 +
 +export LC_COLLATE=C
 +
 +for i in "$@"; do
 +    if [ "$i" == "--help" -o "$i" == "-h" ]; then
 +        usage
 +        exit 0
 +    fi
 +done
 +
 +if [[ "${0##*/}" == 'installkernel' ]]; then
 +    COMMAND='add'
 +else
 +    COMMAND="$1"
 +    shift
 +fi
 +
 +KERNEL_VERSION="$1"
 +KERNEL_IMAGE="$2"
 +
 +if [[ -f /etc/machine-id ]]; then
 +    read MACHINE_ID < /etc/machine-id
 +fi
 +
 +if [[ ! $COMMAND ]] || [[ ! $KERNEL_VERSION ]]; then
 +    echo "Not enough arguments" >&2
 +    exit 1
 +fi
 +
 +if ! [[ $MACHINE_ID ]]; then
 +    BOOT_DIR_ABS=$(mktemp -d /tmp/kernel-install.XXXXX) || exit 1
 +    trap "rm -rf '$BOOT_DIR_ABS'" EXIT INT QUIT PIPE
 +elif [[ -d /efi/loader/entries ]] || [[ -d /efi/$MACHINE_ID ]]; then
 +    BOOT_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION"
 +elif [[ -d /boot/loader/entries ]] || [[ -d /boot/$MACHINE_ID ]]; then
 +    BOOT_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION"
 +elif [[ -d /boot/efi/loader/entries ]] || [[ -d /boot/efi/$MACHINE_ID ]]; then
 +    BOOT_DIR_ABS="/boot/efi/$MACHINE_ID/$KERNEL_VERSION"
 +elif mountpoint -q /efi; then
 +    BOOT_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION"
 +elif mountpoint -q /boot/efi; then
 +    BOOT_DIR_ABS="/boot/efi/$MACHINE_ID/$KERNEL_VERSION"
 +else
 +    BOOT_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION"
 +fi
 +
 +export KERNEL_INSTALL_MACHINE_ID=$MACHINE_ID
 +
 +ret=0
 +
 +readarray -t PLUGINS <<<"$(
 +    dropindirs_sort ".install" \
 +        "/etc/kernel/install.d" \
 +        "/usr/lib/kernel/install.d"
 +)"
 +
 +case $COMMAND in
 +    add)
 +        if [[ ! "$KERNEL_IMAGE" ]]; then
 +            echo "Command 'add' requires an argument" >&2
 +            exit 1
 +        fi
 +
 +        mkdir -p "$BOOT_DIR_ABS" || {
 +            echo "Could not create boot directory '$BOOT_DIR_ABS'." >&2
 +            exit 1
 +        }
 +
 +        for f in "${PLUGINS[@]}"; do
 +            if [[ -x $f ]]; then
 +                "$f" add "$KERNEL_VERSION" "$BOOT_DIR_ABS" "$KERNEL_IMAGE"
 +                x=$?
 +                if [[ $x == $SKIP_REMAINING ]]; then
 +                    ret=0
 +                    break
 +                fi
 +                ((ret+=$x))
 +            fi
 +        done
 +
 +        if ! [[ $MACHINE_ID ]] && ! rmdir "$BOOT_DIR_ABS"; then
 +            echo "Warning: In kernel-install plugins, requiring BOOT_DIR_ABS to be preset is deprecated." >&2
 +            echo "         All plugins should not put anything in BOOT_DIR_ABS if the environment" >&2
 +            echo "         variable KERNEL_INSTALL_MACHINE_ID is empty." >&2
 +            rm -rf "$BOOT_DIR_ABS"
 +            ((ret+=$?))
 +        fi
 +        ;;
 +
 +    remove)
 +        for f in "${PLUGINS[@]}"; do
 +            if [[ -x $f ]]; then
 +                "$f" remove "$KERNEL_VERSION" "$BOOT_DIR_ABS"
 +                x=$?
 +                if [[ $x == $SKIP_REMAINING ]]; then
 +                    ret=0
 +                    break
 +                fi
 +                ((ret+=$x))
 +            fi
 +        done
 +
 +        rm -rf "$BOOT_DIR_ABS"
 +        ((ret+=$?))
 +        ;;
 +
 +    *)
 +        echo "Unknown command '$COMMAND'" >&2
 +        exit 1
 +        ;;
 +esac
 +
 +exit $ret
 +</file>
 +PLUGINS として /etc/kernel/install.d と /usr/lib/kernel/install.d の *.install を呼び出しているようです。\\
 +<code>
 +$ ll /etc/kernel/install.d
 +-rw-r--r-- 1 root root 0 10月  5 06:22 20-grubby.install
 +-rw-r--r-- 1 root root 0 10月  5 06:22 90-loaderentry.install
 +</code>
 +<code>
 +$ ll /usr/lib/kernel/install.d
 +-rwxr-xr-x 1 root root 1662  1月 30 01:05 10-devicetree.install
 +-rwxr-xr-x 1 root root 5368 10月  5 06:22 20-grub.install
 +-rwxr-xr-x 1 root root 1905  2月  8 17:08 20-grubby.install
 +-rwxr-xr-x 1 root root  424  2月  8 03:14 50-depmod.install
 +-rwxr-xr-x 1 root root 1719 12月  4 19:27 50-dracut.install
 +-rwxr-xr-x 1 root root 3391 12月  4 19:27 51-dracut-rescue.install
 +-rwxr-xr-x 1 root root 2106  2月  8 03:14 90-loaderentry.install
 +</code>
 +dracut-config-rescue-048 は壊れていて動作しないとの事なので確認したところ 049 だったので大丈夫そうである。\\
 +<code>
 +$ rpm -qa | grep dracut-config-rescue
 +dracut-config-rescue-049-25.git20181204.fc29.x86_64
 +</code>
 +dracut-config-rescue パッケージには以下のファイルが含まれている。\\
 +<code>
 +$ rpm -ql dracut-config-rescue
 +/etc/kernel/postinst.d/51-dracut-rescue-postinst.sh
 +/usr/lib/dracut/dracut.conf.d/02-rescue.conf
 +/usr/lib/kernel/install.d/51-dracut-rescue.install
 +</code>
 +PLUGINS として呼び出される 51-dracut-rescue.install は以下の様になっている。\\
 +<code>
 +$ cat /usr/lib/kernel/install.d/51-dracut-rescue.install
 +</code>
 +<file bash /usr/lib/kernel/install.d/51-dracut-rescue.install>
 +#!/usr/bin/bash
 +
 +export LANG=C
 +
 +COMMAND="$1"
 +KERNEL_VERSION="$2"
 +BOOT_DIR_ABS="${3%/*}/0-rescue"
 +KERNEL_IMAGE="$4"
 +
 +
 +dropindirs_sort()
 +{
 +    suffix=$1; shift
 +    args=("$@")
 +    files=$(
 +        while (( $# > 0 )); do
 +            for i in ${1}/*${suffix}; do
 +                [[ -f $i ]] && echo ${i##*/}
 +            done
 +            shift
 +        done | sort -Vu
 +    )
 +
 +    for f in $files; do
 +        for d in "${args[@]}"; do
 +            if [[ -f "$d/$f" ]]; then
 +                echo "$d/$f"
 +                continue 2
 +            fi
 +        done
 +    done
 +}
 +
 +[[ -f /etc/os-release ]] && . /etc/os-release
 +
 +if [[ ${KERNEL_INSTALL_MACHINE_ID+x} ]]; then
 +    MACHINE_ID=$KERNEL_INSTALL_MACHINE_ID
 +elif [[ -f /etc/machine-id ]] ; then
 +    read MACHINE_ID < /etc/machine-id
 +fi
 +
 +if ! [[ $MACHINE_ID ]]; then
 +    exit 0
 +fi
 +
 +if [[ -f /etc/kernel/cmdline ]]; then
 +    read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline
 +elif [[ -f /usr/lib/kernel/cmdline ]]; then
 +    read -r -d '' -a BOOT_OPTIONS < /usr/lib/kernel/cmdline
 +fi
 +
 +if ! [[ "${BOOT_OPTIONS[@]}" ]]; then
 +    read -r -d '' -a line < /proc/cmdline
 +    for i in "${line[@]}"; do
 +        [[ "${i#initrd=*}" != "$i" ]] && continue
 +        BOOT_OPTIONS+=("$i")
 +    done
 +fi
 +
 +if ! [[ ${BOOT_OPTIONS[*]} ]]; then
 +    echo "Could not determine the kernel command line parameters." >&2
 +    echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2
 +    exit 1
 +fi
 +
 +if [[ -d "${BOOT_DIR_ABS%/*}" ]]; then
 +    BOOT_DIR="/${MACHINE_ID}/0-rescue"
 +    BOOT_ROOT=${BOOT_DIR_ABS%$BOOT_DIR}
 +    LOADER_ENTRY="$BOOT_ROOT/loader/entries/${MACHINE_ID}-0-rescue.conf"
 +    KERNEL="linux"
 +    INITRD="initrd"
 +else
 +    BLS_DIR="/boot/loader/entries"
 +    BOOT_DIR_ABS="/boot"
 +    LOADER_ENTRY="$BLS_DIR/${MACHINE_ID}-0-rescue.conf"
 +    KERNEL="vmlinuz-0-rescue-${MACHINE_ID}"
 +    INITRD="initramfs-0-rescue-${MACHINE_ID}.img"
 +fi
 +
 +ret=0
 +
 +case "$COMMAND" in
 +    add)
 +        [[ -f "$LOADER_ENTRY" ]] && [[ -f "$BOOT_DIR_ABS/$KERNEL" ]] \
 +            && [[ -f "$BOOT_DIR_ABS/$INITRD" ]] && exit 0
 +
 +        # source our config dir
 +        for f in $(dropindirs_sort ".conf" "/etc/dracut.conf.d" "/usr/lib/dracut/dracut.conf.d"); do
 +            [[ -e $f ]] && . "$f"
 +        done
 +
 +        [[ $dracut_rescue_image != "yes" ]] && exit 0
 +
 +        [[ -d "$BOOT_DIR_ABS" ]] || mkdir -p "$BOOT_DIR_ABS"
 +
 +        if ! cp --reflink=auto "$KERNEL_IMAGE" "$BOOT_DIR_ABS/$KERNEL"; then
 +            echo "Can't copy '$KERNEL_IMAGE to '$BOOT_DIR_ABS/$KERNEL'!" >&2
 +        fi
 +
 +        if [[ ! -f "$BOOT_DIR_ABS/$INITRD" ]]; then
 +            dracut -f --no-hostonly -a "rescue" "$BOOT_DIR_ABS/$INITRD" "$KERNEL_VERSION"
 +            ((ret+=$?))
 +        fi
 +
 +        if [[ "${BOOT_DIR_ABS}" != "/boot" ]]; then
 +            {
 +                echo "title      $PRETTY_NAME - Rescue Image"
 +                echo "version    $KERNEL_VERSION"
 +                echo "machine-id $MACHINE_ID"
 +                echo "options    ${BOOT_OPTIONS[@]} rd.auto=1"
 +                echo "linux      $BOOT_DIR/linux"
 +                echo "initrd     $BOOT_DIR/initrd"
 +            } > $LOADER_ENTRY
 +        else
 +            cp -aT "${KERNEL_IMAGE%/*}/bls.conf" $LOADER_ENTRY
 +            sed -i 's/'$KERNEL_VERSION'/0-rescue-'${MACHINE_ID}'/' $LOADER_ENTRY
 +        fi
 +
 +        ((ret+=$?))
 +        ;;
 +
 +    remove)
 +        exit 0
 +        ;;
 +
 +    *)
 +        usage
 +        ret=1;;
 +esac
 +
 +exit $ret
 +</file>
 +initramfs-0-rescue-${MACHINE_ID}.img が存在しない場合に dracut による生成を行う様である。\\
 +<code bash>
 +        if [[ ! -f "$BOOT_DIR_ABS/$INITRD" ]]; then
 +            dracut -f --no-hostonly -a "rescue" "$BOOT_DIR_ABS/$INITRD" "$KERNEL_VERSION"
 +            ((ret+=$?))
 +        fi
 +</code>
 +initramfs-0-rescue-${MACHINE_ID}.img と vmlinuz-0-rescue-${MACHINE_ID} を削除して、kernel-install スクリプトを以下の様に呼び出してみる事にしました。\\
 +<code>
 +$ sudo rm /boot/*rescue*
 +$ sudo kernel-install add $(uname -r) /lib/modules/$(uname -r)/vmlinuz
 +</code>
 +initramfs-0-rescue-${MACHINE_ID}.img と vmlinuz-0-rescue-${MACHINE_ID} が新しい日付で再生成されました。\\
 +<code>
 +$ ll /boot/*rescue*
 +-rw------- 1 root root 72370961  2月 24 22:12 /boot/initramfs-0-rescue-74a4a050fda14b66a30a52debdd88dfe.img
 +-rwxr-xr-x 1 root root  8753352  2月 24 22:12 /boot/vmlinuz-0-rescue-74a4a050fda14b66a30a52debdd88dfe
 +</code>
 +再起動してみると grub2 のメニューエントリーが以下の様になってしまいました。\\
 +Fedora 29 Rescue が先頭に来ています。\\
 +<code>
 +Fedora 29 Rescue 74a4a050fda14b66a30a52debdd88dfe (4.20.8-200.fc29.x86_64)
 +Fedora (4.20.8-200.fc29.x86_64) 29 (Workstation Edition)
 +Fedora (4.20.7-200.fc29.x86_64) 29 (Workstation Edition)
 +Fedora (4.20.6-200.fc29.x86_64) 29 (Workstation Edition)
 +Fedora (4.4.3-300.fc23.x86_64) 23 (Workstation Edition)
 +Fedora (4.2.5-300.fc23.x86_64) 23 (Workstation Edition)
 +Fedora (0-rescue-74a4a050fda14b66a30a52debdd88dfe) 23 (Workstation Edition)
 +</code>
 +grub2-mkconfig で grub2 のメニューエントリーを再生成してみる事にしました。\\
 +<code>
 +$ sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg 
 +Generating grub configuration file ...
 +Found linux image: /boot/vmlinuz-4.20.8-200.fc29.x86_64
 +Found initrd image: /boot/initramfs-4.20.8-200.fc29.x86_64.img
 +Found linux image: /boot/vmlinuz-4.20.7-200.fc29.x86_64
 +Found initrd image: /boot/initramfs-4.20.7-200.fc29.x86_64.img
 +Found linux image: /boot/vmlinuz-4.20.6-200.fc29.x86_64
 +Found initrd image: /boot/initramfs-4.20.6-200.fc29.x86_64.img
 +Found linux image: /boot/vmlinuz-4.4.3-300.fc23.x86_64
 +Found initrd image: /boot/initramfs-4.4.3-300.fc23.x86_64.img
 +Found linux image: /boot/vmlinuz-4.2.5-300.fc23.x86_64
 +Found initrd image: /boot/initramfs-4.2.5-300.fc23.x86_64.img
 +Found linux image: /boot/vmlinuz-0-rescue-74a4a050fda14b66a30a52debdd88dfe
 +Found initrd image: /boot/initramfs-0-rescue-74a4a050fda14b66a30a52debdd88dfe.img
 +Found Windows Boot Manager on /dev/sda2@/EFI/Microsoft/Boot/bootmgfw.efi
 +Adding boot menu entry for EFI firmware configuration
 +done
 +</code>
 +grub2-mkconfig で再生成した grub2 のメニューエントリーは以下の様になっており大丈夫でした。\\
 +<code>
 +Fedora (4.20.8-200.fc29.x86_64) 29 (Workstation Edition)
 +Fedora (4.20.7-200.fc29.x86_64) 29 (Workstation Edition)
 +Fedora (4.20.6-200.fc29.x86_64) 29 (Workstation Edition)
 +Fedora (4.4.3-300.fc23.x86_64) 23 (Workstation Edition)
 +Fedora (4.2.5-300.fc23.x86_64) 23 (Workstation Edition)
 +Fedora (0-rescue-74a4a050fda14b66a30a52debdd88dfe) 29 (Workstation Edition)
 +Windows Boot Manager (on /dev/sda2)
 +System setup
 +</code>
 +
 +===== 参考文献 =====
 +[[https://bugzilla.redhat.com/show_bug.cgi?id=1581478|1581478 – dnf system upgrade does not upgrade rescue kernel]]\\
 +[[http://enakai00.hatenablog.com/entry/2015/11/27/152442|GRUB2で知っておくとよいこと - めもめも]]\\