È un BUG!
Questo è un bug che si verifica nella versione più recente di Ubuntu Server LTS (Ubuntu Server 14.04 LTS), quando si crea la partizione di avvio (o la partizione di root, quando la partizione di avvio non esiste) all'interno di una partizione LVM o RAID .
È possibile ottenere ulteriori informazioni su questo bug nel Launchpad di Ubuntu: Bug # 1274320 "Errore: le scritture di diskfilter non sono supportate" .
Aggiornamento: questo errore è già stato risolto in Ubuntu Server 14.04 e in alcune versioni più recenti di Ubuntu. Probabilmente devi solo correre apt-get upgrade
.
Perché si verifica questo errore?
Quando il sistema si avvia, GRUB legge i load_env
dati ( ) /boot/grub/grubenv
. Questo file si chiama GRUB Environment Block .
Dal manuale di GRUB:
È spesso utile essere in grado di ricordare una piccola quantità di informazioni da uno stivale all'altro.
[...]
Al momento dell'avvio, il comando load_env (vedi load_env) carica le variabili d'ambiente da esso, e il comando save_env (vedi save_env) vi salva le variabili d'ambiente.
[...]
grub-mkconfig
utilizza questa funzione per implementare GRUB_SAVEDEFAULT
Questo comportamento può essere fondato in /etc/grub.d/00_header
( update-grub
utilizza questo file per generare il /boot/grub/grub.cfg
file):
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
Il problema è che l' save_env
istruzione funziona solo in installazioni semplici (non è possibile eseguire save_env
all'interno di un disco RAID o LVM). Dal manuale di GRUB:
Per motivi di sicurezza, questo spazio di archiviazione è disponibile solo se installato su un disco normale (senza LVM o RAID), utilizzando un filesystem senza checksum (senza ZFS) e utilizzando le funzioni BIOS o EFI (no ATA, USB o IEEE1275).
La funzione recordfail di GRUB utilizza l' save_env
istruzione per aggiornare lo stato del recordfail (consultare la Guida di Ubuntu - Grub 2 , sezione "Ultimo avvio non riuscito o avvio in modalità di recupero"). Tuttavia, in Ubuntu 14.04 (e nelle recenti versioni di Debian), l' save_env
istruzione (all'interno della funzione recordfail) viene utilizzata anche se GRUB è installato in un LVM o un RAID.
Vediamo le linee da 104 a 124 in /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 salta correttamente la funzione recordfail quando si utilizzano filesystem non supportati (btrfs, zfs, ecc.), Ma non salta LVM e RAID in nessun momento .
In che modo GRUB si protegge dalla scrittura all'interno di RAID e LVM?
Per leggere / scrivere correttamente in un filesystem, GRUB carica un modulo appropriato.
GRUB utilizza il modulo diskfilter ( insmod diskfilter
) nelle partizioni RAID e il modulo lvm nelle partizioni LVM.
Vediamo l'implementazione in lettura / scrittura del modulo diskfilter :
apt-get source grub2
vim grub2-2.02~beta2/grub-core/disk/diskfilter.c
Sto incollando il codice qui (righe da 808 a 823). L'avvertimento mostrato in questa domanda appare alla riga 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
funzione è implementata (e GRUB può leggere filesystem RAID). Tuttavia, la grub_diskfilter_write
funzione genera un GRUB_ERR_NOT_IMPLEMENTED_YET
errore.
Perché l'utilizzo quick_boot=0
risolve il problema? E perché è la soluzione sbagliata?
Se guardi ancora una volta nel /etc/grub.d/00_header
codice, vedrai che il recordfail in primo piano viene utilizzato solo quando quick_boot=1
. Pertanto, la modifica quick_boot
da 1 a 0 disabilita la funzione recordfail e disabilita le scritture nella partizione RAID / LVM.
Tuttavia, disabiliterà anche molte altre funzionalità (esegui grep \$quick_boot /etc/grub.d/*
e vedrai). /boot/grub
Inoltre , se un giorno cambiate la vostra directory al di fuori del RAID / LVM, la funzione recordfail verrà comunque disabilitata.
Riassumendo, questa soluzione disabilita inutilmente le funzionalità e non è generica.
Qual è la soluzione corretta?
La soluzione corretta dovrebbe considerare la disabilitazione delle save_env
istruzioni quando GRUB si trova all'interno di partizioni LVM o RAID.
Una patch è stata proposta nel sistema Debian Bug Tracker per implementare questa soluzione. Può essere trovato in: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754921
L'idea alla base di questa patch è:
- Esegui un
grub-probe --target=abstraction "${grubdir}"
comando per ottenere quale tipo di moduli di astrazione utilizza GRUB per leggere / scrivere i file nella /boot/grub
directory;
- Se GRUB utilizza il modulo
diskfilter
o lvm
, salta l' save_env
istruzione recordfail e scrive un commento appropriato nel /boot/grub/grub.cfg
file;
- Per esempio,
# GRUB lacks write support for /dev/md0, so recordfail support is disabled.
Come applicare la soluzione corretta?
Se non vuoi aspettare che questa patch venga applicata dai ragazzi di Ubuntu / Debian nel codice ufficiale, puoi usare il mio patch 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