O CentOS 7 classifica incorretamente as entradas do menu do kernel no grub.cfg?

3

Eu notei uma ordem inesperada de entradas do menu grub em um sistema CentOS 7:

Tem os seguintes kernels instalados:

$ 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

Na minha interpretação do esquema de versão, a versão '3.10.0-123.9.3.el7' é maior que '3.10.0-123.el7'. Isso também é consistente com os arquivos mtime - e também corresponde ao uname -a outputs:

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

Mas o /boot/grub2/grub.cfg usa outro pedido:

$ 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

Huh?

Como o sistema recebeu alguns parâmetros adicionais do kernel, grub.cfg foi explicitamente gerado novamente pelo seguinte comando:

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

O que deve ser o método oficial - conforme documentado no manual.

A encomenda está aparentemente implementada através de:

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

Este é um bug bem conhecido no grub2-mkconfig?

No entanto, não consegui encontrar um relatório de erros.

Surpreendentemente, em outra máquina do CentOS 7 (que também está atualizada), a ordem do grub.cfg está correta:

$ 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 

A diferença entre as duas máquinas é: na segunda máquina grub2-mkconfig nunca foi executada manualmente.

E, de fato, ao executá-lo manualmente, a ordem também está errada:

# 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

Assim, ao instalar as atualizações do kernel via yum update , o script de instalação não executa grub-2-mkconfig -o /boot/efi/EFI/centos/grub.cfg . Como o grub.cfg é regenerado durante a instalação de um pacote do kernel, então?

    
por maxschlepzig 26.11.2014 / 16:35

3 respostas

1

Este é um bug bem conhecido:

Para determinar como um pacote do kernel atualiza grub.cfg , pode-se exibir os scripts via:

$ 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

Isso mostra que /usr/sbin/new-kernel-pkg é chamado - o que, por sua vez, chama sujos .

Solução alternativa

(até que seja corrigido no 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=""
-  for i in "$@" ; do
-    if version_test_gt "$i" "$version_find_latest_a" ; then
-      version_find_latest_a="$i"
-    fi
-  done
-  echo "$version_find_latest_a"
+  # workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1124074
+  # 'grub2-mkconfig wrong sorting'
+  {
+    for i in "$@"; do
+      echo $i
+    done | grep -v rescue | sort -V
+    for i in "$@"; do
+      echo $i
+    done | grep rescue | sort -V
+  } | head -n 1
 }
    
por 26.11.2014 / 16:49
1

Eu postei um patch para os dois bugs do bugzilla.redhat.com que realmente corrige esse problema. O patch do maxschlepzig está muito próximo da resposta certa, mas não é bem assim. Meu patch é baseado nele.

    
por 09.12.2014 / 01:02
0

Acho que a maneira como você determina o que acontece depois que um kernel é instalado é a seguinte usando rpm + a opção --scripts .

Exemplo

$ 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 $?

Isso é dividido em seções: pós-instalação , pré-instalação e postrans . A ferramenta que faz a instalação / remoção de kernels é este script:

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

Quem é o proprietário deste script?

O script kernel-install faz parte do Systemd.

$ rpm -qf /bin/kernel-install 
systemd-208-28.fc20.x86_64
    
por 26.11.2014 / 17:38

Tags