Bu bir böcek!
Bu, bir LVM veya RAID bölümünün içindeki önyükleme bölümünü (veya önyükleme bölümü olmadığında kök bölümünü) oluşturduğunuzda Ubuntu Server LTS'nin (Ubuntu Server 14.04 LTS) en son sürümünde meydana gelen bir hatadır .
Bu hata hakkında daha fazla bilgiyi Ubuntu Launchpad'de bulabilirsiniz: Hata # 1274320 "Hata: diskfilter yazma desteklenmiyor" .
Güncelleme: Bu hata zaten Ubuntu Server 14.04 ve bazı yeni Ubuntu sürümlerinde düzeltildi. Muhtemelen, sadece koşman gerek apt-get upgrade
.
Bu hata neden oluyor?
Sistem önyüklenirken GRUB, load_env
içindeki verileri okur /boot/grub/grubenv
. Bu dosyaya GRUB Çevre Bloğu denir .
GRUB El Kitabından:
Bir açılıştan diğerine az miktarda bilgi hatırlayabilmek genellikle yararlıdır.
[...]
Önyükleme sırasında, load_env komutu (bkz. Load_env) ortam değişkenlerini buradan yükler ve save_env (bkz: save_env) komutu ortam değişkenlerini buna kaydeder.
[...]
grub-mkconfig
uygulamak için bu tesisi kullanır GRUB_SAVEDEFAULT
Bu davranış kurulan edilebilir /etc/grub.d/00_header
( update-grub
oluşturmak için bu dosyayı kullanır /boot/grub/grub.cfg
dosyası):
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
Sorun, save_env
ifadenin yalnızca basit kurulumlarda işe yaramasıdır ( save_env
bir RAID veya LVM diskinde çalışamazsınız ). GRUB el kitabından:
Güvenlik nedenleriyle, bu depolama yalnızca düz bir diske (LVM veya RAID olmadan), kontrol toplamı olmayan bir dosya sistemi (ZFS olmadan) ve BIOS veya EFI işlevlerini kullanarak (ATA, USB veya IEEE1275 olmadan) kullanılabilir.
GRUB kayıt hatası özelliği, save_env
kayıt hatası durumunu güncellemek için ifadeyi kullanır (bkz. Ubuntu Yardım - Grub 2 , "Son Önyükleme Başarısız Oldu veya Kurtarma Moduna Başlatma" bölümü). Bununla birlikte, Ubuntu 14.04'te (ve son Debian versiyonlarında), save_env
GRUB bir LVM'ye veya RAID'e kurulsa bile , ifade (kayıt hatası özelliğinin içinde) kullanılır.
104'den 124'e kadar olan satırları görelim /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, desteklenmeyen dosya sistemlerini (btrfs, zfs, vb.) Kullanırken kayıt hatası özelliğini doğru atlar, ancak hiçbir zaman LVM ve RAID'i atlamaz .
GRUB, RAID ve LVM içine yazmaktan nasıl korunur?
Bir dosya sisteminde doğru okumak / yazmak için GRUB uygun bir modül yükler.
GRUB, RAID bölümlerinde diskfilter modülünü ( insmod diskfilter
) ve LVM bölümlerinde lvm modülünü kullanır.
Diskfilter modülünün okuma / yazma uygulamasını görelim :
apt-get source grub2
vim grub2-2.02~beta2/grub-core/disk/diskfilter.c
Kodu buraya yapıştıracağım (satır 808 - 823). Bu soruda gösterilen uyarı 821 satırında görünür:
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");
}
grub_diskfilter_read
Fonksiyonu (ve GRUB RAID dosya sistemleri okuyabilir) uygulanmaktadır. Ancak, grub_diskfilter_write
işlev bir GRUB_ERR_NOT_IMPLEMENTED_YET
hataya neden olur.
Neden kullanmak quick_boot=0
sorunu çözüyor? Ve neden yanlış bir çözüm?
/etc/grub.d/00_header
Kodda bir kez daha bakarsanız , özellikli kaydın yalnızca ne zaman kullanıldığını göreceksiniz quick_boot=1
. Bu nedenle, quick_boot
1'den 0'a değiştirmek , kayıt hatası özelliğini devre dışı bırakır ve RAID / LVM bölümünde yazmayı devre dışı bırakır.
Ancak, diğer birçok özelliği de devre dışı bırakacaktır (çalıştırın grep \$quick_boot /etc/grub.d/*
ve göreceksiniz). Dahası, bir gün /boot/grub
dizinizi RAID / LVM dışına değiştirirseniz, kayıt hatası özelliği hala devre dışı kalır.
Özetle, bu çözüm gereksiz yere özellikleri devre dışı bırakır ve genel değildir.
Doğru çözüm nedir?
Doğru çözüm save_env
, GRUB LVM veya RAID bölümlerinin içindeyken ifadeleri devre dışı bırakmayı düşünmelidir .
Bu çözümü uygulamak için Debian Bug Tracker sisteminde bir yama önerildi. Bu bulunabilir: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754921
Bu yamanın arkasındaki fikir:
grub-probe --target=abstraction "${grubdir}"
GRUB /boot/grub
dizindeki dosyaları okumak / yazmak için ne tür soyutlama modüllerini kullandığını öğrenmek için bir komut çalıştırın ;
- GRUB
diskfilter
veya lvm
modülünü kullanıyorsa, recordfail save_env
deyimini atlayın ve dosyaya uygun bir yorum /boot/grub/grub.cfg
yazın;
- Örneğin,
# GRUB lacks write support for /dev/md0, so recordfail support is disabled.
Doğru çözüm nasıl uygulanır?
Bu yamayı beklemek istemiyorsanız resmi koddaki Ubuntu / Debian adamları tarafından uygulanacaksa yamalarımı kullanabilirsiniz 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