Es ist ein Fehler!
Dies ist ein Fehler, der in der neuesten Version von Ubuntu Server LTS (Ubuntu Server 14.04 LTS) auftritt, wenn Sie die Startpartition (oder die Stammpartition, wenn die Startpartition nicht vorhanden ist) in einer LVM- oder RAID-Partition erstellen .
Weitere Informationen zu diesem Fehler erhalten Sie im Ubuntu Launchpad: Fehler # 1274320 "Fehler: Schreibvorgänge mit Festplattenfilter werden nicht unterstützt" .
Update: Dieser Fehler ist bereits in Ubuntu Server 14.04 und einigen neueren Ubuntu-Versionen behoben. Wahrscheinlich müssen Sie nur noch rennen apt-get upgrade
.
Warum tritt dieser Fehler auf?
Beim Booten des Systems liest GRUB ( load_env
) Daten ein /boot/grub/grubenv
. Diese Datei heißt GRUB Environment Block .
Aus dem GRUB-Handbuch:
Es ist oft nützlich, sich eine kleine Menge von Informationen von einem Start zum nächsten merken zu können.
[...]
Beim Booten werden mit dem Befehl load_env (siehe load_env) Umgebungsvariablen daraus geladen, und mit dem Befehl save_env (siehe save_env) werden Umgebungsvariablen darin gespeichert.
[...]
grub-mkconfig
verwendet diese Funktion zum Implementieren GRUB_SAVEDEFAULT
Dieses Verhalten kann begründet werden /etc/grub.d/00_header
( update-grub
verwendet diese Datei, um die /boot/grub/grub.cfg
Datei zu generieren ):
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
Das Problem ist, dass die save_env
Anweisung nur bei einfachen Installationen funktioniert (Sie können nicht save_env
innerhalb eines RAID- oder LVM-Datenträgers ausgeführt werden). Aus dem GRUB-Handbuch:
Aus Sicherheitsgründen ist dieser Speicher nur verfügbar, wenn er auf einer einfachen Festplatte (kein LVM oder RAID) installiert ist, ein nicht prüfsummierendes Dateisystem (kein ZFS) verwendet und BIOS- oder EFI-Funktionen (kein ATA, USB oder IEEE1275) verwendet werden.
Die GRUB- Recordfail- Funktion verwendet die save_env
Anweisung, um den Recordfail-Status zu aktualisieren (siehe Ubuntu-Hilfe - Grub 2 , Abschnitt "Letzter Start fehlgeschlagen oder Start im Wiederherstellungsmodus"). In Ubuntu 14.04 (und in neueren Debian-Versionen) wird die save_env
Anweisung (innerhalb der Recordfail-Funktion) jedoch verwendet, selbst wenn GRUB in einem LVM oder RAID installiert ist.
Sehen wir uns die Zeilen 104 bis 124 an /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 überspringt die Recordfail-Funktion korrekt, wenn nicht unterstützte Dateisysteme (btrfs, zfs usw.) verwendet werden, aber LVM und RAID werden zu keinem Zeitpunkt übersprungen .
Wie schützt sich GRUB vor dem Schreiben in RAID und LVM?
Um in einem Dateisystem richtig lesen / schreiben zu können, lädt GRUB ein entsprechendes Modul.
GRUB verwendet das diskfilter- Modul ( insmod diskfilter
) in RAID-Partitionen und das lvm- Modul in LVM-Partitionen.
Sehen wir uns die Lese- / Schreib-Implementierung des Diskfilter- Moduls an:
apt-get source grub2
vim grub2-2.02~beta2/grub-core/disk/diskfilter.c
Ich füge den Code hier ein (Zeilen von 808 bis 823). Die in dieser Frage angezeigte Warnung wird in Zeile 821 angezeigt:
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");
}
Die grub_diskfilter_read
Funktion ist implementiert (und GRUB kann RAID-Dateisysteme lesen). Die grub_diskfilter_write
Funktion löst jedoch einen GRUB_ERR_NOT_IMPLEMENTED_YET
Fehler aus.
Warum löst die Verwendung quick_boot=0
das Problem? Und warum ist es die falsche Lösung?
Wenn Sie sich den /etc/grub.d/00_header
Code noch einmal ansehen, werden Sie feststellen, dass die Funktion recordfail nur verwendet wird, wenn quick_boot=1
. quick_boot
Wenn Sie also von 1 auf 0 wechseln , wird die Recordfail-Funktion deaktiviert und Schreibvorgänge in der RAID / LVM-Partition werden deaktiviert.
Es werden jedoch auch viele andere Funktionen deaktiviert (Ausführen, grep \$quick_boot /etc/grub.d/*
und Sie werden sehen). Wenn Sie eines Tages Ihr /boot/grub
Verzeichnis außerhalb des RAID / LVM ändern , wird die Recordfail-Funktion dennoch deaktiviert.
Zusammenfassend deaktiviert diese Lösung unnötigerweise Funktionen und ist nicht generisch.
Was ist die richtige Lösung?
Für die richtige Lösung sollten Sie die save_env
Anweisungen deaktivieren , wenn sich GRUB in LVM- oder RAID-Partitionen befindet.
Ein Patch wurde im Debian Bug Tracker-System vorgeschlagen, um diese Lösung zu implementieren. Sie finden es unter: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754921
Die Idee hinter diesem Patch ist:
- Führen Sie einen
grub-probe --target=abstraction "${grubdir}"
Befehl aus, um zu ermitteln, welche Art von Abstraktionsmodulen GRUB zum Lesen / Schreiben von Dateien im /boot/grub
Verzeichnis verwendet.
- Wenn GRUB das Modul
diskfilter
oder verwendet lvm
, überspringen Sie die save_env
Anweisung recordfail und schreiben Sie einen entsprechenden Kommentar in die /boot/grub/grub.cfg
Datei.
- Zum Beispiel,
# GRUB lacks write support for /dev/md0, so recordfail support is disabled.
Wie wende ich die richtige Lösung an?
Wenn Sie nicht darauf warten möchten, dass dieser Patch von den Ubuntu / Debian-Leuten im offiziellen Code angewendet wird, können Sie meinen Patch verwenden 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