====== Fedora Rescue カーネルのアップデート ====== Fedora のレスキュー用のカーネル(vmlinuz) と RAM ディスク(initramfs) を更新する方法を記載する。\\ \\ 結論から言うと以下のコマンドを実行すると Fedora 29 では上手く行きました。\\ $ 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 ※**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 パッケージのスクリプトが呼び出されて、レスキューカーネルが生成される様である。\\ $ kernel-install add 4.17.5-200.fc28.x86_64 /lib/modules/4.17.5-200.fc28.x86_64/vmlinuz kernel-install スクリプトは /usr/bin にありました。\\ $ which kernel-install /usr/bin/kernel-install $ cat /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 . 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 PLUGINS として /etc/kernel/install.d と /usr/lib/kernel/install.d の *.install を呼び出しているようです。\\ $ 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 $ 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 dracut-config-rescue-048 は壊れていて動作しないとの事なので確認したところ 049 だったので大丈夫そうである。\\ $ rpm -qa | grep dracut-config-rescue dracut-config-rescue-049-25.git20181204.fc29.x86_64 dracut-config-rescue パッケージには以下のファイルが含まれている。\\ $ 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 PLUGINS として呼び出される 51-dracut-rescue.install は以下の様になっている。\\ $ cat /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 initramfs-0-rescue-${MACHINE_ID}.img が存在しない場合に dracut による生成を行う様である。\\ if [[ ! -f "$BOOT_DIR_ABS/$INITRD" ]]; then dracut -f --no-hostonly -a "rescue" "$BOOT_DIR_ABS/$INITRD" "$KERNEL_VERSION" ((ret+=$?)) fi initramfs-0-rescue-${MACHINE_ID}.img と vmlinuz-0-rescue-${MACHINE_ID} を削除して、kernel-install スクリプトを以下の様に呼び出してみる事にしました。\\ $ sudo rm /boot/*rescue* $ sudo kernel-install add $(uname -r) /lib/modules/$(uname -r)/vmlinuz initramfs-0-rescue-${MACHINE_ID}.img と vmlinuz-0-rescue-${MACHINE_ID} が新しい日付で再生成されました。\\ $ 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 再起動してみると grub2 のメニューエントリーが以下の様になってしまいました。\\ Fedora 29 Rescue が先頭に来ています。\\ 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) grub2-mkconfig で grub2 のメニューエントリーを再生成してみる事にしました。\\ $ 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 grub2-mkconfig で再生成した grub2 のメニューエントリーは以下の様になっており大丈夫でした。\\ 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 ===== 参考文献 ===== [[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で知っておくとよいこと - めもめも]]\\