web-dev-qa-db-ja.com

CentOS 7はgrub.cfgのカーネルメニューエントリを誤ってソートしますか?

CentOS7システムでのgrubメニューエントリの予期しない順序に気づきました。

次のカーネルがインストールされています。

$ ls /boot/vmlinuz* -ltr
Jun 30 14:17 /boot/vmlinuz-3.10.0-123.el7.x86_64
Nov  6 16:14 /boot/vmlinuz-3.10.0-123.9.3.el7.x86_64
Nov 23 17:12 /boot/vmlinuz-0-rescue-c61cbe0918ab45e0927fb5d31cf45f98

バージョンスキームの私の解釈では、バージョン「3.10.0-123.9.3.el7」は「3.10.0-123.el7」よりも大きいです。これは、ファイルmtimeとも一致し、uname -a出力とも一致します。

3.10.0-123.el7.x86_64     Mon Jun 30 12:09:22 UTC 2014
3.10.0-123.9.3.el7.x86_64 Thu Nov 6  15:06:03 UTC 2014

ただし、/boot/grub2/grub.cfgは別の順序を使用します。

$ grep vmlinuz-3 /boot/grub2/grub.cfg | sed 's/root=.*//'
linux16 /vmlinuz-3.10.0-123.el7.x86_64 
linux16 /vmlinuz-3.10.0-123.9.3.el7.x86_64

え?

システムがいくつかの追加のカーネルパラメータを取得したため、grub.cfgは次のコマンドを使用して明示的に再生成されました。

# grub2-mkconfig -o /boot/grub2/grub.cfg 

マニュアルに記載されているように、どちらが 公式の方法 -である必要があります。

順序付けは、次の方法で実装されているようです。

/etc/grub.d/10_linux
  -> /usr/share/grub/grub-mkconfig_lib
     -> version_find_latest()
        -> version_test_gt()

これはgrub2-mkconfigのよく知られたバグですか?

しかし、バグレポートは見つかりませんでした。

驚いたことに、別のCentOS 7マシン(これも最新です)では、grub.cfgの順序は正しいです。

$ grep vmlinuz /boot/efi/EFI/centos/grub.cfg | sed 's/root=.*//'
linuxefi /vmlinuz-3.10.0-123.9.3.el7.x86_64 
linuxefi /vmlinuz-3.10.0-123.9.2.el7.x86_64 
linuxefi /vmlinuz-3.10.0-123.8.1.el7.x86_64 
linuxefi /vmlinuz-3.10.0-123.6.3.el7.x86_64 
linuxefi /vmlinuz-3.10.0-123.el7.x86_64 
linuxefi /vmlinuz-0-rescue-48235f1ad5c943c3a7dfd1551a1fc5b8 

2台のマシンの違いは次のとおりです。2台目のマシンではgrub2-mkconfigが手動で実行されたことはありません。

実際、手動で実行すると、順序も間違っています。

# grub2-mkconfig -o del.cfg
# grep vmlinuz del.cfg | sed 's/root=.*//' 
linuxefi /vmlinuz-3.10.0-123.el7.x86_64 
linuxefi /vmlinuz-3.10.0-123.9.3.el7.x86_64 
linuxefi /vmlinuz-3.10.0-123.9.2.el7.x86_64 
linuxefi /vmlinuz-3.10.0-123.8.1.el7.x86_64 
linuxefi /vmlinuz-3.10.0-123.6.3.el7.x86_64 
linuxefi /vmlinuz-0-rescue-48235f1ad5c943c3a7dfd1551a1fc5b8

したがって、yum updateを介してカーネル更新をインストールする場合、インストールスクリプトはgrub-2-mkconfig -o /boot/efi/EFI/centos/grub.cfgを実行しないようです。では、カーネルパッケージのインストール中にgrub.cfgはどのように再生成されますか?

3
maxschlepzig

これはよく知られているバグです。

カーネルパッケージがどのように更新されるかを決定するにはgrub.cfg次の方法でスクリプトを表示できます。

$ yum whatprovides /boot/vmlinuz-3.10.0-123.9.3.el7.x86_64
kernel-3.10.0-123.9.3.el7.x86_64 : The Linux kernel
[..]
$ rpm -q --scripts kernel-3.10.0-123.9.3.el7.x86_64

これは、/usr/sbin/new-kernel-pkgが呼び出されます-これは次に grubby を呼び出します。

Workaround

(RHEL/CentOSで修正されるまで)

 --- /usr/share/grub/grub-mkconfig_lib.orig 2014-06-30 18:16:11.000000000 +0200 
 +++/usr/share/grub/grub-mkconfig_lib 2014-11-26 17:38:57.814000000 +0100 
 @@ -255,13 +255,24 @@ 
 
 version_find_latest()
 {
-version_find_latest_a = "" 
-fori in "$ @"; do 
-ifversion_test_gt "$ i" "$ version_find_latest_a"; then 
-version_find_latest_a = "$ i" 
-fi 
-done 
-echo "$ version_find_latest_a" 
 +#https:/の回避策/bugzilla.redhat.com/show_bug.cgi?id=1124074
+#'grub2-mkconfig間違った並べ替え '
 + {
 + for i in "$ @"; do 
 + echo $ i 
 +完了| grep-vレスキュー|並べ替え-V 
 + for i in "$ @"; do 
 + echo $ i 
 +完了| grepレスキュー|並べ替え-V 
 +} | head -n 1 
} 
1
maxschlepzig

この問題を実際に修正する2つのbugzilla.redhat.comバグへのパッチを投稿しました。 maxschlepzigのパッチは正解に非常に近いですが、完全ではありません。私のパッチは彼に基づいています。

1
edgan

カーネルのインストール後に何が起こるかを判断する方法は、rpm + --scriptsスイッチを使用して次のようになると思います。

$ rpm --scripts -q kernel-$(uname -r)
postinstall scriptlet (using /bin/sh):

if [ `uname -i` == "x86_64" -o `uname -i` == "i386" ] &&
   [ -f /etc/sysconfig/kernel ]; then
  /bin/sed -r -i -e 's/^DEFAULTKERNEL=kernel-smp$/DEFAULTKERNEL=kernel/' /etc/sysconfig/kernel || exit $?
fi
preuninstall scriptlet (using /bin/sh):
/bin/kernel-install remove 3.16.6-203.fc20.x86_64 /boot/vmlinuz-3.16.6-203.fc20.x86_64 || exit $?
posttrans scriptlet (using /bin/sh):
/bin/kernel-install add 3.16.6-203.fc20.x86_64 /boot/vmlinuz-3.16.6-203.fc20.x86_64 || exit $?

これはセクションに分かれています:postinstallpreuninstall、およびpostrans。カーネルのインストール/削除を行うツールは次のスクリプトです。

/bin/kernel-install add <kernel label> </path/to/boot/vmlinuz-...> || exit $

このスクリプトの所有者は誰ですか?

スクリプトkernel-installはSystemdの一部です。

$ rpm -qf /bin/kernel-install 
systemd-208-28.fc20.x86_64
0
slm