Ini BUG!
Ini adalah bug yang muncul di versi terbaru dari Ubuntu Server LTS (Ubuntu Server 14.04 LTS), ketika Anda membuat partisi boot (atau partisi root, ketika partisi boot tidak ada) di dalam LVM atau partisi RAID .
Anda bisa mendapatkan info lebih lanjut tentang bug ini di Ubuntu Launchpad: Bug # 1274320 "Kesalahan: penulisan diskfilter tidak didukung" .
Pembaruan: Bug ini sudah diperbaiki di Ubuntu Server 14.04 dan beberapa versi Ubuntu yang lebih baru. Mungkin, Anda hanya perlu berlari apt-get upgrade.
Mengapa bug ini terjadi?
Ketika sistem boot, GRUB membaca ( load_env) data di /boot/grub/grubenv. File ini disebut Blok Lingkungan GRUB .
Dari Manual GRUB:
Seringkali berguna untuk mengingat sejumlah kecil informasi dari satu boot ke boot berikutnya.
[...]
Pada saat boot, perintah load_env (lihat load_env) memuat variabel lingkungan darinya, dan perintah save_env (lihat save_env) menyimpan variabel lingkungan ke dalamnya.
[...]
grub-mkconfig menggunakan fasilitas ini untuk mengimplementasikan GRUB_SAVEDEFAULT
Perilaku ini dapat ditemukan di /etc/grub.d/00_header( update-grubmenggunakan file ini untuk menghasilkan /boot/grub/grub.cfgfile):
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
Masalahnya adalah save_envpernyataan itu hanya berfungsi pada instalasi sederhana (Anda tidak bisa menjalankan save_envdisk RAID atau LVM). Dari manual GRUB:
Untuk alasan keamanan, penyimpanan ini hanya tersedia ketika diinstal pada disk biasa (tanpa LVM atau RAID), menggunakan sistem file non-checksumming (tanpa ZFS), dan menggunakan fungsi BIOS atau EFI (tanpa ATA, USB atau IEEE1275).
Fitur GRUB recordfail menggunakan save_envpernyataan untuk memperbarui status recordfail (lihat Bantuan Ubuntu - Grub 2 , bagian "Boot Terakhir Gagal atau Boot ke Mode Pemulihan"). Namun, dalam Ubuntu 14.04 (dan dalam versi Debian terbaru), save_envpernyataan (di dalam fitur recordfail) digunakan bahkan jika GRUB diinstal dalam LVM atau RAID.
Mari kita lihat garis dari 104 hingga 124 di /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 melewatkan fitur recordfail dengan benar ketika menggunakan sistem file yang tidak didukung (btrfs, zfs, dll), tetapi tidak melewatkan LVM dan RAID setiap saat .
Bagaimana GRUB melindungi dirinya dari penulisan di dalam RAID dan LVM?
Untuk membaca / menulis dengan benar di sistem file, GRUB memuat modul yang sesuai.
GRUB menggunakan modul diskfilter ( insmod diskfilter) di partisi RAID, dan modul lvm di partisi LVM.
Mari kita lihat implementasi baca / tulis dari modul diskfilter :
apt-get source grub2
vim grub2-2.02~beta2/grub-core/disk/diskfilter.c
Saya menempelkan kode di sini (baris dari 808 ke 823). Peringatan yang ditunjukkan dalam pertanyaan ini muncul di baris 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");
}
The grub_diskfilter_readfungsi diimplementasikan (dan GRUB dapat membaca filesystem RAID). Namun, grub_diskfilter_writefungsi ini menimbulkan GRUB_ERR_NOT_IMPLEMENTED_YETkesalahan.
Mengapa menggunakan quick_boot=0memecahkan masalah? Dan mengapa itu solusi yang salah?
Jika Anda melihat sekali lagi dalam /etc/grub.d/00_headerkode, Anda akan melihat bahwa fitur recordfail hanya digunakan saat quick_boot=1. Jadi, mengubah quick_bootdari 1 ke 0 menonaktifkan fitur recordfail, dan menonaktifkan menulis di partisi RAID / LVM.
Namun, itu juga akan menonaktifkan banyak fitur lainnya (jalankan grep \$quick_boot /etc/grub.d/*dan Anda akan melihat). Terlebih lagi, jika suatu hari Anda mengubah /boot/grubdirektori Anda ke luar RAID / LVM, fitur recordfail masih akan dinonaktifkan.
Singkatnya, solusi ini tidak perlu menonaktifkan fitur, dan itu tidak umum.
Apa solusi yang benar?
Solusi yang benar harus mempertimbangkan menonaktifkan save_envpernyataan ketika GRUB berada di dalam partisi LVM atau RAID.
Satu tambalan diusulkan dalam sistem Debian Bug Tracker untuk mengimplementasikan solusi ini. Itu dapat ditemukan di: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754921
Gagasan di balik tambalan ini adalah:
- Jalankan
grub-probe --target=abstraction "${grubdir}"perintah untuk mendapatkan modul abstraksi seperti apa yang digunakan GRUB untuk membaca / menulis file di /boot/grubdirektori;
- Jika GRUB menggunakan modul
diskfilteratau lvm, lewati save_envpernyataan recordfail dan tulis komentar yang sesuai dalam /boot/grub/grub.cfgfile;
- Sebagai contoh,
# GRUB lacks write support for /dev/md0, so recordfail support is disabled.
Bagaimana cara menerapkan solusi yang benar?
Jika Anda tidak ingin menunggu tambalan ini diterapkan oleh orang-orang Ubuntu / Debian dalam kode resmi, Anda dapat menggunakan tambalan saya 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