C'est un bogue!
Il s'agit d'un bogue qui survient dans la version la plus récente d'Ubuntu Server LTS (Ubuntu Server 14.04 LTS) lorsque vous créez la partition de démarrage (ou la partition racine, lorsque la partition de démarrage n'existe pas) dans une partition LVM ou RAID. .
Vous pouvez obtenir plus d'informations sur ce bogue dans Ubuntu Launchpad: Bug n ° 1274320 "Erreur: les écritures de filtre de disque ne sont pas prises en charge" .
Mise à jour: Ce bogue est déjà corrigé dans Ubuntu Server 14.04 et certaines versions plus récentes d’Ubuntu. Probablement, il suffit de courir apt-get upgrade
.
Pourquoi ce bug se produit?
Lorsque le système démarre, GRUB lit les load_env
données ( ) dans /boot/grub/grubenv
. Ce fichier s'appelle GRUB Environment Block .
Du manuel GRUB:
Il est souvent utile de pouvoir se souvenir d’une petite quantité d’informations d’un démarrage à l’autre.
[...]
Au démarrage, la commande load_env (voir load_env) charge les variables d'environnement à partir de celle-ci, et la commande save_env (voir save_env) lui enregistre les variables d'environnement.
[...]
grub-mkconfig
utilise cette installation pour mettre en œuvre GRUB_SAVEDEFAULT
Ce comportement peut être trouvé dans /etc/grub.d/00_header
( update-grub
utilise ce fichier pour générer le /boot/grub/grub.cfg
fichier):
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
Le problème est que l' save_env
instruction ne fonctionne que dans des installations simples (vous ne pouvez pas exécuter à l' save_env
intérieur d'un disque RAID ou LVM). Du manuel GRUB:
Pour des raisons de sécurité, ce stockage est uniquement disponible lorsqu’il est installé sur un disque ordinaire (sans LVM ou RAID), avec un système de fichiers non soumis à un checksum (sans ZFS) et avec les fonctions BIOS ou EFI (sans ATA, USB ou IEEE1275).
La fonction recordfail de GRUB utilise l' save_env
instruction pour mettre à jour l'état recordfail (voir la section Aide Ubuntu - Grub 2 , section "Dernier échec du démarrage ou démarrage en mode de récupération"). Cependant, dans Ubuntu 14.04 (et dans les versions récentes de Debian), l’ save_env
instruction (à l’intérieur de la fonctionnalité recordfail) est utilisée même si GRUB est installé dans un LVM ou un RAID.
Voyons les lignes de 104 à 124 dans /etc/grub.d/00_header
:
if [ "$quick_boot" = 1 ]; then
[...]
case "$FS" in
btrfs | cpiofs | newc | odc | romfs | squash4 | tarfs | zfs)
cat <<EOF
# GRUB lacks write support for $FS, so recordfail support is disabled.
[...]
if [ -n "\${have_grubenv}" ]; then if [ -z "\${boot_once}" ]; then save_env recordfail; fi; fi
GRUB ignore correctement la fonction recordfail lors de l’utilisation de systèmes de fichiers non pris en charge (btrfs, zfs, etc.), mais ne saute pas le LVM et le RAID à tout moment .
Comment GRUB se protège-t-il contre l'écriture dans RAID et LVM?
Pour lire / écrire correctement dans un système de fichiers, GRUB charge un module approprié.
GRUB utilise le module diskfilter ( insmod diskfilter
) dans les partitions RAID et le module lvm dans les partitions LVM.
Voyons l'implémentation en lecture / écriture du module diskfilter :
apt-get source grub2
vim grub2-2.02~beta2/grub-core/disk/diskfilter.c
Je colle le code ici (lignes 808 à 823). L'avertissement indiqué dans cette question apparaît à la ligne 821:
static grub_err_t
grub_diskfilter_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_size_t size, char *buf)
{
return read_lv (disk->data, sector, size, buf);
}
static grub_err_t
grub_diskfilter_write (grub_disk_t disk __attribute ((unused)),
grub_disk_addr_t sector __attribute ((unused)),
grub_size_t size __attribute ((unused)),
const char *buf __attribute ((unused)))
{
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"diskfilter writes are not supported");
}
La grub_diskfilter_read
fonction est implémentée (et GRUB peut lire les systèmes de fichiers RAID). Cependant, la grub_diskfilter_write
fonction génère une GRUB_ERR_NOT_IMPLEMENTED_YET
erreur.
Pourquoi l'utilisation quick_boot=0
résout-elle le problème? Et pourquoi est-ce la mauvaise solution?
Si vous regardez une fois de plus dans le /etc/grub.d/00_header
code, vous verrez que le recordfail présenté n'est utilisé que quand quick_boot=1
. Ainsi, passer quick_boot
de 1 à 0 désactive la fonctionnalité recordfail et désactive les écritures dans la partition RAID / LVM.
Cependant, il désactivera de nombreuses autres fonctionnalités (exécutez grep \$quick_boot /etc/grub.d/*
et vous verrez). Plus encore, si un jour vous changez votre /boot/grub
répertoire en dehors du RAID / LVM, la fonction recordfail sera toujours désactivée.
En résumé, cette solution désactive inutilement les fonctionnalités, et ce n’est pas générique.
Quelle est la bonne solution?
La solution appropriée doit envisager de désactiver les save_env
instructions lorsque GRUB se trouve dans des partitions LVM ou RAID.
Un correctif a été proposé dans le système Debian Bug Tracker pour mettre en œuvre cette solution. Vous pouvez le trouver à l' adresse suivante : https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754921.
L'idée derrière ce patch est:
- Exécutez une
grub-probe --target=abstraction "${grubdir}"
commande pour obtenir le type de modules d'abstraction que GRUB utilise pour lire / écrire des fichiers dans le /boot/grub
répertoire.
- Si GRUB utilise le module
diskfilter
ou lvm
, ignorez l' save_env
instruction recordfail et écrivez un commentaire approprié dans le /boot/grub/grub.cfg
fichier;
- Par exemple,
# GRUB lacks write support for /dev/md0, so recordfail support is disabled.
Comment appliquer la bonne solution?
Si vous ne voulez pas attendre que ce correctif soit appliqué par les gars d'Ubuntu / Debian dans le code officiel, vous pouvez utiliser mon correctif 00_header
:
# Download
wget https://gist.githubusercontent.com/rarylson/da6b77ad6edde25529b2/raw/99f266a10e663e1829efc25eca6eddb9412c6fdc/00_header_patched
# Apply
mv /etc/grub.d/00_header /etc/grub.d/00_header.orig
mv 00_header_patched /etc/grub.d/00_header
# Disable the old script and enable the new one
chmod -x /etc/grub.d/00_header.orig
chmod +x /etc/grub.d/00_header
# Update Grub
update-grub