LinuxMint 20 xfce не показывает меню grub после upgrade
Как правильно задавать вопросы Правильно сформулированный вопрос и его грамотное оформление способствует высокой вероятности получения достаточно содержательного и по существу ответа. Общая рекомендация по составлению тем: 1. Для начала воспользуйтесь поиском форума. 2. Укажите версию ОС вместе с разрядностью. Пример: LM 19.3 x64, LM Sarah x32 3. DE. Если вопрос касается двух, то через запятую. (xfce, KDE, cinnamon, mate) 4. Какое железо. (достаточно вывод
inxi -Fxz
в спойлере (как пользоваться спойлером смотрим здесь)) или же дать ссылку на hw-probe 5. Суть. Желательно с выводом консоли, логами. 6. Скрин. Просьба указывать 2, 3 и 4 независимо от того, имеет ли это отношение к вопросу или нет. Так же не забываем об общих правилах Как пример вот
LinuxMint 20 xfce не показывает меню grub после upgrade
Привет! Изначально: SSD1 Windows10, SSD2 LinuxMint 19.3 xfce всё работает, меню есть. После upgrade to LinuxMint 20 всё работает, меню НЕТ.
Может кто подскажет как исправить.
Может кто подскажет как исправить.
-
- Сообщения: 5934
- Зарегистрирован: 16 дек 2017, 21:59
- Решено: 37
- Откуда: Феодосия
- Благодарил (а): 32 раза
- Поблагодарили: 750 раз
- Контактная информация:
LinuxMint 20 xfce не показывает меню grub после upgrade
Что то как то знакомо. Покажи
sudo fdisk -l
, и что стоит в биосе первым в загрузке.LinuxMint 20 xfce не показывает меню grub после upgrade
sudo fdisk -l
В bios:
1. Ubuntu
2. Windows
3. SSD1
4. SSD2 и т.д.
В таком виде работало при 19.3
maxim@maxim-ThinkPad-E555:~$ sudo fdisk -l
[sudo] пароль для maxim:
Диск /dev/loop0: 96,52 MiB, 101191680 байт, 197640 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop1: 259,38 MiB, 271970304 байт, 531192 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop2: 96,101 MiB, 101695488 байт, 198624 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop3: 54,97 MiB, 57618432 байт, 112536 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop4: 160,16 MiB, 167931904 байт, 327992 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop5: 54,98 MiB, 57626624 байт, 112552 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop6: 43,33 MiB, 45424640 байт, 88720 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop7: 139,94 MiB, 146714624 байт, 286552 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/sdb: 447,13 GiB, 480103981056 байт, 937703088 секторов
Disk model: KINGSTON SA400S3
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Тип метки диска: gpt
Идентификатор диска: 940553A3-AE49-4499-AAF4-DCEABE7FA1A4
Устр-во начало Конец Секторы Размер Тип
/dev/sdb1 2048 411647 409600 200M EFI
/dev/sdb2 411648 118501375 118089728 56,3G Файловая система Linux
/dev/sdb3 118501376 937701375 819200000 390,6G Файловая система Linux
Диск /dev/sda: 447,13 GiB, 480103981056 байт, 937703088 секторов
Disk model: KINGSTON SA400S3
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Тип метки диска: gpt
Идентификатор диска: 9BF7A172-BF4E-40DE-A13F-1B2B90E7C77B
Устр-во начало Конец Секторы Размер Тип
/dev/sda1 2048 2050047 2048000 1000M Среда для восстановления Microsoft
/dev/sda2 2050048 2582527 532480 260M EFI
/dev/sda3 2582528 2844671 262144 128M Зарезервированный раздел Microsoft
/dev/sda4 2844672 937703054 934858383 445,8G Microsoft basic data
Диск /dev/loop8: 43,16 MiB, 45248512 байт, 88376 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop9: 161,42 MiB, 169254912 байт, 330576 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop10: 29,84 MiB, 31272960 байт, 61080 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop11: 62,9 MiB, 65105920 байт, 127160 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop12: 29,9 MiB, 31334400 байт, 61200 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop13: 140,7 MiB, 146874368 байт, 286864 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop14: 42,86 MiB, 44916736 байт, 87728 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop15: 43,29 MiB, 45383680 байт, 88640 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop16: 54,84 MiB, 57479168 байт, 112264 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
maxim@maxim-ThinkPad-E555:~$
[sudo] пароль для maxim:
Диск /dev/loop0: 96,52 MiB, 101191680 байт, 197640 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop1: 259,38 MiB, 271970304 байт, 531192 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop2: 96,101 MiB, 101695488 байт, 198624 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop3: 54,97 MiB, 57618432 байт, 112536 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop4: 160,16 MiB, 167931904 байт, 327992 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop5: 54,98 MiB, 57626624 байт, 112552 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop6: 43,33 MiB, 45424640 байт, 88720 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop7: 139,94 MiB, 146714624 байт, 286552 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/sdb: 447,13 GiB, 480103981056 байт, 937703088 секторов
Disk model: KINGSTON SA400S3
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Тип метки диска: gpt
Идентификатор диска: 940553A3-AE49-4499-AAF4-DCEABE7FA1A4
Устр-во начало Конец Секторы Размер Тип
/dev/sdb1 2048 411647 409600 200M EFI
/dev/sdb2 411648 118501375 118089728 56,3G Файловая система Linux
/dev/sdb3 118501376 937701375 819200000 390,6G Файловая система Linux
Диск /dev/sda: 447,13 GiB, 480103981056 байт, 937703088 секторов
Disk model: KINGSTON SA400S3
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Тип метки диска: gpt
Идентификатор диска: 9BF7A172-BF4E-40DE-A13F-1B2B90E7C77B
Устр-во начало Конец Секторы Размер Тип
/dev/sda1 2048 2050047 2048000 1000M Среда для восстановления Microsoft
/dev/sda2 2050048 2582527 532480 260M EFI
/dev/sda3 2582528 2844671 262144 128M Зарезервированный раздел Microsoft
/dev/sda4 2844672 937703054 934858383 445,8G Microsoft basic data
Диск /dev/loop8: 43,16 MiB, 45248512 байт, 88376 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop9: 161,42 MiB, 169254912 байт, 330576 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop10: 29,84 MiB, 31272960 байт, 61080 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop11: 62,9 MiB, 65105920 байт, 127160 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop12: 29,9 MiB, 31334400 байт, 61200 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop13: 140,7 MiB, 146874368 байт, 286864 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop14: 42,86 MiB, 44916736 байт, 87728 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop15: 43,29 MiB, 45383680 байт, 88640 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
Диск /dev/loop16: 54,84 MiB, 57479168 байт, 112264 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
Размер I/O (минимальный/оптимальный): 512 байт / 512 байт
maxim@maxim-ThinkPad-E555:~$
1. Ubuntu
2. Windows
3. SSD1
4. SSD2 и т.д.
В таком виде работало при 19.3
-
- Сообщения: 5934
- Зарегистрирован: 16 дек 2017, 21:59
- Решено: 37
- Откуда: Феодосия
- Благодарил (а): 32 раза
- Поблагодарили: 750 раз
- Контактная информация:
LinuxMint 20 xfce не показывает меню grub после upgrade
Maxim, ты когда ставил системы , на каждом диске делал эфи раздел ? Что то бардак , в биосе 1 убунту , а диск sdb.
Покажи ещё
Покажи ещё
lsblk
и inxi -Fxz
LinuxMint 20 xfce не показывает меню grub после upgrade
EFI раздел на каждом диске. Загрузчик LinuxMint прописывается в bios как Ubuntu.
lsblk
inxi -Fxz
lsblk
maxim@maxim-ThinkPad-E555:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 96,5M 1 loop /snap/core/9436
loop1 7:1 0 259,4M 1 loop /snap/acestreamplayer/10
loop2 7:2 0 97M 1 loop /snap/core/9665
loop3 7:3 0 55M 1 loop /snap/core18/1754
loop4 7:4 0 160,2M 1 loop /snap/gnome-3-28-1804/116
loop5 7:5 0 55M 1 loop /snap/core18/1880
loop6 7:6 0 43,3M 1 loop /snap/riseup-vpn/161
loop7 7:7 0 139,9M 1 loop /snap/icq-im/51
loop8 7:8 0 43,2M 1 loop /snap/snap-store/415
loop9 7:9 0 161,4M 1 loop /snap/gnome-3-28-1804/128
loop10 7:10 0 29,8M 1 loop /snap/snapd/8140
loop11 7:11 0 62,1M 1 loop /snap/gtk-common-themes/1506
loop12 7:12 0 29,9M 1 loop /snap/snapd/8542
loop13 7:13 0 140,1M 1 loop /snap/icq-im/52
loop14 7:14 0 42,9M 1 loop /snap/snap-store/209
loop15 7:15 0 43,3M 1 loop /snap/riseup-vpn/159
loop16 7:16 0 54,8M 1 loop /snap/gtk-common-themes/1502
sda 8:0 0 447,1G 0 disk
├─sda1 8:1 0 1000M 0 part
├─sda2 8:2 0 260M 0 part /media/root/SYSTEM_DRV
├─sda3 8:3 0 128M 0 part
└─sda4 8:4 0 445,8G 0 part
sdb 8:16 0 447,1G 0 disk
├─sdb1 8:17 0 200M 0 part /boot/efi
├─sdb2 8:18 0 56,3G 0 part /
└─sdb3 8:19 0 390,6G 0 part /home
maxim@maxim-ThinkPad-E555:~$
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 96,5M 1 loop /snap/core/9436
loop1 7:1 0 259,4M 1 loop /snap/acestreamplayer/10
loop2 7:2 0 97M 1 loop /snap/core/9665
loop3 7:3 0 55M 1 loop /snap/core18/1754
loop4 7:4 0 160,2M 1 loop /snap/gnome-3-28-1804/116
loop5 7:5 0 55M 1 loop /snap/core18/1880
loop6 7:6 0 43,3M 1 loop /snap/riseup-vpn/161
loop7 7:7 0 139,9M 1 loop /snap/icq-im/51
loop8 7:8 0 43,2M 1 loop /snap/snap-store/415
loop9 7:9 0 161,4M 1 loop /snap/gnome-3-28-1804/128
loop10 7:10 0 29,8M 1 loop /snap/snapd/8140
loop11 7:11 0 62,1M 1 loop /snap/gtk-common-themes/1506
loop12 7:12 0 29,9M 1 loop /snap/snapd/8542
loop13 7:13 0 140,1M 1 loop /snap/icq-im/52
loop14 7:14 0 42,9M 1 loop /snap/snap-store/209
loop15 7:15 0 43,3M 1 loop /snap/riseup-vpn/159
loop16 7:16 0 54,8M 1 loop /snap/gtk-common-themes/1502
sda 8:0 0 447,1G 0 disk
├─sda1 8:1 0 1000M 0 part
├─sda2 8:2 0 260M 0 part /media/root/SYSTEM_DRV
├─sda3 8:3 0 128M 0 part
└─sda4 8:4 0 445,8G 0 part
sdb 8:16 0 447,1G 0 disk
├─sdb1 8:17 0 200M 0 part /boot/efi
├─sdb2 8:18 0 56,3G 0 part /
└─sdb3 8:19 0 390,6G 0 part /home
maxim@maxim-ThinkPad-E555:~$
maxim@maxim-ThinkPad-E555:~$ inxi -Fxz
System:
Kernel: 5.4.0-42-generic x86_64 bits: 64 compiler: gcc v: 9.3.0
Desktop: Xfce 4.14.2 Distro: Linux Mint 20 Ulyana base: Ubuntu 20.04 focal
Machine:
Type: Laptop System: LENOVO product: 20DH001BRT v: ThinkPad E555
serial: <filter>
Mobo: LENOVO model: 20DH001BRT v: SDK0E50515 STD serial: <filter>
UEFI: LENOVO v: HTET35WW (1.07 ) date: 08/13/2014
Battery:
ID-1: BAT0 charge: 37.7 Wh condition: 37.7/47.5 Wh (79%)
model: SANYO LNV-45N1 status: Not charging
CPU:
Topology: Quad Core model: AMD A10-7300 Radeon R6 10 Compute Cores 4C+6G
bits: 64 type: MCP arch: Steamroller rev: 1 L2 cache: 2048 KiB
flags: avx lm nx pae sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3 svm
bogomips: 15171
Speed: 1618 MHz min/max: 1100/1900 MHz Core speeds (MHz): 1: 1896 2: 1896
3: 1193 4: 1190
Graphics:
Device-1: AMD Kaveri [Radeon R6 Graphics] vendor: Lenovo driver: radeon
v: kernel bus ID: 00:01.0
Device-2: AMD Jet XT [Radeon R5 M240] vendor: Lenovo driver: radeon
v: kernel bus ID: 01:00.0
Display: x11 server: X.Org 1.20.8 driver: ati,radeon
unloaded: fbdev,modesetting,vesa resolution: 1366x768~60Hz
OpenGL: renderer: AMD KAVERI (DRM 2.50.0 5.4.0-42-generic LLVM 10.0.0)
v: 4.5 Mesa 20.0.8 direct render: Yes
Audio:
Device-1: AMD Kaveri HDMI/DP Audio vendor: Lenovo driver: snd_hda_intel
v: kernel bus ID: 00:01.1
Device-2: AMD FCH Azalia vendor: Lenovo driver: snd_hda_intel v: kernel
bus ID: 00:14.2
Sound Server: ALSA v: k5.4.0-42-generic
Network:
Device-1: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet
vendor: Lenovo driver: r8169 v: kernel port: 2000 bus ID: 02:00.0
IF: enp2s0 state: up speed: 100 Mbps duplex: full mac: <filter>
Device-2: Realtek RTL8723BE PCIe Wireless Network Adapter
vendor: Lenovo Z50-75 driver: rtl8723be v: kernel port: 1000
bus ID: 04:00.0
IF: wlp4s0 state: down mac: <filter>
IF-ID-1: vmnet1 state: unknown speed: N/A duplex: N/A mac: <filter>
IF-ID-2: vmnet8 state: unknown speed: N/A duplex: N/A mac: <filter>
Drives:
Local Storage: total: 894.26 GiB used: 246.26 GiB (27.5%)
ID-1: /dev/sda vendor: Kingston model: SA400S37480G size: 447.13 GiB
ID-2: /dev/sdb vendor: Kingston model: SA400S37480G size: 447.13 GiB
Partition:
ID-1: / size: 55.18 GiB used: 37.58 GiB (68.1%) fs: ext4 dev: /dev/sdb2
ID-2: /home size: 383.50 GiB used: 208.67 GiB (54.4%) fs: ext4
dev: /dev/sdb3
Sensors:
System Temperatures: cpu: 65.1 C mobo: N/A
Fan Speeds (RPM): cpu: 0
GPU: device: radeon temp: 65 C device: radeon temp: 56 C
Info:
Processes: 274 Uptime: 2h 16m Memory: 6.74 GiB used: 2.68 GiB (39.7%)
Init: systemd runlevel: 5 Compilers: gcc: 9.3.0 Shell: bash v: 5.0.17
inxi: 3.0.38
maxim@maxim-ThinkPad-E555:~$
System:
Kernel: 5.4.0-42-generic x86_64 bits: 64 compiler: gcc v: 9.3.0
Desktop: Xfce 4.14.2 Distro: Linux Mint 20 Ulyana base: Ubuntu 20.04 focal
Machine:
Type: Laptop System: LENOVO product: 20DH001BRT v: ThinkPad E555
serial: <filter>
Mobo: LENOVO model: 20DH001BRT v: SDK0E50515 STD serial: <filter>
UEFI: LENOVO v: HTET35WW (1.07 ) date: 08/13/2014
Battery:
ID-1: BAT0 charge: 37.7 Wh condition: 37.7/47.5 Wh (79%)
model: SANYO LNV-45N1 status: Not charging
CPU:
Topology: Quad Core model: AMD A10-7300 Radeon R6 10 Compute Cores 4C+6G
bits: 64 type: MCP arch: Steamroller rev: 1 L2 cache: 2048 KiB
flags: avx lm nx pae sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3 svm
bogomips: 15171
Speed: 1618 MHz min/max: 1100/1900 MHz Core speeds (MHz): 1: 1896 2: 1896
3: 1193 4: 1190
Graphics:
Device-1: AMD Kaveri [Radeon R6 Graphics] vendor: Lenovo driver: radeon
v: kernel bus ID: 00:01.0
Device-2: AMD Jet XT [Radeon R5 M240] vendor: Lenovo driver: radeon
v: kernel bus ID: 01:00.0
Display: x11 server: X.Org 1.20.8 driver: ati,radeon
unloaded: fbdev,modesetting,vesa resolution: 1366x768~60Hz
OpenGL: renderer: AMD KAVERI (DRM 2.50.0 5.4.0-42-generic LLVM 10.0.0)
v: 4.5 Mesa 20.0.8 direct render: Yes
Audio:
Device-1: AMD Kaveri HDMI/DP Audio vendor: Lenovo driver: snd_hda_intel
v: kernel bus ID: 00:01.1
Device-2: AMD FCH Azalia vendor: Lenovo driver: snd_hda_intel v: kernel
bus ID: 00:14.2
Sound Server: ALSA v: k5.4.0-42-generic
Network:
Device-1: Realtek RTL8111/8168/8411 PCI Express Gigabit Ethernet
vendor: Lenovo driver: r8169 v: kernel port: 2000 bus ID: 02:00.0
IF: enp2s0 state: up speed: 100 Mbps duplex: full mac: <filter>
Device-2: Realtek RTL8723BE PCIe Wireless Network Adapter
vendor: Lenovo Z50-75 driver: rtl8723be v: kernel port: 1000
bus ID: 04:00.0
IF: wlp4s0 state: down mac: <filter>
IF-ID-1: vmnet1 state: unknown speed: N/A duplex: N/A mac: <filter>
IF-ID-2: vmnet8 state: unknown speed: N/A duplex: N/A mac: <filter>
Drives:
Local Storage: total: 894.26 GiB used: 246.26 GiB (27.5%)
ID-1: /dev/sda vendor: Kingston model: SA400S37480G size: 447.13 GiB
ID-2: /dev/sdb vendor: Kingston model: SA400S37480G size: 447.13 GiB
Partition:
ID-1: / size: 55.18 GiB used: 37.58 GiB (68.1%) fs: ext4 dev: /dev/sdb2
ID-2: /home size: 383.50 GiB used: 208.67 GiB (54.4%) fs: ext4
dev: /dev/sdb3
Sensors:
System Temperatures: cpu: 65.1 C mobo: N/A
Fan Speeds (RPM): cpu: 0
GPU: device: radeon temp: 65 C device: radeon temp: 56 C
Info:
Processes: 274 Uptime: 2h 16m Memory: 6.74 GiB used: 2.68 GiB (39.7%)
Init: systemd runlevel: 5 Compilers: gcc: 9.3.0 Shell: bash v: 5.0.17
inxi: 3.0.38
maxim@maxim-ThinkPad-E555:~$
-
- Сообщения: 5934
- Зарегистрирован: 16 дек 2017, 21:59
- Решено: 37
- Откуда: Феодосия
- Благодарил (а): 32 раза
- Поблагодарили: 750 раз
- Контактная информация:
LinuxMint 20 xfce не показывает меню grub после upgrade
Я вот это не догоняю. Расскажи про диски поподробней , сам ставил или были , где стоят , как системы ставил, и случаем они не в рейде?
LinuxMint 20 xfce не показывает меню grub после upgrade
Был HHD с Windows 10 и LinuxMint 19.3. Купил SSD1 и поставил его вместо DVD-ROM, затем создал разделы и перенес LM 19.3 на SSD1. ВСЁ работало. Дальше - купил SSD2 и поставил его вместо SSD1, чтобы перенести Windows 10 (перенес). Потом SSD2 вместо HHD, а SSD1 обратно туда где был DVD-ROM. Включаю ВСЁ работает. Пользовался около месяца пока не сделал upgrade.
Как-то так. Сейчас тоже всё работает , но без меню grub при загрузке.
Как-то так. Сейчас тоже всё работает , но без меню grub при загрузке.
-
- Сообщения: 5934
- Зарегистрирован: 16 дек 2017, 21:59
- Решено: 37
- Откуда: Феодосия
- Благодарил (а): 32 раза
- Поблагодарили: 750 раз
- Контактная информация:
LinuxMint 20 xfce не показывает меню grub после upgrade
запутанная история. Если я понял , винда сейчас на месте харда , а линукс на месте сидюка ? Винду в принципе загрузить можешь? Я бы посоветовал линь поставить на место харда , загрузиля с него и сделать update-grub
LinuxMint 20 xfce не показывает меню grub после upgrade
Правильно понял. Загрузить Windows могу, LM грузится при старте. НЕТ меню grub.
LinuxMint 20 xfce не показывает меню grub после upgrade
Записи в биосе не при делах, update-grub делал. Думаю подождать, может само рассосётся.
-
- Сообщения: 4506
- Зарегистрирован: 21 июн 2017, 18:09
- Решено: 99
- Благодарил (а): 51 раз
- Поблагодарили: 1993 раза
- Контактная информация:
LinuxMint 20 xfce не показывает меню grub после upgrade
1. EFI разделов может быть несколько. Это нормально. Иногда даже полезно (RAID1, например).
2. Перестановка дисков в слотах, на загрузку linux через grub-EFI не влияет никак. За исключением случая, когда один слот/кабель дохлый. Но тогда и диск вообще не увидится.
3. Для диагностики данной ситуации нужно видеть конфиги GRUB, рабочий и конфигурации для установки из etc. Это: /boot/grub/grub.cfg (рабочий) и содержимое файлов в каталоге /etc/grub.d/*.conf (их там до десятка может быть).
2. Перестановка дисков в слотах, на загрузку linux через grub-EFI не влияет никак. За исключением случая, когда один слот/кабель дохлый. Но тогда и диск вообще не увидится.
3. Для диагностики данной ситуации нужно видеть конфиги GRUB, рабочий и конфигурации для установки из etc. Это: /boot/grub/grub.cfg (рабочий) и содержимое файлов в каталоге /etc/grub.d/*.conf (их там до десятка может быть).
LinuxMint 20 xfce не показывает меню grub после upgrade
grub.cfg
Из grub.d
00_header
05_debian_theme
10_linux
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
if [ "${initrdfail}" = 2 ]; then
set initrdfail=
elif [ "${initrdfail}" = 1 ]; then
set next_entry="${prev_entry}"
set prev_entry=
save_env prev_entry
if [ "${next_entry}" ]; then
set initrdfail=2
fi
fi
if [ "${next_entry}" ] ; then
set default="${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="0"
fi
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "${prev_saved_entry}" ]; then
set saved_entry="${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "${boot_once}" ]; then
saved_entry="${chosen}"
save_env saved_entry
fi
}
function initrdfail {
if [ -n "${have_grubenv}" ]; then if [ -n "${partuuid}" ]; then
if [ -z "${initrdfail}" ]; then
set initrdfail=1
if [ -n "${boot_once}" ]; then
set prev_entry="${default}"
save_env prev_entry
fi
fi
save_env initrdfail
fi; fi
}
function recordfail {
set recordfail=1
if [ -n "${have_grubenv}" ]; then if [ -z "${boot_once}" ]; then save_env recordfail; fi; fi
}
function load_video {
if [ x$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
}
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
if loadfont /boot/grub/fonts/UbuntuMono16.pf2 ; then
set gfxmode=auto
load_video
insmod gfxterm
set locale_dir=$prefix/locale
set lang=ru_RU
insmod gettext
fi
terminal_output gfxterm
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
insmod gfxmenu
insmod png
set theme=($root)/boot/grub/themes/linuxmint/theme.txt
export theme
if [ "${recordfail}" = 1 ] ; then
set timeout=5
else
if [ x$feature_timeout_style = xy ] ; then
set timeout_style=menu
set timeout=5
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
set timeout=5
fi
fi
### END /etc/grub.d/00_header ###
### BEGIN /etc/grub.d/05_debian_theme ###
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
### END /etc/grub.d/05_debian_theme ###
### BEGIN /etc/grub.d/10_linux ###
function gfxmode {
set gfxpayload="${1}"
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=7
else
set vt_handoff=
fi
}
if [ "${recordfail}" != 1 ]; then
if [ -e ${prefix}/gfxblacklist.txt ]; then
if hwmatch ${prefix}/gfxblacklist.txt 3; then
if [ ${match} = 0 ]; then
set linux_gfx_mode=keep
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=keep
fi
else
set linux_gfx_mode=text
fi
export linux_gfx_mode
menuentry 'Linux Mint 20 Xfce' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-e601cc10-e115-40f1-a14e-868d9667b993' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
linux /boot/vmlinuz-5.4.0-42-generic root=UUID=e601cc10-e115-40f1-a14e-868d9667b993 ro quiet splash
initrd /boot/initrd.img-5.4.0-42-generic
}
submenu 'Advanced options for Linux Mint 20 Xfce' $menuentry_id_option 'gnulinux-advanced-e601cc10-e115-40f1-a14e-868d9667b993' {
menuentry 'Linux Mint 20 Xfce, with Linux 5.4.0-42-generic' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-42-generic-advanced-e601cc10-e115-40f1-a14e-868d9667b993' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
echo 'Loading Linux 5.4.0-42-generic ...'
linux /boot/vmlinuz-5.4.0-42-generic root=UUID=e601cc10-e115-40f1-a14e-868d9667b993 ro quiet splash
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-5.4.0-42-generic
}
menuentry 'Linux Mint 20 Xfce, with Linux 5.4.0-42-generic (recovery mode)' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-42-generic-recovery-e601cc10-e115-40f1-a14e-868d9667b993' {
recordfail
load_video
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
echo 'Loading Linux 5.4.0-42-generic ...'
linux /boot/vmlinuz-5.4.0-42-generic root=UUID=e601cc10-e115-40f1-a14e-868d9667b993 ro recovery nomodeset
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-5.4.0-42-generic
}
menuentry 'Linux Mint 20 Xfce, with Linux 5.4.0-40-generic' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-40-generic-advanced-e601cc10-e115-40f1-a14e-868d9667b993' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
echo 'Loading Linux 5.4.0-40-generic ...'
linux /boot/vmlinuz-5.4.0-40-generic root=UUID=e601cc10-e115-40f1-a14e-868d9667b993 ro quiet splash
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-5.4.0-40-generic
}
menuentry 'Linux Mint 20 Xfce, with Linux 5.4.0-40-generic (recovery mode)' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-40-generic-recovery-e601cc10-e115-40f1-a14e-868d9667b993' {
recordfail
load_video
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
echo 'Loading Linux 5.4.0-40-generic ...'
linux /boot/vmlinuz-5.4.0-40-generic root=UUID=e601cc10-e115-40f1-a14e-868d9667b993 ro recovery nomodeset
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-5.4.0-40-generic
}
}
### END /etc/grub.d/10_linux ###
### BEGIN /etc/grub.d/10_linux_zfs ###
### END /etc/grub.d/10_linux_zfs ###
### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###
### BEGIN /etc/grub.d/25_custom ###
menuentry "EFI/BOOT/bkpbootx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/bkpbootx64.efi
}
menuentry "EFI/BOOT/fbx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/fbx64.efi
}
menuentry "EFI/BOOT/mmx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/mmx64.efi
}
menuentry "EFI/ubuntu/mmx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/ubuntu/mmx64.efi
}
menuentry "Windows UEFI bootmgfw.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi
}
menuentry "Windows Boot UEFI loader" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/bkpbootx64.efi
}
menuentry "Windows Boot UEFI fbx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/fbx64.efi
}
menuentry "Windows Boot UEFI mmx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/mmx64.efi
}
menuentry "EFI/ubuntu/fbx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/ubuntu/fbx64.efi
}
menuentry "EFI/ubuntu/mmx64.efi sdb2" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/ubuntu/mmx64.efi
}
menuentry "EFI/Lenovo/Boot/bootmgfw.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Lenovo/Boot/bootmgfw.efi
}
### END /etc/grub.d/25_custom ###
### BEGIN /etc/grub.d/30_os-prober ###
menuentry 'Windows Boot Manager (on /dev/sdb2)' --class windows --class os $menuentry_id_option 'osprober-efi-5217-53CE' {
insmod part_gpt
insmod fat
set root='hd1,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd1,gpt2 --hint-efi=hd1,gpt2 --hint-baremetal=ahci1,gpt2 5217-53CE
else
search --no-floppy --fs-uuid --set=root 5217-53CE
fi
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
set timeout_style=menu
if [ "${timeout}" = 0 ]; then
set timeout=5
fi
### END /etc/grub.d/30_os-prober ###
### BEGIN /etc/grub.d/30_uefi-firmware ###
menuentry 'UEFI Firmware Settings' $menuentry_id_option 'uefi-firmware' {
fwsetup
}
### END /etc/grub.d/30_uefi-firmware ###
### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry "Android CM 14" {
set root='(hd0,2)'
linux /cm-x86-14.1-r3/kernel quiet root=/dev/ram0 androidboot.selinux=permissive buildvariant=userdebug SRC=/cm-x86-14.1-r3
initrd /cm-x86-14.1-r3/initrd.img
}
### END /etc/grub.d/40_custom ###
### BEGIN /etc/grub.d/41_custom ###
if [ -f ${config_directory}/custom.cfg ]; then
source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then
source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
if [ "${initrdfail}" = 2 ]; then
set initrdfail=
elif [ "${initrdfail}" = 1 ]; then
set next_entry="${prev_entry}"
set prev_entry=
save_env prev_entry
if [ "${next_entry}" ]; then
set initrdfail=2
fi
fi
if [ "${next_entry}" ] ; then
set default="${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="0"
fi
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "${prev_saved_entry}" ]; then
set saved_entry="${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "${boot_once}" ]; then
saved_entry="${chosen}"
save_env saved_entry
fi
}
function initrdfail {
if [ -n "${have_grubenv}" ]; then if [ -n "${partuuid}" ]; then
if [ -z "${initrdfail}" ]; then
set initrdfail=1
if [ -n "${boot_once}" ]; then
set prev_entry="${default}"
save_env prev_entry
fi
fi
save_env initrdfail
fi; fi
}
function recordfail {
set recordfail=1
if [ -n "${have_grubenv}" ]; then if [ -z "${boot_once}" ]; then save_env recordfail; fi; fi
}
function load_video {
if [ x$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
}
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
if loadfont /boot/grub/fonts/UbuntuMono16.pf2 ; then
set gfxmode=auto
load_video
insmod gfxterm
set locale_dir=$prefix/locale
set lang=ru_RU
insmod gettext
fi
terminal_output gfxterm
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
insmod gfxmenu
insmod png
set theme=($root)/boot/grub/themes/linuxmint/theme.txt
export theme
if [ "${recordfail}" = 1 ] ; then
set timeout=5
else
if [ x$feature_timeout_style = xy ] ; then
set timeout_style=menu
set timeout=5
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
set timeout=5
fi
fi
### END /etc/grub.d/00_header ###
### BEGIN /etc/grub.d/05_debian_theme ###
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
### END /etc/grub.d/05_debian_theme ###
### BEGIN /etc/grub.d/10_linux ###
function gfxmode {
set gfxpayload="${1}"
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=7
else
set vt_handoff=
fi
}
if [ "${recordfail}" != 1 ]; then
if [ -e ${prefix}/gfxblacklist.txt ]; then
if hwmatch ${prefix}/gfxblacklist.txt 3; then
if [ ${match} = 0 ]; then
set linux_gfx_mode=keep
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=keep
fi
else
set linux_gfx_mode=text
fi
export linux_gfx_mode
menuentry 'Linux Mint 20 Xfce' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-e601cc10-e115-40f1-a14e-868d9667b993' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
linux /boot/vmlinuz-5.4.0-42-generic root=UUID=e601cc10-e115-40f1-a14e-868d9667b993 ro quiet splash
initrd /boot/initrd.img-5.4.0-42-generic
}
submenu 'Advanced options for Linux Mint 20 Xfce' $menuentry_id_option 'gnulinux-advanced-e601cc10-e115-40f1-a14e-868d9667b993' {
menuentry 'Linux Mint 20 Xfce, with Linux 5.4.0-42-generic' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-42-generic-advanced-e601cc10-e115-40f1-a14e-868d9667b993' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
echo 'Loading Linux 5.4.0-42-generic ...'
linux /boot/vmlinuz-5.4.0-42-generic root=UUID=e601cc10-e115-40f1-a14e-868d9667b993 ro quiet splash
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-5.4.0-42-generic
}
menuentry 'Linux Mint 20 Xfce, with Linux 5.4.0-42-generic (recovery mode)' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-42-generic-recovery-e601cc10-e115-40f1-a14e-868d9667b993' {
recordfail
load_video
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
echo 'Loading Linux 5.4.0-42-generic ...'
linux /boot/vmlinuz-5.4.0-42-generic root=UUID=e601cc10-e115-40f1-a14e-868d9667b993 ro recovery nomodeset
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-5.4.0-42-generic
}
menuentry 'Linux Mint 20 Xfce, with Linux 5.4.0-40-generic' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-40-generic-advanced-e601cc10-e115-40f1-a14e-868d9667b993' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
echo 'Loading Linux 5.4.0-40-generic ...'
linux /boot/vmlinuz-5.4.0-40-generic root=UUID=e601cc10-e115-40f1-a14e-868d9667b993 ro quiet splash
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-5.4.0-40-generic
}
menuentry 'Linux Mint 20 Xfce, with Linux 5.4.0-40-generic (recovery mode)' --class linuxmint --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-40-generic-recovery-e601cc10-e115-40f1-a14e-868d9667b993' {
recordfail
load_video
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 e601cc10-e115-40f1-a14e-868d9667b993
else
search --no-floppy --fs-uuid --set=root e601cc10-e115-40f1-a14e-868d9667b993
fi
echo 'Loading Linux 5.4.0-40-generic ...'
linux /boot/vmlinuz-5.4.0-40-generic root=UUID=e601cc10-e115-40f1-a14e-868d9667b993 ro recovery nomodeset
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-5.4.0-40-generic
}
}
### END /etc/grub.d/10_linux ###
### BEGIN /etc/grub.d/10_linux_zfs ###
### END /etc/grub.d/10_linux_zfs ###
### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###
### BEGIN /etc/grub.d/25_custom ###
menuentry "EFI/BOOT/bkpbootx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/bkpbootx64.efi
}
menuentry "EFI/BOOT/fbx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/fbx64.efi
}
menuentry "EFI/BOOT/mmx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/mmx64.efi
}
menuentry "EFI/ubuntu/mmx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/ubuntu/mmx64.efi
}
menuentry "Windows UEFI bootmgfw.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi
}
menuentry "Windows Boot UEFI loader" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/bkpbootx64.efi
}
menuentry "Windows Boot UEFI fbx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/fbx64.efi
}
menuentry "Windows Boot UEFI mmx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/mmx64.efi
}
menuentry "EFI/ubuntu/fbx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/ubuntu/fbx64.efi
}
menuentry "EFI/ubuntu/mmx64.efi sdb2" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/ubuntu/mmx64.efi
}
menuentry "EFI/Lenovo/Boot/bootmgfw.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Lenovo/Boot/bootmgfw.efi
}
### END /etc/grub.d/25_custom ###
### BEGIN /etc/grub.d/30_os-prober ###
menuentry 'Windows Boot Manager (on /dev/sdb2)' --class windows --class os $menuentry_id_option 'osprober-efi-5217-53CE' {
insmod part_gpt
insmod fat
set root='hd1,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd1,gpt2 --hint-efi=hd1,gpt2 --hint-baremetal=ahci1,gpt2 5217-53CE
else
search --no-floppy --fs-uuid --set=root 5217-53CE
fi
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
set timeout_style=menu
if [ "${timeout}" = 0 ]; then
set timeout=5
fi
### END /etc/grub.d/30_os-prober ###
### BEGIN /etc/grub.d/30_uefi-firmware ###
menuentry 'UEFI Firmware Settings' $menuentry_id_option 'uefi-firmware' {
fwsetup
}
### END /etc/grub.d/30_uefi-firmware ###
### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry "Android CM 14" {
set root='(hd0,2)'
linux /cm-x86-14.1-r3/kernel quiet root=/dev/ram0 androidboot.selinux=permissive buildvariant=userdebug SRC=/cm-x86-14.1-r3
initrd /cm-x86-14.1-r3/initrd.img
}
### END /etc/grub.d/40_custom ###
### BEGIN /etc/grub.d/41_custom ###
if [ -f ${config_directory}/custom.cfg ]; then
source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then
source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###
00_header
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"
grub_lang=`echo $LANG | cut -d . -f 1`
grubdir="`echo "/boot/grub" | sed 's,//*,/,g'`"
quick_boot="1"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
. "$pkgdatadir/grub-mkconfig_lib"
# Do this as early as possible, since other commands might depend on it.
# (e.g. the `loadfont' command might need lvm or raid modules)
for i in ${GRUB_PRELOAD_MODULES} ; do
echo "insmod $i"
done
if [ "x${GRUB_DEFAULT}" = "x" ] ; then GRUB_DEFAULT=0 ; fi
if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then GRUB_DEFAULT='${saved_entry}' ; fi
if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi
if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=auto ; fi
if [ "x${GRUB_DEFAULT_BUTTON}" = "x" ] ; then GRUB_DEFAULT_BUTTON="$GRUB_DEFAULT" ; fi
if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_entry}' ; fi
if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi
cat << EOF
if [ -s \$prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
EOF
cat <<EOF
if [ "\${initrdfail}" = 2 ]; then
set initrdfail=
elif [ "\${initrdfail}" = 1 ]; then
set next_entry="\${prev_entry}"
set prev_entry=
save_env prev_entry
if [ "\${next_entry}" ]; then
set initrdfail=2
fi
fi
EOF
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
set default="${GRUB_DEFAULT_BUTTON}"
elif [ "\${next_entry}" ] ; then
set default="\${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="${GRUB_DEFAULT}"
fi
EOF
else
cat <<EOF
if [ "\${next_entry}" ] ; then
set default="\${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="${GRUB_DEFAULT}"
fi
EOF
fi
cat <<EOF
if [ x"\${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "\${prev_saved_entry}" ]; then
set saved_entry="\${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "\${boot_once}" ]; then
saved_entry="\${chosen}"
save_env saved_entry
fi
}
EOF
cat <<"EOF"
function initrdfail {
if [ -n "${have_grubenv}" ]; then if [ -n "${partuuid}" ]; then
if [ -z "${initrdfail}" ]; then
set initrdfail=1
if [ -n "${boot_once}" ]; then
set prev_entry="${default}"
save_env prev_entry
fi
fi
save_env initrdfail
fi; fi
}
EOF
if [ "$quick_boot" = 1 ]; then
cat <<EOF
function recordfail {
set recordfail=1
EOF
check_writable () {
abstractions="$(grub-probe --target=abstraction "${grubdir}")"
for abstraction in $abstractions; do
case "$abstraction" in
diskfilter | lvm)
cat <<EOF
# GRUB lacks write support for $abstraction, so recordfail support is disabled.
EOF
return 1
;;
esac
done
FS="$(grub-probe --target=fs "${grubdir}")"
case "$FS" in
btrfs | cpiofs | newc | odc | romfs | squash4 | tarfs | zfs)
cat <<EOF
# GRUB lacks write support for $FS, so recordfail support is disabled.
EOF
return 1
;;
esac
cat <<EOF
if [ -n "\${have_grubenv}" ]; then if [ -z "\${boot_once}" ]; then save_env recordfail; fi; fi
EOF
}
if ! check_writable; then
recordfail_broken=1
fi
cat <<EOF
}
EOF
fi
cat <<EOF
function load_video {
EOF
if [ -n "${GRUB_VIDEO_BACKEND}" ]; then
cat <<EOF
insmod ${GRUB_VIDEO_BACKEND}
EOF
else
# If all_video.mod isn't available load all modules available
# with versions prior to introduction of all_video.mod
cat <<EOF
if [ x\$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
EOF
fi
cat <<EOF
}
EOF
serial=0;
gfxterm=0;
for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do
if [ xserial = "x$x" ]; then
serial=1;
fi
if [ xgfxterm = "x$x" ]; then
gfxterm=1;
fi
done
if [ "x$serial" = x1 ]; then
if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then
grub_warn "$(gettext "Requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used.")"
GRUB_SERIAL_COMMAND=serial
fi
echo "${GRUB_SERIAL_COMMAND}"
fi
if [ "x$gfxterm" = x1 ]; then
if [ -n "$GRUB_FONT" ] ; then
# Make the font accessible
prepare_grub_to_access_device `${grub_probe} --target=device "${GRUB_FONT}"`
cat << EOF
if loadfont `make_system_path_relative_to_its_root "${GRUB_FONT}"` ; then
EOF
else
for dir in "${pkgdatadir}" "`echo '/boot/grub' | sed "s,//*,/,g"`" /usr/share/grub ; do
for basename in unicode unifont ascii; do
path="${dir}/${basename}.pf2"
if is_path_readable_by_grub "${path}" > /dev/null ; then
font_path="${path}"
else
continue
fi
break 2
done
done
if [ -n "${font_path}" ] ; then
cat << EOF
if [ x\$feature_default_font_path = xy ] ; then
font=unicode
else
EOF
# Make the font accessible
prepare_grub_to_access_device `${grub_probe} --target=device "${font_path}"`
cat << EOF
font="`make_system_path_relative_to_its_root "${font_path}"`"
fi
if loadfont \$font ; then
EOF
else
cat << EOF
if loadfont unicode ; then
EOF
fi
fi
cat << EOF
set gfxmode=${GRUB_GFXMODE}
load_video
insmod gfxterm
EOF
# Gettext variables and module
if [ "x${LANG}" != "xC" ] && [ "x${LANG}" != "x" ]; then
cat << EOF
set locale_dir=\$prefix/locale
set lang=${grub_lang}
insmod gettext
EOF
fi
cat <<EOF
fi
EOF
fi
case x${GRUB_TERMINAL_INPUT} in
x)
# Just use the native terminal
;;
x*)
cat << EOF
terminal_input ${GRUB_TERMINAL_INPUT}
EOF
;;
esac
case x${GRUB_TERMINAL_OUTPUT} in
x)
# Just use the native terminal
;;
x*)
cat << EOF
terminal_output ${GRUB_TERMINAL_OUTPUT}
EOF
;;
esac
if [ "x$gfxterm" = x1 ]; then
if [ "x$GRUB_THEME" != x ] && [ -f "$GRUB_THEME" ] \
&& is_path_readable_by_grub "$GRUB_THEME"; then
gettext_printf "Found theme: %s\n" "$GRUB_THEME" >&2
prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_THEME"`
cat << EOF
insmod gfxmenu
EOF
themedir="`dirname "$GRUB_THEME"`"
for x in "$themedir"/*.pf2 "$themedir"/f/*.pf2; do
if [ -f "$x" ]; then
cat << EOF
loadfont (\$root)`make_system_path_relative_to_its_root $x`
EOF
fi
done
if [ x"`echo "$themedir"/*.jpg`" != x"$themedir/*.jpg" ] || [ x"`echo "$themedir"/*.jpeg`" != x"$themedir/*.jpeg" ]; then
cat << EOF
insmod jpeg
EOF
fi
if [ x"`echo "$themedir"/*.png`" != x"$themedir/*.png" ]; then
cat << EOF
insmod png
EOF
fi
if [ x"`echo "$themedir"/*.tga`" != x"$themedir/*.tga" ]; then
cat << EOF
insmod tga
EOF
fi
cat << EOF
set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME`
export theme
EOF
elif [ "x$GRUB_BACKGROUND" != x ] && [ -f "$GRUB_BACKGROUND" ] \
&& is_path_readable_by_grub "$GRUB_BACKGROUND"; then
gettext_printf "Found background: %s\n" "$GRUB_BACKGROUND" >&2
case "$GRUB_BACKGROUND" in
*.png) reader=png ;;
*.tga) reader=tga ;;
*.jpg|*.jpeg) reader=jpeg ;;
*) gettext "Unsupported image format" >&2; echo >&2; exit 1 ;;
esac
prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_BACKGROUND"`
cat << EOF
insmod $reader
background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`
EOF
fi
fi
make_timeout ()
{
cat << EOF
if [ "\${recordfail}" = 1 ] ; then
set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
else
EOF
if [ "x${3}" != "x" ] ; then
timeout="${2}"
style="${3}"
elif [ "x${1}" != "x" ] && \
([ "$quick_boot" = 1 ] || [ "x${1}" != "x0" ]) ; then
# Handle the deprecated GRUB_HIDDEN_TIMEOUT scheme.
timeout="${1}"
if [ "x${2}" != "x0" ] ; then
grub_warn "$(gettext "Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.")"
fi
if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then
style="hidden"
verbose=
else
style="countdown"
verbose=" --verbose"
fi
else
# No hidden timeout, so treat as GRUB_TIMEOUT_STYLE=menu
timeout="${2}"
style="menu"
fi
cat << EOF
if [ x\$feature_timeout_style = xy ] ; then
set timeout_style=${style}
set timeout=${timeout}
EOF
if [ "x${style}" = "xmenu" ] ; then
cat << EOF
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
set timeout=${timeout}
EOF
else
cat << EOF
# Fallback hidden-timeout code in case the timeout_style feature is
# unavailable.
elif sleep${verbose} --interruptible ${timeout} ; then
set timeout=0
EOF
fi
cat << EOF
fi
fi
EOF
if [ "$recordfail_broken" = 1 ]; then
cat << EOF
if [ \$grub_platform = efi ]; then
set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
if [ x\$feature_timeout_style = xy ] ; then
set timeout_style=menu
fi
fi
EOF
fi
}
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
EOF
make_timeout "${GRUB_HIDDEN_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_STYLE_BUTTON}"
echo else
make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}" "${GRUB_TIMEOUT_STYLE}"
echo fi
else
make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}" "${GRUB_TIMEOUT_STYLE}"
fi
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ] && [ "x$GRUB_BUTTON_CMOS_CLEAN" = "xyes" ]; then
cat <<EOF
cmosclean $GRUB_BUTTON_CMOS_ADDRESS
EOF
fi
# Play an initial tune
if [ "x${GRUB_INIT_TUNE}" != "x" ] ; then
echo "play ${GRUB_INIT_TUNE}"
fi
if [ "x${GRUB_BADRAM}" != "x" ] ; then
echo "badram ${GRUB_BADRAM}"
fi
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"
grub_lang=`echo $LANG | cut -d . -f 1`
grubdir="`echo "/boot/grub" | sed 's,//*,/,g'`"
quick_boot="1"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
. "$pkgdatadir/grub-mkconfig_lib"
# Do this as early as possible, since other commands might depend on it.
# (e.g. the `loadfont' command might need lvm or raid modules)
for i in ${GRUB_PRELOAD_MODULES} ; do
echo "insmod $i"
done
if [ "x${GRUB_DEFAULT}" = "x" ] ; then GRUB_DEFAULT=0 ; fi
if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then GRUB_DEFAULT='${saved_entry}' ; fi
if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi
if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=auto ; fi
if [ "x${GRUB_DEFAULT_BUTTON}" = "x" ] ; then GRUB_DEFAULT_BUTTON="$GRUB_DEFAULT" ; fi
if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_entry}' ; fi
if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi
cat << EOF
if [ -s \$prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
EOF
cat <<EOF
if [ "\${initrdfail}" = 2 ]; then
set initrdfail=
elif [ "\${initrdfail}" = 1 ]; then
set next_entry="\${prev_entry}"
set prev_entry=
save_env prev_entry
if [ "\${next_entry}" ]; then
set initrdfail=2
fi
fi
EOF
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
set default="${GRUB_DEFAULT_BUTTON}"
elif [ "\${next_entry}" ] ; then
set default="\${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="${GRUB_DEFAULT}"
fi
EOF
else
cat <<EOF
if [ "\${next_entry}" ] ; then
set default="\${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="${GRUB_DEFAULT}"
fi
EOF
fi
cat <<EOF
if [ x"\${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "\${prev_saved_entry}" ]; then
set saved_entry="\${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "\${boot_once}" ]; then
saved_entry="\${chosen}"
save_env saved_entry
fi
}
EOF
cat <<"EOF"
function initrdfail {
if [ -n "${have_grubenv}" ]; then if [ -n "${partuuid}" ]; then
if [ -z "${initrdfail}" ]; then
set initrdfail=1
if [ -n "${boot_once}" ]; then
set prev_entry="${default}"
save_env prev_entry
fi
fi
save_env initrdfail
fi; fi
}
EOF
if [ "$quick_boot" = 1 ]; then
cat <<EOF
function recordfail {
set recordfail=1
EOF
check_writable () {
abstractions="$(grub-probe --target=abstraction "${grubdir}")"
for abstraction in $abstractions; do
case "$abstraction" in
diskfilter | lvm)
cat <<EOF
# GRUB lacks write support for $abstraction, so recordfail support is disabled.
EOF
return 1
;;
esac
done
FS="$(grub-probe --target=fs "${grubdir}")"
case "$FS" in
btrfs | cpiofs | newc | odc | romfs | squash4 | tarfs | zfs)
cat <<EOF
# GRUB lacks write support for $FS, so recordfail support is disabled.
EOF
return 1
;;
esac
cat <<EOF
if [ -n "\${have_grubenv}" ]; then if [ -z "\${boot_once}" ]; then save_env recordfail; fi; fi
EOF
}
if ! check_writable; then
recordfail_broken=1
fi
cat <<EOF
}
EOF
fi
cat <<EOF
function load_video {
EOF
if [ -n "${GRUB_VIDEO_BACKEND}" ]; then
cat <<EOF
insmod ${GRUB_VIDEO_BACKEND}
EOF
else
# If all_video.mod isn't available load all modules available
# with versions prior to introduction of all_video.mod
cat <<EOF
if [ x\$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
EOF
fi
cat <<EOF
}
EOF
serial=0;
gfxterm=0;
for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do
if [ xserial = "x$x" ]; then
serial=1;
fi
if [ xgfxterm = "x$x" ]; then
gfxterm=1;
fi
done
if [ "x$serial" = x1 ]; then
if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then
grub_warn "$(gettext "Requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used.")"
GRUB_SERIAL_COMMAND=serial
fi
echo "${GRUB_SERIAL_COMMAND}"
fi
if [ "x$gfxterm" = x1 ]; then
if [ -n "$GRUB_FONT" ] ; then
# Make the font accessible
prepare_grub_to_access_device `${grub_probe} --target=device "${GRUB_FONT}"`
cat << EOF
if loadfont `make_system_path_relative_to_its_root "${GRUB_FONT}"` ; then
EOF
else
for dir in "${pkgdatadir}" "`echo '/boot/grub' | sed "s,//*,/,g"`" /usr/share/grub ; do
for basename in unicode unifont ascii; do
path="${dir}/${basename}.pf2"
if is_path_readable_by_grub "${path}" > /dev/null ; then
font_path="${path}"
else
continue
fi
break 2
done
done
if [ -n "${font_path}" ] ; then
cat << EOF
if [ x\$feature_default_font_path = xy ] ; then
font=unicode
else
EOF
# Make the font accessible
prepare_grub_to_access_device `${grub_probe} --target=device "${font_path}"`
cat << EOF
font="`make_system_path_relative_to_its_root "${font_path}"`"
fi
if loadfont \$font ; then
EOF
else
cat << EOF
if loadfont unicode ; then
EOF
fi
fi
cat << EOF
set gfxmode=${GRUB_GFXMODE}
load_video
insmod gfxterm
EOF
# Gettext variables and module
if [ "x${LANG}" != "xC" ] && [ "x${LANG}" != "x" ]; then
cat << EOF
set locale_dir=\$prefix/locale
set lang=${grub_lang}
insmod gettext
EOF
fi
cat <<EOF
fi
EOF
fi
case x${GRUB_TERMINAL_INPUT} in
x)
# Just use the native terminal
;;
x*)
cat << EOF
terminal_input ${GRUB_TERMINAL_INPUT}
EOF
;;
esac
case x${GRUB_TERMINAL_OUTPUT} in
x)
# Just use the native terminal
;;
x*)
cat << EOF
terminal_output ${GRUB_TERMINAL_OUTPUT}
EOF
;;
esac
if [ "x$gfxterm" = x1 ]; then
if [ "x$GRUB_THEME" != x ] && [ -f "$GRUB_THEME" ] \
&& is_path_readable_by_grub "$GRUB_THEME"; then
gettext_printf "Found theme: %s\n" "$GRUB_THEME" >&2
prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_THEME"`
cat << EOF
insmod gfxmenu
EOF
themedir="`dirname "$GRUB_THEME"`"
for x in "$themedir"/*.pf2 "$themedir"/f/*.pf2; do
if [ -f "$x" ]; then
cat << EOF
loadfont (\$root)`make_system_path_relative_to_its_root $x`
EOF
fi
done
if [ x"`echo "$themedir"/*.jpg`" != x"$themedir/*.jpg" ] || [ x"`echo "$themedir"/*.jpeg`" != x"$themedir/*.jpeg" ]; then
cat << EOF
insmod jpeg
EOF
fi
if [ x"`echo "$themedir"/*.png`" != x"$themedir/*.png" ]; then
cat << EOF
insmod png
EOF
fi
if [ x"`echo "$themedir"/*.tga`" != x"$themedir/*.tga" ]; then
cat << EOF
insmod tga
EOF
fi
cat << EOF
set theme=(\$root)`make_system_path_relative_to_its_root $GRUB_THEME`
export theme
EOF
elif [ "x$GRUB_BACKGROUND" != x ] && [ -f "$GRUB_BACKGROUND" ] \
&& is_path_readable_by_grub "$GRUB_BACKGROUND"; then
gettext_printf "Found background: %s\n" "$GRUB_BACKGROUND" >&2
case "$GRUB_BACKGROUND" in
*.png) reader=png ;;
*.tga) reader=tga ;;
*.jpg|*.jpeg) reader=jpeg ;;
*) gettext "Unsupported image format" >&2; echo >&2; exit 1 ;;
esac
prepare_grub_to_access_device `${grub_probe} --target=device "$GRUB_BACKGROUND"`
cat << EOF
insmod $reader
background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`
EOF
fi
fi
make_timeout ()
{
cat << EOF
if [ "\${recordfail}" = 1 ] ; then
set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
else
EOF
if [ "x${3}" != "x" ] ; then
timeout="${2}"
style="${3}"
elif [ "x${1}" != "x" ] && \
([ "$quick_boot" = 1 ] || [ "x${1}" != "x0" ]) ; then
# Handle the deprecated GRUB_HIDDEN_TIMEOUT scheme.
timeout="${1}"
if [ "x${2}" != "x0" ] ; then
grub_warn "$(gettext "Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.")"
fi
if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then
style="hidden"
verbose=
else
style="countdown"
verbose=" --verbose"
fi
else
# No hidden timeout, so treat as GRUB_TIMEOUT_STYLE=menu
timeout="${2}"
style="menu"
fi
cat << EOF
if [ x\$feature_timeout_style = xy ] ; then
set timeout_style=${style}
set timeout=${timeout}
EOF
if [ "x${style}" = "xmenu" ] ; then
cat << EOF
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
set timeout=${timeout}
EOF
else
cat << EOF
# Fallback hidden-timeout code in case the timeout_style feature is
# unavailable.
elif sleep${verbose} --interruptible ${timeout} ; then
set timeout=0
EOF
fi
cat << EOF
fi
fi
EOF
if [ "$recordfail_broken" = 1 ]; then
cat << EOF
if [ \$grub_platform = efi ]; then
set timeout=${GRUB_RECORDFAIL_TIMEOUT:-30}
if [ x\$feature_timeout_style = xy ] ; then
set timeout_style=menu
fi
fi
EOF
fi
}
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
EOF
make_timeout "${GRUB_HIDDEN_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_STYLE_BUTTON}"
echo else
make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}" "${GRUB_TIMEOUT_STYLE}"
echo fi
else
make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}" "${GRUB_TIMEOUT_STYLE}"
fi
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ] && [ "x$GRUB_BUTTON_CMOS_CLEAN" = "xyes" ]; then
cat <<EOF
cmosclean $GRUB_BUTTON_CMOS_ADDRESS
EOF
fi
# Play an initial tune
if [ "x${GRUB_INIT_TUNE}" != "x" ] ; then
echo "play ${GRUB_INIT_TUNE}"
fi
if [ "x${GRUB_BADRAM}" != "x" ] ; then
echo "badram ${GRUB_BADRAM}"
fi
#!/bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2010 Alexander Kurtz <kurtz.alex@googlemail.com>
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Include the GRUB helper library for grub-mkconfig.
. /usr/share/grub/grub-mkconfig_lib
# We want to work in /boot/grub/ only.
test -d /boot/grub; cd /boot/grub
# Set the location of a possibly necessary cache file for the background image.
# NOTE: This MUST BE A DOTFILE to avoid confusing it with user-defined images.
BACKGROUND_CACHE=".background_cache"
set_default_theme(){
case $GRUB_DISTRIBUTOR in
Tanglu|Ubuntu|Kubuntu)
# Set a monochromatic theme for Tanglu/Ubuntu.
echo "${1}set menu_color_normal=white/black"
echo "${1}set menu_color_highlight=black/light-gray"
if [ -e /usr/share/plymouth/themes/default.grub ]; then
sed "s/^/${1}/" /usr/share/plymouth/themes/default.grub
fi
# For plymouth backward compatiblity. Can be removed
# after xenial.
if [ -e /lib/plymouth/themes/default.grub ]; then
sed "s/^/${1}/" /lib/plymouth/themes/default.grub
fi
;;
*)
# Set the traditional Debian blue theme.
echo "${1}set menu_color_normal=cyan/blue"
echo "${1}set menu_color_highlight=white/blue"
;;
esac
}
module_available(){
local module
for module in "${1}.mod" */"${1}.mod"; do
if [ -f "${module}" ]; then
return 0
fi
done
return 1
}
set_background_image(){
# Step #1: Search all available output modes ...
local output
for output in ${GRUB_TERMINAL_OUTPUT}; do
if [ "x$output" = "xgfxterm" ]; then
break
fi
done
# ... and check if we are able to display a background image at all.
if ! [ "x${output}" = "xgfxterm" ]; then
return 1
fi
# Step #2: Check if the specified background image exists.
if ! [ -f "${1}" ]; then
return 2
fi
# Step #3: Search the correct GRUB module for our background image.
local reader
case "${1}" in
*.jpg|*.JPG|*.jpeg|*.JPEG) reader="jpeg";;
*.png|*.PNG) reader="png";;
*.tga|*.TGA) reader="tga";;
*) return 3;; # Unknown image type.
esac
# Step #4: Check if the necessary GRUB module is available.
if ! module_available "${reader}"; then
return 4
fi
# Step #5: Check if GRUB can read the background image directly.
# If so, we can remove the cache file (if any). Otherwise the backgound
# image needs to be cached under /boot/grub/.
if is_path_readable_by_grub "${1}"; then
rm --force "${BACKGROUND_CACHE}.jpeg" \
"${BACKGROUND_CACHE}.png" "${BACKGROUND_CACHE}.tga"
elif cp "${1}" "${BACKGROUND_CACHE}.${reader}"; then
set -- "${BACKGROUND_CACHE}.${reader}" "${2}" "${3}"
else
return 5
fi
# Step #6: Prepare GRUB to read the background image.
if ! prepare_grub_to_access_device "`${grub_probe} --target=device "${1}"`"; then
return 6
fi
# Step #7: Everything went fine, print out a message to stderr ...
echo "Found background image: ${1}" >&2
# ... and write our configuration snippet to stdout. Use the colors
# desktop-base specified. If we're using a user-defined background, use
# the default colors since we've got no idea how the image looks like.
# If loading the background image fails, use the default theme.
echo "insmod ${reader}"
echo "if background_image `make_system_path_relative_to_its_root "${1}"`; then"
if [ -n "${2}" ]; then
echo " set color_normal=${2}"
fi
if [ -n "${3}" ]; then
echo " set color_highlight=${3}"
fi
if [ -z "${2}" ] && [ -z "${3}" ]; then
echo " true"
fi
echo "else"
set_default_theme " "
echo "fi"
}
# Earlier versions of grub-pc copied the default background image to /boot/grub
# during postinst. Remove those obsolete images if they haven't been touched by
# the user. They are still available under /usr/share/images/desktop-base/ if
# desktop-base is installed.
while read checksum background; do
if [ -f "${background}" ] && [ "x`sha1sum "${background}"`" = "x${checksum} ${background}" ]; then
echo "Removing old background image: ${background}" >&2
rm "${background}"
fi
done <<EOF
648ee65dd0c157a69b019a5372cbcfea4fc754a5 debian-blueish-wallpaper-640x480.png
0431e97a6c661084c59676c4baeeb8c2f602edb8 debian-blueish-wallpaper-640x480.png
968ecf6696c5638cfe80e8e70aba239526270864 debian-blueish-wallpaper-640x480.tga
11143e8c92a073401de0b0fd42d0c052af4ccd9b moreblue-orbit-grub.png
d00d5e505ab63f2d53fa880bfac447e2d3bb197c moreblue-orbit-grub.png
f5b12c1009ec0a3b029185f6b66cd0d7e5611019 moreblue-orbit-grub.png
EOF
# Include the configuration of desktop-base if available.
if [ -f "/usr/share/desktop-base/grub_background.sh" ]; then
. "/usr/share/desktop-base/grub_background.sh"
fi
# First check whether the user has specified a background image explicitly.
# If so, try to use it. Don't try the other possibilities in that case
# (#608263).
if [ -n "${GRUB_BACKGROUND+x}" ]; then
set_background_image "${GRUB_BACKGROUND}" || set_default_theme
exit 0
fi
# Next search for pictures the user put into /boot/grub/ and use the first one.
for background in *.jpg *.JPG *.jpeg *.JPEG *.png *.PNG *.tga *.TGA; do
if set_background_image "${background}"; then
exit 0
fi
done
# Next try to use the background image and colors specified by desktop-base.
if set_background_image "${WALLPAPER}" "${COLOR_NORMAL}" "${COLOR_HIGHLIGHT}"; then
exit 0
fi
# If we haven't found a background image yet, use the default from desktop-base.
case $GRUB_DISTRIBUTOR in
Ubuntu|Kubuntu)
;;
Tanglu)
if set_background_image "/usr/share/images/grub/grub.png"; then
exit 0
fi
;;
*)
if set_background_image "/usr/share/images/desktop-base/desktop-grub.png"; then
exit 0
fi
;;
esac
# Finally, if all of the above fails, use the default theme.
set_default_theme
set -e
# grub-mkconfig helper script.
# Copyright (C) 2010 Alexander Kurtz <kurtz.alex@googlemail.com>
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Include the GRUB helper library for grub-mkconfig.
. /usr/share/grub/grub-mkconfig_lib
# We want to work in /boot/grub/ only.
test -d /boot/grub; cd /boot/grub
# Set the location of a possibly necessary cache file for the background image.
# NOTE: This MUST BE A DOTFILE to avoid confusing it with user-defined images.
BACKGROUND_CACHE=".background_cache"
set_default_theme(){
case $GRUB_DISTRIBUTOR in
Tanglu|Ubuntu|Kubuntu)
# Set a monochromatic theme for Tanglu/Ubuntu.
echo "${1}set menu_color_normal=white/black"
echo "${1}set menu_color_highlight=black/light-gray"
if [ -e /usr/share/plymouth/themes/default.grub ]; then
sed "s/^/${1}/" /usr/share/plymouth/themes/default.grub
fi
# For plymouth backward compatiblity. Can be removed
# after xenial.
if [ -e /lib/plymouth/themes/default.grub ]; then
sed "s/^/${1}/" /lib/plymouth/themes/default.grub
fi
;;
*)
# Set the traditional Debian blue theme.
echo "${1}set menu_color_normal=cyan/blue"
echo "${1}set menu_color_highlight=white/blue"
;;
esac
}
module_available(){
local module
for module in "${1}.mod" */"${1}.mod"; do
if [ -f "${module}" ]; then
return 0
fi
done
return 1
}
set_background_image(){
# Step #1: Search all available output modes ...
local output
for output in ${GRUB_TERMINAL_OUTPUT}; do
if [ "x$output" = "xgfxterm" ]; then
break
fi
done
# ... and check if we are able to display a background image at all.
if ! [ "x${output}" = "xgfxterm" ]; then
return 1
fi
# Step #2: Check if the specified background image exists.
if ! [ -f "${1}" ]; then
return 2
fi
# Step #3: Search the correct GRUB module for our background image.
local reader
case "${1}" in
*.jpg|*.JPG|*.jpeg|*.JPEG) reader="jpeg";;
*.png|*.PNG) reader="png";;
*.tga|*.TGA) reader="tga";;
*) return 3;; # Unknown image type.
esac
# Step #4: Check if the necessary GRUB module is available.
if ! module_available "${reader}"; then
return 4
fi
# Step #5: Check if GRUB can read the background image directly.
# If so, we can remove the cache file (if any). Otherwise the backgound
# image needs to be cached under /boot/grub/.
if is_path_readable_by_grub "${1}"; then
rm --force "${BACKGROUND_CACHE}.jpeg" \
"${BACKGROUND_CACHE}.png" "${BACKGROUND_CACHE}.tga"
elif cp "${1}" "${BACKGROUND_CACHE}.${reader}"; then
set -- "${BACKGROUND_CACHE}.${reader}" "${2}" "${3}"
else
return 5
fi
# Step #6: Prepare GRUB to read the background image.
if ! prepare_grub_to_access_device "`${grub_probe} --target=device "${1}"`"; then
return 6
fi
# Step #7: Everything went fine, print out a message to stderr ...
echo "Found background image: ${1}" >&2
# ... and write our configuration snippet to stdout. Use the colors
# desktop-base specified. If we're using a user-defined background, use
# the default colors since we've got no idea how the image looks like.
# If loading the background image fails, use the default theme.
echo "insmod ${reader}"
echo "if background_image `make_system_path_relative_to_its_root "${1}"`; then"
if [ -n "${2}" ]; then
echo " set color_normal=${2}"
fi
if [ -n "${3}" ]; then
echo " set color_highlight=${3}"
fi
if [ -z "${2}" ] && [ -z "${3}" ]; then
echo " true"
fi
echo "else"
set_default_theme " "
echo "fi"
}
# Earlier versions of grub-pc copied the default background image to /boot/grub
# during postinst. Remove those obsolete images if they haven't been touched by
# the user. They are still available under /usr/share/images/desktop-base/ if
# desktop-base is installed.
while read checksum background; do
if [ -f "${background}" ] && [ "x`sha1sum "${background}"`" = "x${checksum} ${background}" ]; then
echo "Removing old background image: ${background}" >&2
rm "${background}"
fi
done <<EOF
648ee65dd0c157a69b019a5372cbcfea4fc754a5 debian-blueish-wallpaper-640x480.png
0431e97a6c661084c59676c4baeeb8c2f602edb8 debian-blueish-wallpaper-640x480.png
968ecf6696c5638cfe80e8e70aba239526270864 debian-blueish-wallpaper-640x480.tga
11143e8c92a073401de0b0fd42d0c052af4ccd9b moreblue-orbit-grub.png
d00d5e505ab63f2d53fa880bfac447e2d3bb197c moreblue-orbit-grub.png
f5b12c1009ec0a3b029185f6b66cd0d7e5611019 moreblue-orbit-grub.png
EOF
# Include the configuration of desktop-base if available.
if [ -f "/usr/share/desktop-base/grub_background.sh" ]; then
. "/usr/share/desktop-base/grub_background.sh"
fi
# First check whether the user has specified a background image explicitly.
# If so, try to use it. Don't try the other possibilities in that case
# (#608263).
if [ -n "${GRUB_BACKGROUND+x}" ]; then
set_background_image "${GRUB_BACKGROUND}" || set_default_theme
exit 0
fi
# Next search for pictures the user put into /boot/grub/ and use the first one.
for background in *.jpg *.JPG *.jpeg *.JPEG *.png *.PNG *.tga *.TGA; do
if set_background_image "${background}"; then
exit 0
fi
done
# Next try to use the background image and colors specified by desktop-base.
if set_background_image "${WALLPAPER}" "${COLOR_NORMAL}" "${COLOR_HIGHLIGHT}"; then
exit 0
fi
# If we haven't found a background image yet, use the default from desktop-base.
case $GRUB_DISTRIBUTOR in
Ubuntu|Kubuntu)
;;
Tanglu)
if set_background_image "/usr/share/images/grub/grub.png"; then
exit 0
fi
;;
*)
if set_background_image "/usr/share/images/desktop-base/desktop-grub.png"; then
exit 0
fi
;;
esac
# Finally, if all of the above fails, use the default theme.
set_default_theme
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"
ubuntu_recovery="1"
quiet_boot="1"
quick_boot="1"
gfxpayload_dynamic="1"
vt_handoff="1"
. "$pkgdatadir/grub-mkconfig_lib"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
CLASS="--class gnu-linux --class gnu --class os"
SUPPORTED_INITS="sysvinit:/lib/sysvinit/init systemd:/lib/systemd/systemd upstart:/sbin/upstart"
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
else
case ${GRUB_DISTRIBUTOR} in
Ubuntu|Kubuntu)
OS="${GRUB_DISTRIBUTOR}"
;;
*)
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
;;
esac
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
fi
# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
/dev/loop/*|/dev/loop[0-9])
GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
# We can't cope with devices loop-mounted from files here.
case ${GRUB_DEVICE} in
/dev/*) ;;
*) exit 0 ;;
esac
;;
esac
# Default to disabling partition uuid support to maintian compatibility with
# older kernels.
GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}
# get_dm_field_for_dev /dev/dm-0 uuid -> get the device mapper UUID for /dev/dm-0
# get_dm_field_for_dev /dev/dm-1 name -> get the device mapper name for /dev/dm-1
# etc
get_dm_field_for_dev () {
dmsetup info -c --noheadings -o $2 $1 2>/dev/null
}
# Is $1 a multipath device?
is_multipath () {
local dmuuid dmtype
dmuuid="$(get_dm_field_for_dev $1 uuid)"
if [ $? -ne 0 ]; then
# Not a device mapper device -- or dmsetup not installed, and as
# multipath depends on kpartx which depends on dmsetup, if there is no
# dmsetup then there are not going to be any multipath devices.
return 1
fi
# A device mapper "uuid" is always <type>-<uuid>. If <type> is of the form
# part[0-9] then <uuid> is the device the partition is on and we want to
# look at that instead. A multipath node always has <type> of mpath.
dmtype="${dmuuid%%-*}"
if [ "${dmtype#part}" != "$dmtype" ]; then
dmuuid="${dmuuid#*-}"
dmtype="${dmuuid%%-*}"
fi
if [ "$dmtype" = "mpath" ]; then
return 0
else
return 1
fi
}
if test -e "${GRUB_DEVICE}" && is_multipath "${GRUB_DEVICE}"; then
# If / is multipathed, there will be multiple paths to the partition, so
# using root=UUID= exposes the boot process to udev races. In addition
# GRUB_DEVICE in this case will be /dev/dm-0 or similar -- better to use a
# symlink that depends on the multipath name.
GRUB_DEVICE=/dev/mapper/"$(get_dm_field_for_dev $GRUB_DEVICE name)"
GRUB_DISABLE_LINUX_UUID=true
fi
# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
# and mounting btrfs requires user space scanning, so force UUID in this case.
if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
|| ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
&& [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
|| ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
&& ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
|| ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
|| [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi
case x"$GRUB_FS" in
xbtrfs)
rootsubvol="`make_system_path_relative_to_its_root /`"
rootsubvol="${rootsubvol#/}"
if [ "x${rootsubvol}" != x ]; then
GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
fi;;
xzfs)
# We have a more specialized ZFS handler, with multiple system in 10_linux_zfs.
if [ -e "`dirname $(readlink -f $0)`/10_linux_zfs" ]; then
exit 0
fi
rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs%/}"
;;
esac
title_correction_code=
if [ -x /lib/recovery-mode/recovery-menu ]; then
GRUB_CMDLINE_LINUX_RECOVERY=recovery
else
GRUB_CMDLINE_LINUX_RECOVERY=single
fi
if [ "$ubuntu_recovery" = 1 ]; then
GRUB_CMDLINE_LINUX_RECOVERY="$GRUB_CMDLINE_LINUX_RECOVERY nomodeset"
fi
if [ "$vt_handoff" = 1 ]; then
for word in $GRUB_CMDLINE_LINUX_DEFAULT; do
if [ "$word" = splash ]; then
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT \$vt_handoff"
fi
done
fi
if [ x"$GRUB_FORCE_PARTUUID" != x ]; then
echo "set partuuid=${GRUB_FORCE_PARTUUID}"
fi
linux_entry ()
{
os="$1"
version="$2"
type="$3"
args="$4"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
if [ x$type != xsimple ] ; then
case $type in
recovery)
title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" ;;
init-*)
title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "${type#init-}")" ;;
*)
title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;;
esac
if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")"
fi
echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
else
echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
fi
if [ "$quick_boot" = 1 ]; then
echo " recordfail" | sed "s/^/$submenu_indentation/"
fi
if [ x$type != xrecovery ] ; then
save_default_entry | grub_add_tab
fi
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
echo " load_video" | sed "s/^/$submenu_indentation/"
else
if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then
echo " load_video" | sed "s/^/$submenu_indentation/"
fi
fi
if ([ "$ubuntu_recovery" = 0 ] || [ x$type != xrecovery ]) && \
([ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 1 ]); then
echo " gfxmode \$linux_gfx_mode" | sed "s/^/$submenu_indentation/"
fi
echo " insmod gzio" | sed "s/^/$submenu_indentation/"
echo " if [ x\$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi" | sed "s/^/$submenu_indentation/"
if [ x$dirname = x/ ]; then
if [ -z "${prepare_root_cache}" ]; then
prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)"
fi
printf '%s\n' "${prepare_root_cache}" | sed "s/^/$submenu_indentation/"
else
if [ -z "${prepare_boot_cache}" ]; then
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)"
fi
printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
fi
if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then
message="$(gettext_printf "Loading Linux %s ..." ${version})"
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
EOF
fi
if test -d /sys/firmware/efi && test -e "${linux}.efi.signed"; then
sed "s/^/$submenu_indentation/" << EOF
linux ${rel_dirname}/${basename}.efi.signed root=${linux_root_device_thisversion} ro ${args}
EOF
else
# We have initrd and PARTUUID is set - we try to boot without initrd, and fallback to using it
# if it fails.
# "panic=-1" means "on panic reboot immediately". "panic=0" disables the reboot behavior.
if [ x"$GRUB_FORCE_PARTUUID" != x ]; then
linux_root_device_thisversion="PARTUUID=${GRUB_FORCE_PARTUUID}"
fi
message="$(gettext_printf "Loading initial ramdisk ...")"
if test -n "${initrd}" && [ x"$GRUB_FORCE_PARTUUID" != x ]; then
sed "s/^/$submenu_indentation/" << EOF
if [ "\${initrdfail}" = 1 ]; then
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
EOF
if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
EOF
fi
sed "s/^/$submenu_indentation/" << EOF
initrd ${rel_dirname}/${initrd}
else
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} panic=-1
fi
initrdfail
EOF
else
# We don't have initrd or we don't want to set PARTUUID. Don't try initrd-less boot with fallback.
sed "s/^/$submenu_indentation/" << EOF
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
EOF
if test -n "${initrd}"; then
# We do have initrd - let's use it at boot.
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
EOF
fi
sed "s/^/$submenu_indentation/" << EOF
initrd ${rel_dirname}/${initrd}
EOF
fi
fi
if test -n "${dtb}" ; then
if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then
message="$(gettext_printf "Loading device tree blob...")"
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
EOF
fi
sed "s/^/$submenu_indentation/" << EOF
devicetree ${rel_dirname}/${dtb}
EOF
fi
fi
sed "s/^/$submenu_indentation/" << EOF
}
EOF
}
machine=`uname -m`
case "x$machine" in
xi?86 | xx86_64)
list=
for i in /boot/vmlinuz-* /vmlinuz-* /boot/kernel-* ; do
if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
done ;;
*)
list=
for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* /boot/kernel-* ; do
if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
done ;;
esac
case "$machine" in
i?86) GENKERNEL_ARCH="x86" ;;
mips|mips64) GENKERNEL_ARCH="mips" ;;
mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
arm*) GENKERNEL_ARCH="arm" ;;
*) GENKERNEL_ARCH="$machine" ;;
esac
prepare_boot_cache=
prepare_root_cache=
boot_device_id=
title_correction_code=
cat << 'EOF'
function gfxmode {
set gfxpayload="${1}"
EOF
if [ "$vt_handoff" = 1 ]; then
cat << 'EOF'
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=7
else
set vt_handoff=
fi
EOF
fi
cat << EOF
}
EOF
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 0 ]; then
echo "set linux_gfx_mode=$GRUB_GFXPAYLOAD_LINUX"
else
cat << EOF
if [ "\${recordfail}" != 1 ]; then
if [ -e \${prefix}/gfxblacklist.txt ]; then
if hwmatch \${prefix}/gfxblacklist.txt 3; then
if [ \${match} = 0 ]; then
set linux_gfx_mode=keep
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=keep
fi
else
set linux_gfx_mode=text
fi
EOF
fi
cat << EOF
export linux_gfx_mode
EOF
# Extra indentation to add to menu entries in a submenu. We're not in a submenu
# yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
submenu_indentation=""
is_top_level=true
while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`
case $linux in
*.efi.signed)
# We handle these in linux_entry.
list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
continue
;;
esac
gettext_printf "Found linux image: %s\n" "$linux" >&2
basename=`basename $linux`
dirname=`dirname $linux`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
initrd_early=
for i in ${GRUB_EARLY_INITRD_LINUX_STOCK} \
${GRUB_EARLY_INITRD_LINUX_CUSTOM}; do
if test -e "${dirname}/${i}" ; then
initrd_early="${initrd_early} ${i}"
fi
done
initrd_real=
for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
"initrd-${version}" "initramfs-${version}.img" \
"initrd.img-${alt_version}" "initrd-${alt_version}.img" \
"initrd-${alt_version}" "initramfs-${alt_version}.img" \
"initramfs-genkernel-${version}" \
"initramfs-genkernel-${alt_version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do
if test -e "${dirname}/${i}" ; then
initrd_real="${i}"
break
fi
done
initrd=
if test -n "${initrd_early}" || test -n "${initrd_real}"; then
initrd="${initrd_real}"
if test -n "${initrd_early}"; then
initrd="${initrd_early} ${initrd}"
fi
initrd_display=
for i in ${initrd}; do
initrd_display="${initrd_display} ${dirname}/${i}"
done
gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
fi
dtb=
for i in "dtb-${version}" "dtb-${alt_version}" "dtb"; do
if test -e "${dirname}/${i}" ; then
dtb="$i"
break
fi
done
config=
for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
if test -e "${i}" ; then
config="${i}"
break
fi
done
initramfs=
if test -n "${config}" ; then
initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"`
fi
if test -z "${initramfs}" && test -z "${initrd_real}" ; then
# "UUID=" and "ZFS=" magic is parsed by initrd or initramfs. Since there's
# no initrd or builtin initramfs, it can't work here.
if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \
|| [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then
linux_root_device_thisversion=${GRUB_DEVICE}
else
linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID}
fi
fi
if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
linux_entry "${OS}" "${version}" simple \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
submenu_indentation="$grub_tab"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
# TRANSLATORS: %s is replaced with an OS name
echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
is_top_level=false
fi
linux_entry "${OS}" "${version}" advanced \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
for supported_init in ${SUPPORTED_INITS}; do
init_path="${supported_init#*:}"
if [ -x "${init_path}" ] && [ "$(readlink -f /sbin/init)" != "$(readlink -f "${init_path}")" ]; then
linux_entry "${OS}" "${version}" "init-${supported_init%%:*}" \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} init=${init_path}"
fi
done
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${version}" recovery \
"${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}"
fi
list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
done
# If at least one kernel was found, then we need to
# add a closing '}' for the submenu command.
if [ x"$is_top_level" != xtrue ]; then
echo '}'
fi
echo "$title_correction_code"
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"
ubuntu_recovery="1"
quiet_boot="1"
quick_boot="1"
gfxpayload_dynamic="1"
vt_handoff="1"
. "$pkgdatadir/grub-mkconfig_lib"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
CLASS="--class gnu-linux --class gnu --class os"
SUPPORTED_INITS="sysvinit:/lib/sysvinit/init systemd:/lib/systemd/systemd upstart:/sbin/upstart"
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
else
case ${GRUB_DISTRIBUTOR} in
Ubuntu|Kubuntu)
OS="${GRUB_DISTRIBUTOR}"
;;
*)
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
;;
esac
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
fi
# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
/dev/loop/*|/dev/loop[0-9])
GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
# We can't cope with devices loop-mounted from files here.
case ${GRUB_DEVICE} in
/dev/*) ;;
*) exit 0 ;;
esac
;;
esac
# Default to disabling partition uuid support to maintian compatibility with
# older kernels.
GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}
# get_dm_field_for_dev /dev/dm-0 uuid -> get the device mapper UUID for /dev/dm-0
# get_dm_field_for_dev /dev/dm-1 name -> get the device mapper name for /dev/dm-1
# etc
get_dm_field_for_dev () {
dmsetup info -c --noheadings -o $2 $1 2>/dev/null
}
# Is $1 a multipath device?
is_multipath () {
local dmuuid dmtype
dmuuid="$(get_dm_field_for_dev $1 uuid)"
if [ $? -ne 0 ]; then
# Not a device mapper device -- or dmsetup not installed, and as
# multipath depends on kpartx which depends on dmsetup, if there is no
# dmsetup then there are not going to be any multipath devices.
return 1
fi
# A device mapper "uuid" is always <type>-<uuid>. If <type> is of the form
# part[0-9] then <uuid> is the device the partition is on and we want to
# look at that instead. A multipath node always has <type> of mpath.
dmtype="${dmuuid%%-*}"
if [ "${dmtype#part}" != "$dmtype" ]; then
dmuuid="${dmuuid#*-}"
dmtype="${dmuuid%%-*}"
fi
if [ "$dmtype" = "mpath" ]; then
return 0
else
return 1
fi
}
if test -e "${GRUB_DEVICE}" && is_multipath "${GRUB_DEVICE}"; then
# If / is multipathed, there will be multiple paths to the partition, so
# using root=UUID= exposes the boot process to udev races. In addition
# GRUB_DEVICE in this case will be /dev/dm-0 or similar -- better to use a
# symlink that depends on the multipath name.
GRUB_DEVICE=/dev/mapper/"$(get_dm_field_for_dev $GRUB_DEVICE name)"
GRUB_DISABLE_LINUX_UUID=true
fi
# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
# and mounting btrfs requires user space scanning, so force UUID in this case.
if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
|| ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
&& [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
|| ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
&& ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
|| ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
|| [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi
case x"$GRUB_FS" in
xbtrfs)
rootsubvol="`make_system_path_relative_to_its_root /`"
rootsubvol="${rootsubvol#/}"
if [ "x${rootsubvol}" != x ]; then
GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
fi;;
xzfs)
# We have a more specialized ZFS handler, with multiple system in 10_linux_zfs.
if [ -e "`dirname $(readlink -f $0)`/10_linux_zfs" ]; then
exit 0
fi
rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs%/}"
;;
esac
title_correction_code=
if [ -x /lib/recovery-mode/recovery-menu ]; then
GRUB_CMDLINE_LINUX_RECOVERY=recovery
else
GRUB_CMDLINE_LINUX_RECOVERY=single
fi
if [ "$ubuntu_recovery" = 1 ]; then
GRUB_CMDLINE_LINUX_RECOVERY="$GRUB_CMDLINE_LINUX_RECOVERY nomodeset"
fi
if [ "$vt_handoff" = 1 ]; then
for word in $GRUB_CMDLINE_LINUX_DEFAULT; do
if [ "$word" = splash ]; then
GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT \$vt_handoff"
fi
done
fi
if [ x"$GRUB_FORCE_PARTUUID" != x ]; then
echo "set partuuid=${GRUB_FORCE_PARTUUID}"
fi
linux_entry ()
{
os="$1"
version="$2"
type="$3"
args="$4"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
if [ x$type != xsimple ] ; then
case $type in
recovery)
title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")" ;;
init-*)
title="$(gettext_printf "%s, with Linux %s (%s)" "${os}" "${version}" "${type#init-}")" ;;
*)
title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;;
esac
if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")"
fi
echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
else
echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
fi
if [ "$quick_boot" = 1 ]; then
echo " recordfail" | sed "s/^/$submenu_indentation/"
fi
if [ x$type != xrecovery ] ; then
save_default_entry | grub_add_tab
fi
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
echo " load_video" | sed "s/^/$submenu_indentation/"
else
if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then
echo " load_video" | sed "s/^/$submenu_indentation/"
fi
fi
if ([ "$ubuntu_recovery" = 0 ] || [ x$type != xrecovery ]) && \
([ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 1 ]); then
echo " gfxmode \$linux_gfx_mode" | sed "s/^/$submenu_indentation/"
fi
echo " insmod gzio" | sed "s/^/$submenu_indentation/"
echo " if [ x\$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi" | sed "s/^/$submenu_indentation/"
if [ x$dirname = x/ ]; then
if [ -z "${prepare_root_cache}" ]; then
prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)"
fi
printf '%s\n' "${prepare_root_cache}" | sed "s/^/$submenu_indentation/"
else
if [ -z "${prepare_boot_cache}" ]; then
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)"
fi
printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
fi
if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then
message="$(gettext_printf "Loading Linux %s ..." ${version})"
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
EOF
fi
if test -d /sys/firmware/efi && test -e "${linux}.efi.signed"; then
sed "s/^/$submenu_indentation/" << EOF
linux ${rel_dirname}/${basename}.efi.signed root=${linux_root_device_thisversion} ro ${args}
EOF
else
# We have initrd and PARTUUID is set - we try to boot without initrd, and fallback to using it
# if it fails.
# "panic=-1" means "on panic reboot immediately". "panic=0" disables the reboot behavior.
if [ x"$GRUB_FORCE_PARTUUID" != x ]; then
linux_root_device_thisversion="PARTUUID=${GRUB_FORCE_PARTUUID}"
fi
message="$(gettext_printf "Loading initial ramdisk ...")"
if test -n "${initrd}" && [ x"$GRUB_FORCE_PARTUUID" != x ]; then
sed "s/^/$submenu_indentation/" << EOF
if [ "\${initrdfail}" = 1 ]; then
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
EOF
if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
EOF
fi
sed "s/^/$submenu_indentation/" << EOF
initrd ${rel_dirname}/${initrd}
else
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} panic=-1
fi
initrdfail
EOF
else
# We don't have initrd or we don't want to set PARTUUID. Don't try initrd-less boot with fallback.
sed "s/^/$submenu_indentation/" << EOF
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
EOF
if test -n "${initrd}"; then
# We do have initrd - let's use it at boot.
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
EOF
fi
sed "s/^/$submenu_indentation/" << EOF
initrd ${rel_dirname}/${initrd}
EOF
fi
fi
if test -n "${dtb}" ; then
if [ x"$quiet_boot" = x0 ] || [ x"$type" != xsimple ]; then
message="$(gettext_printf "Loading device tree blob...")"
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
EOF
fi
sed "s/^/$submenu_indentation/" << EOF
devicetree ${rel_dirname}/${dtb}
EOF
fi
fi
sed "s/^/$submenu_indentation/" << EOF
}
EOF
}
machine=`uname -m`
case "x$machine" in
xi?86 | xx86_64)
list=
for i in /boot/vmlinuz-* /vmlinuz-* /boot/kernel-* ; do
if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
done ;;
*)
list=
for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* /boot/kernel-* ; do
if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
done ;;
esac
case "$machine" in
i?86) GENKERNEL_ARCH="x86" ;;
mips|mips64) GENKERNEL_ARCH="mips" ;;
mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
arm*) GENKERNEL_ARCH="arm" ;;
*) GENKERNEL_ARCH="$machine" ;;
esac
prepare_boot_cache=
prepare_root_cache=
boot_device_id=
title_correction_code=
cat << 'EOF'
function gfxmode {
set gfxpayload="${1}"
EOF
if [ "$vt_handoff" = 1 ]; then
cat << 'EOF'
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=7
else
set vt_handoff=
fi
EOF
fi
cat << EOF
}
EOF
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "x$GRUB_GFXPAYLOAD_LINUX" != x ] || [ "$gfxpayload_dynamic" = 0 ]; then
echo "set linux_gfx_mode=$GRUB_GFXPAYLOAD_LINUX"
else
cat << EOF
if [ "\${recordfail}" != 1 ]; then
if [ -e \${prefix}/gfxblacklist.txt ]; then
if hwmatch \${prefix}/gfxblacklist.txt 3; then
if [ \${match} = 0 ]; then
set linux_gfx_mode=keep
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=keep
fi
else
set linux_gfx_mode=text
fi
EOF
fi
cat << EOF
export linux_gfx_mode
EOF
# Extra indentation to add to menu entries in a submenu. We're not in a submenu
# yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
submenu_indentation=""
is_top_level=true
while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`
case $linux in
*.efi.signed)
# We handle these in linux_entry.
list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
continue
;;
esac
gettext_printf "Found linux image: %s\n" "$linux" >&2
basename=`basename $linux`
dirname=`dirname $linux`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
initrd_early=
for i in ${GRUB_EARLY_INITRD_LINUX_STOCK} \
${GRUB_EARLY_INITRD_LINUX_CUSTOM}; do
if test -e "${dirname}/${i}" ; then
initrd_early="${initrd_early} ${i}"
fi
done
initrd_real=
for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
"initrd-${version}" "initramfs-${version}.img" \
"initrd.img-${alt_version}" "initrd-${alt_version}.img" \
"initrd-${alt_version}" "initramfs-${alt_version}.img" \
"initramfs-genkernel-${version}" \
"initramfs-genkernel-${alt_version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do
if test -e "${dirname}/${i}" ; then
initrd_real="${i}"
break
fi
done
initrd=
if test -n "${initrd_early}" || test -n "${initrd_real}"; then
initrd="${initrd_real}"
if test -n "${initrd_early}"; then
initrd="${initrd_early} ${initrd}"
fi
initrd_display=
for i in ${initrd}; do
initrd_display="${initrd_display} ${dirname}/${i}"
done
gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
fi
dtb=
for i in "dtb-${version}" "dtb-${alt_version}" "dtb"; do
if test -e "${dirname}/${i}" ; then
dtb="$i"
break
fi
done
config=
for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
if test -e "${i}" ; then
config="${i}"
break
fi
done
initramfs=
if test -n "${config}" ; then
initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"`
fi
if test -z "${initramfs}" && test -z "${initrd_real}" ; then
# "UUID=" and "ZFS=" magic is parsed by initrd or initramfs. Since there's
# no initrd or builtin initramfs, it can't work here.
if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \
|| [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then
linux_root_device_thisversion=${GRUB_DEVICE}
else
linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID}
fi
fi
if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
linux_entry "${OS}" "${version}" simple \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
submenu_indentation="$grub_tab"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
# TRANSLATORS: %s is replaced with an OS name
echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
is_top_level=false
fi
linux_entry "${OS}" "${version}" advanced \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
for supported_init in ${SUPPORTED_INITS}; do
init_path="${supported_init#*:}"
if [ -x "${init_path}" ] && [ "$(readlink -f /sbin/init)" != "$(readlink -f "${init_path}")" ]; then
linux_entry "${OS}" "${version}" "init-${supported_init%%:*}" \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} init=${init_path}"
fi
done
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${version}" recovery \
"${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}"
fi
list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
done
# If at least one kernel was found, then we need to
# add a closing '}' for the submenu command.
if [ x"$is_top_level" != xtrue ]; then
echo '}'
fi
echo "$title_correction_code"
LinuxMint 20 xfce не показывает меню grub после upgrade
10_linux_zfs
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2019 Canonical Ltd.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
prefix="/usr"
datarootdir="/usr/share"
ubuntu_recovery="1"
quiet_boot="1"
quick_boot="1"
gfxpayload_dynamic="1"
vt_handoff="1"
. "${pkgdatadir}/grub-mkconfig_lib"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
set -u
## Skip early if zfs utils isn't installed (instead of failing on first zpool list)
if ! `which zfs >/dev/null 2>&1`; then
exit 0
fi
imported_pools=""
MNTDIR="$(mktemp -d ${TMPDIR:-/tmp}/zfsmnt.XXXXXX)"
ZFSTMP="$(mktemp -d ${TMPDIR:-/tmp}/zfstmp.XXXXXX)"
RC=0
on_exit() {
# Restore initial zpool import state
for pool in ${imported_pools}; do
zpool export "${pool}"
done
mountpoint -q "${MNTDIR}" && umount "${MNTDIR}" || true
rmdir "${MNTDIR}"
rm -rf "${ZFSTMP}"
exit "${RC}"
}
trap on_exit EXIT INT QUIT ABRT PIPE TERM
# List ONLINE and DEGRADED pools
import_pools() {
# We have to ignore zpool import output, as potentially multiple / will be available,
# and we need to autodetect all zpools this way with their real mountpoints.
local initial_pools="$(zpool list | awk '{if (NR>1) print $1}')"
local all_pools=""
local imported_pools=""
local err=""
set +e
err="$(zpool import -f -a -o cachefile=none -o readonly=on -N 2>&1)"
# Only print stderr if the command returned an error
# (it can echo "No zpool to import" with success, which we don't want)
if [ $? -ne 0 ]; then
echo "Some pools couldn't be imported and will be ignored:\n${err}" >&2
fi
set -e
all_pools="$(zpool list | awk '{if (NR>1) print $1}')"
for pool in ${all_pools}; do
if echo "${initial_pools}" | grep -wq "${pool}"; then
continue
fi
imported_pools="${imported_pools} ${pool}"
done
echo "${imported_pools}"
}
# List all the dataset with a root mountpoint
get_root_datasets() {
local pools="$(zpool list | awk '{if (NR>1) print $1}')"
for p in ${pools}; do
local rel_pool_root=$(zpool get -H altroot ${p} | awk '{print $3}')
if [ "${rel_pool_root}" = "-" ]; then
rel_pool_root="/"
fi
zfs list -H -o name,canmount,mountpoint -t filesystem | grep -E '^'"${p}"'(\s|/[[:print:]]*\s)(on|noauto)\s'"${rel_pool_root}"'$' | awk '{print $1}'
done
}
# find if given datasets can be mounted for directory and return its path (snapshot or real path)
# $1 is our current dataset name
# $2 directory path we look for (cannot contains /)
# $3 is the temporary mount directory to use
# $4 is the optional snapshot name
# return path for directory (which can be a mountpoint)
validate_system_dataset() {
local dataset="$1"
local directory="$2"
local mntdir="$3"
local snapshot_name="$4"
local mount_path="${mntdir}/${directory}"
if ! zfs list "${dataset}" >/dev/null 2>&1; then
return
fi
if ! mount -o noatime,zfsutil -t zfs "${dataset}" "${mount_path}"; then
grub_warn "Failed to find a valid directory '${directory}' for dataset '${dataset}@${snapshot_name}'. Ignoring"
return
fi
local candidate_path="${mount_path}"
if [ -n "${snapshot_name}" ]; then
# WORKAROUND a bug https://github.com/zfsonlinux/zfs/issues/9958
# Reading the content of a snapshot fails if it is not the first mount
# for a given dataset
first_mntdir=$(awk '{if ($1 == "'${dataset}'") {print $2; exit;}}' /proc/mounts)
if [ "${first_mntdir}" = "/" ]; then
# prevents // on candidate_path
first_mntdir=""
fi
candidate_path="${first_mntdir}/.zfs/snapshot/${snapshot_name}"
fi
if [ -n "$(ls ${candidate_path} 2>/dev/null)" ]; then
echo "${candidate_path}"
return
else
mountpoint -q "${mount_path}" && umount "${mount_path}" || true
fi
}
# Detect system directory relevant to the other, trying to find the ones associated on the current dataset or snapshot/
# System directory should be at most a direct child dataset of main datasets (no recursivity)
# We can fallback trying other zfs pools if no match has been found.
# $1 is our current dataset name (which can have @snapshot name)
# $2 directory path we look for (cannot contains /)
# $3 restrict_to_same_pool (true|false) force looking for dataset with the same basename in the current dataset pool only
# $4 is the temporary mount directory to use
# $5 is the optional etc directory (if not $2 is not etc itself)
# return path for directory (which can be a mountpoint)
get_system_directory() {
local dataset_path="$1"
local directory="$2"
local restrict_to_same_pool="$3"
local mntdir="$4"
local etc_dir="$5"
if [ -z "${etc_dir}" ]; then
etc_dir="${mntdir}/etc"
fi
local candidate_path="${mntdir}/${directory}"
# 1. Look for /etc/fstab first (which will mount even on top of non empty $directory)
local mounted_fstab_entry="false"
if [ -f "${etc_dir}/fstab" ]; then
mount_args=$(awk '/^[^#].*[ \t]\/'"${directory}"'[ \t]/ {print "-t", $3, $1}' "${etc_dir}/fstab")
if [ -n "${mount_args}" ]; then
mounted_fstab_entry="true"
mount -o noatime ${mount_args} "${candidate_path}" || mounted_fstab_entry="false"
fi
fi
# If directory isn't empty. Only count if coming from /etc/fstab. Will be
# handled below otherwise as we are interested in potential snapshots.
if [ "${mounted_fstab_entry}" = "true" -a -n "$(ls ${candidate_path} 2>/dev/null)" ]; then
echo "${candidate_path}"
return
fi
# 2. Handle zfs case, which can be a snapshots.
local base_dataset_path="${dataset_path}"
local snapshot_name=""
# For snapshots we extract the parent dataset
if echo "${dataset_path}" | grep -q '@'; then
base_dataset_path=$(echo "${dataset_path}" | cut -d '@' -f1)
snapshot_name=$(echo "${dataset_path}" | cut -d '@' -f2)
fi
base_dataset_name="${base_dataset_path##*/}"
base_pool="$(echo "${base_dataset_path}" | cut -d'/' -f1)"
# 2.a) Look for child dataset included in base dataset, which needs to hold same snapshot if any
candidate_path=$(validate_system_dataset "${base_dataset_path}/${directory}" "${directory}" "${mntdir}" "${snapshot_name}")
if [ -n "${candidate_path}" ]; then
echo "${candidate_path}"
return
fi
# 2.b) Look for current dataset (which is already mounted as /)
candidate_path="${mntdir}/${directory}"
if [ -n "${snapshot_name}" ]; then
# WORKAROUND a bug https://github.com/zfsonlinux/zfs/issues/9958
# Reading the content of a snapshot fails if it is not the first mount
# for a given dataset
first_mntdir=$(awk '{if ($1 == "'${base_dataset_path}'") {print $2; exit;}}' /proc/mounts)
if [ "${first_mntdir}" = "/" ]; then
# prevents // on candidate_path
first_mntdir=""
fi
candidate_path="${first_mntdir}/.zfs/snapshot/${snapshot_name}/${directory}"
fi
if [ -n "$(ls ${candidate_path} 2>/dev/null)" ]; then
echo "${candidate_path}"
return
fi
# 2.c) Look for every datasets in every pool which isn't the current dataset which holds:
# - the same dataset name (last section) than our base_dataset_name
# - mountpoint=directory
# - canmount!=off
all_same_base_dataset_name="$(zfs list -H -t filesystem -o name,canmount | awk '/^[^ ]+\/'"${base_dataset_name}"'[ \t](on|noauto)/ {print $1}') "
# order by local pool datasets first
current_pool_same_base_datasets=""
other_pools_same_base_datasets=""
root_pool=$(echo "${dataset_path%%/*}")
for d in ${all_same_base_dataset_name}; do
cur_dataset_pool=$(echo "${d%%/*}")
if echo "${cur_dataset_pool}" | grep -wq "${root_pool}" 2>/dev/null ; then
current_pool_same_base_datasets="${current_pool_same_base_datasets} ${d}"
else
other_pools_same_base_datasets="${other_pools_same_base_datasets} ${d}"
fi
done
ordered_same_base_datasets="${current_pool_same_base_datasets} ${other_pools_same_base_datasets}"
if [ "${restrict_to_same_pool}" = "true" ]; then
ordered_same_base_datasets="${current_pool_same_base_datasets}"
fi
# now, loop over them
for d in ${ordered_same_base_datasets}; do
cur_dataset_pool=$(echo "${d%%/*}")
rel_pool_root=$(zpool get -H altroot ${cur_dataset_pool} | awk '{print $3}')
if [ "${rel_pool_root}" = "-" ]; then
rel_pool_root=""
fi
# check mountpoint match
candidate_dataset=$(zfs get -H mountpoint ${d} | grep -E "mountpoint\s${rel_pool_root}/${directory}\s" | awk '{print $1}')
if [ -z "${candidate_dataset}" ]; then
continue
fi
candidate_path=$(validate_system_dataset "${candidate_dataset}" "${directory}" "${mntdir}" "${snapshot_name}")
if [ -n "${candidate_path}" ]; then
echo "${candidate_path}"
return
fi
done
# 2.d) If we didn't find anything yet: check for persistent datasets corresponding to our mountpoint, with canmount=on without any snapshot associated:
# Note: we go over previous datasets as well, but this is ok, as we didn't include them before.
all_mountable_datasets="$(zfs list -t filesystem -o name,canmount | awk '/^[^ ]+[ \t]+on/ {print $1}')"
# order by local pool datasets first
current_pool_datasets=""
other_pools_datasets=""
root_pool=$(echo "${dataset_path%%/*}")
for d in ${all_mountable_datasets}; do
cur_dataset_pool=$(echo "${d%%/*}")
if echo "${cur_dataset_pool}" | grep -wq "${root_pool}" 2>/dev/null ; then
current_pool_datasets="${current_pool_datasets} ${d}"
else
other_pools_datasets="${other_pools_datasets} ${d}"
fi
done
ordered_datasets="${current_pool_datasets} ${other_pools_datasets}"
if [ "${restrict_to_same_pool}" = "true" ]; then
ordered_datasets="${current_pool_datasets}"
fi
for d in ${ordered_datasets}; do
cur_dataset_pool=$(echo "${d%%/*}")
rel_pool_root=$(zpool get -H altroot ${cur_dataset_pool} | awk '{print $3}')
if [ "${rel_pool_root}" = "-" ]; then
rel_pool_root=""
fi
# check mountpoint match
candidate_dataset=$(zfs get -H mountpoint ${d} | grep -E "mountpoint\s${rel_pool_root}/${directory}\s" | awk '{print $1}')
if [ -z "${candidate_dataset}" ]; then
continue
fi
candidate_path=$(validate_system_dataset "${d}" "${directory}" "${mntdir}" "")
if [ -n "${candidate_path}" ]; then
echo "${candidate_path}"
return
fi
done
grub_warn "Failed to find a valid directory '${directory}' for dataset '${dataset_path}'. Ignoring"
return
}
# Try our default layout bpool as a prefered layout (fast path)
# This is get_system_directory for boot optimized for our default installation layout
# $1 is our current dataset name (which can have @snapshot name)
# $2 is the temporary mount directory to use
# return path for directory (which can be a mountpoint) if found
try_default_layout_bpool() {
local root_dataset_path="$1"
local mntdir="$2"
dataset_basename="${root_dataset_path##*/}"
candidate_dataset="bpool/BOOT/${dataset_basename}"
dataset_properties="$(zfs get -H mountpoint,canmount ${candidate_dataset} | cut -f3 | paste -sd ' ')"
if [ -z "${dataset_properties}" ]; then
return
fi
rel_pool_root=$(zpool get -H altroot bpool | awk '{print $3}')
if [ "${rel_pool_root}" = "-" ]; then
rel_pool_root=""
fi
snapshot_name="${dataset_basename##*@}"
[ "${snapshot_name}" = "${dataset_basename}" ] && snapshot_name=""
if [ -z "${snapshot_name}" ]; then
if ! echo "${dataset_properties}" | grep -Eq "${rel_pool_root}/boot (on|noauto)"; then
return
fi
else
candidate_dataset=$(echo "${candidate_dataset}" | cut -d '@' -f1)
fi
validate_system_dataset "${candidate_dataset}" "boot" "${mntdir}" "${snapshot_name}"
}
# Return if secure boot is enabled on that system
is_secure_boot_enabled() {
if LANG=C mokutil --sb-state 2>/dev/null | grep -qi enabled; then
echo "true"
return
fi
echo "false"
return
}
# Given a filesystem or snapshot dataset, returns dataset|machine id|pretty name|last used
# $1 is dataset we want information from
# $2 is the temporary mount directory to use
get_dataset_info() {
local dataset="$1"
local mntdir="$2"
local base_dataset="${dataset}"
local etc_dir="${mntdir}/etc"
local is_snapshot="false"
# For snapshot we extract the parent dataset
if echo "${dataset}" | grep -q '@'; then
base_dataset=$(echo "${dataset}" | cut -d '@' -f1)
is_snapshot="true"
fi
mount -o noatime,zfsutil -t zfs "${base_dataset}" "${mntdir}"
# read machine-id/os-release from /etc
etc_dir=$(get_system_directory "${dataset}" "etc" "true" "${mntdir}" "")
if [ -z "${etc_dir}" ]; then
grub_warn "Ignoring ${dataset}"
mountpoint -q "${mntdir}/etc" && umount "${mntdir}/etc" || true
umount "${mntdir}"
return
fi
machine_id=""
if [ -f "${etc_dir}/machine-id" ]; then
machine_id=$(cat "${etc_dir}/machine-id")
fi
# We have to use a random temporary id if we don't have any machine-id file or if this one is empty
# (mostly the case of new installations before first boot).
# Let's use the dataset name directly for this.
# Consequence is that all datasets are then separated.
if [ -z "${machine_id}" ]; then
machine_id="${dataset}"
fi
pretty_name=$(. "${etc_dir}/os-release" && echo "${PRETTY_NAME}")
mountpoint -q "${mntdir}/etc" && umount "${mntdir}/etc" || true
# read available kernels from /boot
boot_dir="$(try_default_layout_bpool "${dataset}" "${mntdir}")"
if [ -z "${boot_dir}" ]; then
boot_dir=$(get_system_directory "${dataset}" "boot" "false" "${mntdir}" "${etc_dir}")
fi
if [ -z "${boot_dir}" ]; then
grub_warn "Ignoring ${dataset}"
mountpoint -q "${mntdir}/boot" && umount "${mntdir}/boot" || true
umount "${mntdir}"
return
fi
machine="$(uname -m)"
case "${machine}" in
i?86) GENKERNEL_ARCH="x86" ;;
mips|mips64) GENKERNEL_ARCH="mips" ;;
mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
arm*) GENKERNEL_ARCH="arm" ;;
*) GENKERNEL_ARCH="${machine}" ;;
esac
initrd_list=""
kernel_list=""
for linux in $(find "${boot_dir}" -maxdepth 1 -type f -regex '.*/\(vmlinuz\|vmlinux\|kernel\)-.*'|sort -V); do
if ! grub_file_is_not_garbage "${linux}" ; then
continue
fi
# Filters entry if efi/non efi.
# Note that for now we allow kernel without .efi.signed as those are signed kernel
# on ubuntu, loaded by the shim.
case "${linux}" in
*.efi.signed)
if [ "$(is_secure_boot_enabled)" = "false" ]; then
continue
fi
;;
esac
linux_basename=$(basename "${linux}")
linux_dirname=$(dirname "${linux}")
version=$(echo "${linux_basename}" | sed -e "s,^[^0-9]*-,,g")
alt_version=$(echo "${version}" | sed -e "s,\.old$,,g")
gettext_printf "Found linux image: %s in %s\n" "${linux_basename}" "${dataset}" >&2
initrd=""
for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
"initrd-${version}" "initramfs-${version}.img" \
"initrd.img-${alt_version}" "initrd-${alt_version}.img" \
"initrd-${alt_version}" "initramfs-${alt_version}.img" \
"initramfs-genkernel-${version}" \
"initramfs-genkernel-${alt_version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do
if test -e "${linux_dirname}/${i}" ; then
initrd="$i"
break
fi
done
if test -z "${initrd}" ; then
grub_warn "Couldn't find any valid initrd for dataset ${dataset}."
continue
fi
gettext_printf "Found initrd image: %s in %s\n" "${initrd}" "${dataset}" >&2
rel_linux_dirname=$(make_system_path_relative_to_its_root "${linux_dirname}")
initrd_list="${rel_linux_dirname}/${initrd}|${initrd_list}"
kernel_list="${rel_linux_dirname}/${linux_basename}|${kernel_list}"
done
initrd_list="${initrd_list%|}"
kernel_list="${kernel_list%|}"
initrd_device=$(${grub_probe} --target=device "${boot_dir}" | head -1)
mountpoint -q "${mntdir}/boot" && umount "${mntdir}/boot" || true
# We needed to look in / for snapshots on root dataset, umount there before zfs lazily unmount it
case "${boot_dir}" in /boot/.zfs/snapshot/*)
umount "${boot_dir}" || true
;;
esac
# for zsys snapshots: we want to know which kernel we successful last booted with
last_booted_kernel=$(zfs get -H com.ubuntu.zsys:last-booted-kernel "${dataset}" | awk '{print $3}')
# snapshot: last_used is dataset creation time
if [ "${is_snapshot}" = "true" ]; then
last_used="$(zfs get -pH creation "${dataset}" | awk -F '\t' '{print $3}')"
# otherwise, last_used is manually marked at boot/shutdown on a root dataset for zsys
else
# if current system, take current time
if zfs mount | awk '/[ \t]+\/$/ {print $1}' | grep -q ${dataset}; then
last_used=$(date +%s)
else
last_used=$(zfs get -H com.ubuntu.zsys:last-used "${dataset}" | awk '{print $3}')
# case of non zsys, or zsys without annotation, take /etc/machine-id stat (as we mounted with noatime).
# However, as systems can be relatime, if system is current mounted one, set current time (case of clone + reboot
# within the same d).
if [ "${last_used}" = "-" ]; then
last_used=$(stat --printf="%X" "${mntdir}/etc/os-release")
if [ -f "${mntdir}/etc/machine-id" ]; then
last_used=$(stat --printf="%X" "${mntdir}/etc/machine-id")
fi
fi
fi
fi
is_zsys=$(zfs get -H com.ubuntu.zsys:bootfs "${base_dataset}" | awk '{print $3}')
if [ -n "${initrd_list}" -a -n "${kernel_list}" ]; then
echo "${dataset}\t${is_zsys}\t${machine_id}\t${pretty_name}\t${last_used}\t${initrd_device}\t${initrd_list}\t${kernel_list}\t${last_booted_kernel}"
else
grub_warn "didn't find any valid initrd or kernel."
fi
umount "${mntdir}" || true
# We needed to look in / for snapshots on root dataset, umount the snapshot for etc before zfs lazily unmount it
case "${etc_dir}" in /.zfs/snapshot/*/etc)
snapshot_path="$(findmnt -n -o TARGET -T ${etc_dir})"
umount "${snapshot_path}" || true
;;
esac
}
# Scan available boot options and returns in a formatted list
# $1 is the temporary mount directory to use
bootlist() {
local mntdir="$1"
local boot_list=""
for dataset in $(get_root_datasets); do
# get information from current root dataset
boot_list="${boot_list}$(get_dataset_info ${dataset} ${mntdir})\n"
# get information from snapshots of this root dataset
for snapshot_dataset in $(zfs list -H -o name -t snapshot "${dataset}"); do
boot_list="${boot_list}$(get_dataset_info ${snapshot_dataset} ${mntdir})\n"
done
done
echo "${boot_list}"
}
# Order machine ids by last_used from their main entry
get_machines_sorted() {
local bootlist="$1"
local machineids="$(echo "${bootlist}" | awk '{print $3}' | sort -u)"
for machineid in ${machineids}; do
echo "${bootlist}" | awk 'BEGIN{FS="\t"} $1 !~ /.*@.*/ {print $5, $3}' | sort -nr | grep -E "[^^]\b${machineid}\b" | head -1
done | sort -nr | awk '{print $2}'
}
# Sort entries by last_used for a given machineid
sort_entries_for_machineid() {
local bootlist="$1"
local machineid="$2"
tab="$(printf '\t')"
echo "${bootlist}" | grep -E "[^^]\b${machineid}\b" | sort -k5,5r -k1,1 -t "${tab}"
}
# Return main entry index
get_main_entry() {
local entries="$1"
echo "${entries}" | awk 'BEGIN{FS="\t"} $1 !~ /.*@.*/ {print}' | head -1
}
# Return specific field at index from entry
get_field_from_entry() {
local entry="$1"
local index="$2"
echo "${entry}" | awk "BEGIN{FS=\"\t\"} {print \$$index}"
}
# Get the main entry metadata
main_entry_meta() {
local main_entry="$1"
initrd=$(get_field_from_entry "${main_entry}" 7 | cut -d'|' -f1)
kernel=$(get_field_from_entry "${main_entry}" 8 | cut -d'|' -f1)
# Take first element (most recent entry) which is not a snapshot
echo "${main_entry}" | awk "BEGIN{ FS=\"\t\"; OFS=\"\t\"} {print \$3, \$2, \"main\", \$4, \$1, \$6, \"$initrd\", \"$kernel\"}"
}
# Get advanced entries metadata
advanced_entries_meta() {
local main_entry="$1"
last_used_kernel="$(get_field_from_entry "${main_entry}" 9 )"
# We must align initrds with kernels.
# Adds initrds to the stack then pop them 1 by 1 as we process the kernels
set -- $(get_field_from_entry "${main_entry}" 7 | tr "|" " ")
for kernel in $(get_field_from_entry "${main_entry}" 8 | tr "|" " "); do
# get initrd and pop to the next one
initrd="$1"; shift
was_last_used_kernel="false"
kernel_basename=$(basename "${kernel}")
if [ "${kernel_basename}" = "${last_used_kernel}" ]; then
was_last_used_kernel="true"
fi
echo "${main_entry}" | awk "BEGIN{ FS=\"\t\"; OFS=\"\t\"} {print \$3, \$2, \"advanced\", \$4, \$1, \$6, \"$initrd\", \"$kernel\", \"$was_last_used_kernel\"}"
done
}
# Get history metadata
history_entries_meta() {
local entries="$1"
local main_dataset_name="$2"
local main_dataset_releasename="$3"
if [ -z "${entries}" ]; then
return
fi
# Traverse snapshots and clones
echo "${entries}" | while read entry; do
name=""
# Compute snapshot/filesystem dataset name
snap_dataset_name="$(get_field_from_entry "${entry}" 1)"
snapname="${snap_dataset_name##*@}"
# If, this is a clone, take what is after main_dataset_name
if [ "${snapname}" = "${snap_dataset_name}" ]; then
snapname="${snap_dataset_name##${main_dataset_name}_}"
# Handle manual user clone (not prefixed by "main_dataset_name")
snapname="${snapname##*/}"
fi
# We keep the snapname only if it is not only a zsys auto snapshot
if echo "${snapname}" | grep -q "^autozsys_"; then
snapname=""
fi
# We store the release only if it different from main dataset release (snapshot before a release upgrade)
releasename=$(get_field_from_entry "${entry}" 4)
if [ "${releasename}" = "${main_dataset_releasename}" ]; then
releasename=""
fi
# Snapshot date
foo="$(get_field_from_entry "${entry}" 5)"
snapdate="$(date -d @$(get_field_from_entry "${entry}" 5) "+%x @ %H:%M")"
# For snapshots/clones the name can have the following formats:
# <DATE>: autozsys, same release
# <OLD_RELEASE> on <DATE>: autozsys, different release
# <SNAPNAME> on <DATE>: Manual snapshot, same release
# <SNAPNAME>, <OLD_RELEASE> on <DATE>: Manual snapshot, different release
if [ "${snapname}" = "" -a "${releasename}" = "" ]; then
name="${snapdate}"
elif [ "${snapname}" = "" -a "${releasename}" != "" ]; then
name=$(gettext_printf "%s on %s" "${releasename}" "${snapdate}")
elif [ "${snapname}" != "" -a "${releasename}" = "" ]; then
name=$(gettext_printf "%s on %s" "${snapname}" "${snapdate}")
else # snapname != "" && releasename != ""
name=$(gettext_printf "%s, %s on %s" "${snapname}" "${releasename}" "${snapdate}")
fi
# Choose kernel and initrd if the snapshot was booted successfully on a specific kernel before
# Take latest by default if no match
initrd=$(get_field_from_entry "${entry}" 7 | cut -d'|' -f1)
kernel=$(get_field_from_entry "${entry}" 8 | cut -d'|' -f1)
last_used_kernel="$(get_field_from_entry "${entry}" 9)"
# We must align initrds with kernels.
# Adds initrds to the stack then pop them 1 by 1 as we process the kernels
set -- $(get_field_from_entry "${entry}" 7 | tr "|" " ")
for k in $(get_field_from_entry "${entry}" 8|tr "|" " "); do
# get initrd and pop to the next one
candidate_initrd="$1"; shift
kernel_basename=$(basename "${k}")
if [ "${kernel_basename}" = "${last_used_kernel}" ]; then
kernel="${k}"
initrd="${candidate_initrd}"
break
fi
done
echo "${entry}" | awk "BEGIN{ FS=\"\t\"; OFS=\"\t\"} {print \$3, \$2, \"history\", \"$name\", \$1, \$6, \"$initrd\", \"$kernel\"}"
done
}
# Generate metadata from a BOOTLIST that will subsequently used to generate
# the final grub menu entries
generate_grub_menu_metadata() {
local bootlist="$1"
# Sort machineids by last_used from their main entry
for machineid in $(get_machines_sorted "${bootlist}"); do
entries="$(sort_entries_for_machineid "${bootlist}" ${machineid})"
main_entry="$(get_main_entry "${entries}")"
if [ -z "$main_entry" ]; then
continue
fi
main_entry_meta "${main_entry}"
advanced_entries_meta "${main_entry}"
main_dataset_name="$(get_field_from_entry "${main_entry}" 1)"
main_dataset_releasename="$(get_field_from_entry "${main_entry}" 4)"
# grep -v errcode != 0 if there is no match. || true to not fail with -e
other_entries="$(echo "${entries}" | grep -v "${main_entry}" || true)"
history_entries_meta "${other_entries}" "${main_dataset_name}" "${main_dataset_releasename}"
done
}
# Print the configuration part common to all sections
# Note:
# If 10_linux runs these part will be defined twice in grub configuration
print_menu_prologue() {
cat << 'EOF'
function gfxmode {
set gfxpayload="${1}"
EOF
if [ "${vt_handoff}" = 1 ]; then
cat << 'EOF'
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=1
else
set vt_handoff=
fi
EOF
fi
cat << EOF
}
EOF
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
GRUB_GFXPAYLOAD_LINUX="${GRUB_GFXPAYLOAD_LINUX:-}"
if [ "${GRUB_GFXPAYLOAD_LINUX}" != "" ] || [ "${gfxpayload_dynamic}" = 0 ]; then
echo "set linux_gfx_mode=${GRUB_GFXPAYLOAD_LINUX}"
else
cat << EOF
if [ "\${recordfail}" != 1 ]; then
if [ -e \${prefix}/gfxblacklist.txt ]; then
if hwmatch \${prefix}/gfxblacklist.txt 3; then
if [ \${match} = 0 ]; then
set linux_gfx_mode=keep
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=keep
fi
else
set linux_gfx_mode=text
fi
EOF
fi
cat << EOF
export linux_gfx_mode
EOF
}
# Cache for prepare_grub_to_access_device call
# $1: boot_device
# $2: submenu_level
prepare_grub_to_access_device_cached() {
local boot_device="$1"
local submenu_level="$2"
local boot_device_idx="$(echo ${boot_device} | tr '/' '_')"
cache_file="${ZFSTMP}/$(echo boot_device${boot_device_idx})"
if [ ! -f "${cache_file}" ]; then
set +u
echo "$(prepare_grub_to_access_device "${boot_device}")" > "${cache_file}"
set -u
for i in 0 1 2; do
submenu_indentation="$(printf %${i}s | tr " " "${grub_tab}")"
sed "s/^/${submenu_indentation} /" "${cache_file}" > "${cache_file}--${i}"
done
fi
cat "${cache_file}--${submenu_level}"
}
# Print a grub menu entry
zfs_linux_entry () {
submenu_level="$1"
title="$2"
type="$3"
dataset="$4"
boot_device="$5"
initrd="$6"
kernel="$7"
kernel_version="$8"
kernel_additional_args="${9:-}"
boot_devices="${10:-}"
submenu_indentation="$(printf %${submenu_level}s | tr " " "${grub_tab}")"
echo "${submenu_indentation}menuentry '$(echo "${title}" | grub_quote)' ${CLASS} \${menuentry_id_option} 'gnulinux-${dataset}-${kernel_version}' {"
if [ "${quick_boot}" = 1 ]; then
echo "${submenu_indentation} recordfail"
fi
if [ "${type}" != "recovery" ] ; then
GRUB_SAVEDEFAULT=${GRUB_SAVEDEFAULT:-}
default_entry="$(save_default_entry)"
if [ -n "${default_entry}" ]; then
echo "${submenu_indentation} ${default_entry}"
fi
fi
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "${GRUB_GFXPAYLOAD_LINUX}" = "" ]; then
echo "${submenu_indentation} load_video"
else
if [ "${GRUB_GFXPAYLOAD_LINUX}" != "text" ]; then
echo "${submenu_indentation} load_video"
fi
fi
if ([ "${ubuntu_recovery}" = 0 ] || [ "${type}" != "recovery" ]) && \
([ "${GRUB_GFXPAYLOAD_LINUX}" != "" ] || [ "${gfxpayload_dynamic}" = 1 ]); then
echo "${submenu_indentation} gfxmode \${linux_gfx_mode}"
fi
echo "${submenu_indentation} insmod gzio"
echo "${submenu_indentation} if [ \"\${grub_platform}\" = xen ]; then insmod xzio; insmod lzopio; fi"
if [ -n "$boot_devices" ]; then
for device in ${boot_devices}; do
echo "${submenu_indentation} if [ "${boot_device}" = "${device}" ]; then"
echo "$(prepare_grub_to_access_device_cached "${device}" $(( submenu_level +1 )) )"
echo "${submenu_indentation} fi"
done
else
echo "$(prepare_grub_to_access_device_cached "${boot_device}" "${submenu_level}")"
fi
if [ "${quiet_boot}" = 0 ] || [ "${type}" != simple ]; then
echo "${submenu_indentation} echo $(gettext_printf "Loading Linux %s ..." ${kernel_version} | grub_quote)"
fi
linux_default_args="${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
if [ ${type} = "recovery" ]; then
linux_default_args="${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}"
fi
echo "${submenu_indentation} linux ${kernel} root=ZFS=${dataset} ro ${linux_default_args} ${kernel_additional_args}"
if [ "${quiet_boot}" = 0 ] || [ "${type}" != simple ]; then
echo "${submenu_indentation} echo '$(gettext_printf "Loading initial ramdisk ..." | grub_quote)'"
fi
echo "${submenu_indentation} initrd ${initrd}"
echo "${submenu_indentation}}"
}
# Generate a GRUB Menu from menu meta data
# $1 menu metadata
generate_grub_menu() {
local menu_metadata="$1"
local last_section=""
local main_dataset_name=""
local main_dataset=""
local have_zsys=""
if [ -z "${menu_metadata}" ]; then
return
fi
CLASS="--class gnu-linux --class gnu --class os"
if [ "${GRUB_DISTRIBUTOR}" = "" ] ; then
OS=GNU/Linux
else
case ${GRUB_DISTRIBUTOR} in
Ubuntu|Kubuntu)
OS="${GRUB_DISTRIBUTOR}"
;;
*)
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
;;
esac
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1 | LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
fi
if [ -x /lib/recovery-mode/recovery-menu ]; then
GRUB_CMDLINE_LINUX_RECOVERY=recovery
else
GRUB_CMDLINE_LINUX_RECOVERY=single
fi
if [ "${ubuntu_recovery}" = 1 ]; then
GRUB_CMDLINE_LINUX_RECOVERY="${GRUB_CMDLINE_LINUX_RECOVERY} nomodeset"
fi
if [ "${vt_handoff}" = 1 ]; then
for word in ${GRUB_CMDLINE_LINUX_DEFAULT}; do
if [ "${word}" = splash ]; then
GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT} \${vt_handoff}"
fi
done
fi
print_menu_prologue
cat<<'EOF'
function zsyshistorymenu {
# $1: root dataset (eg rpool/ROOT/ubuntu_2zhm07@autozsys_k56fr6)
# $2: boot device id (eg 411f29ce1557bfed)
# $3: initrd (eg /BOOT/ubuntu_2zhm07@autozsys_k56fr6/initrd.img-5.4.0-21-generic)
# $4: kernel (eg /BOOT/ubuntu_2zhm07@autozsys_k56fr6/vmlinuz-5.4.0-21-generic)
# $5: kernel_version (eg 5.4.0-21-generic)
set root_dataset="${1}"
set boot_device="${2}"
set initrd="${3}"
set kernel="${4}"
set kversion="${5}"
EOF
boot_devices=$(echo "${menu_metadata}" | cut -d"$(printf '\t')" -f6 | sort -u)
title=$(gettext_printf "Revert system only")
zfs_linux_entry 1 "${title}" "simple" '${root_dataset}' '${boot_device}' '${initrd}' '${kernel}' '${kversion}' '' "${boot_devices}"
title="$(gettext_printf "Revert system and user data")"
zfs_linux_entry 1 "${title}" "simple" '${root_dataset}' '${boot_device}' '${initrd}' '${kernel}' '${kversion}' 'zsys-revert=userdata' "${boot_devices}"
GRUB_DISABLE_RECOVERY="${GRUB_DISABLE_RECOVERY:-}"
if [ "${GRUB_DISABLE_RECOVERY}" != "true" ]; then
title="$(gettext_printf "Revert system only (%s)" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
zfs_linux_entry 1 "${title}" "recovery" '${root_dataset}' '${boot_device}' '${initrd}' '${kernel}' '${kversion}' '' "${boot_devices}"
title="$(gettext_printf "Revert system and user data (%s)" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
zfs_linux_entry 1 "${title}" "recovery" '${root_dataset}' '${boot_device}' '${initrd}' '${kernel}' '${kversion}' 'zsys-revert=userdata' "${boot_devices}"
fi
echo "}"
echo
# IFS is set to TAB (ASCII 0x09)
echo "${menu_metadata}" |
{
at_least_one_entry=0
have_zsys="$(which zsysd || true)"
while IFS="$(printf '\t')" read -r machineid iszsys section name dataset device initrd kernel opt; do
# Disable history for non zsys system or if systems is a zsys one and zsys isn't installed.
# In pure zfs systems, we identified multiple issues due to the mount generator
# in upstream zfs which makes it incompatible. Don't show history for now.
if [ "${section}" = "history" ]; then
if [ "${iszsys}" != "yes" ] || [ "${iszsys}" = "yes" -a -z "${have_zsys}" ]; then
continue
fi
fi
if [ "${last_section}" != "${section}" -a -n "${last_section}" ]; then
# Close previous section wrapper
if [ "${last_section}" != "main" ]; then
echo "}" # Add grub_tabs
at_least_one_entry=0
fi
fi
case "${section}" in
main)
title="${name}"
main_dataset_name="${name}"
main_dataset="${dataset}"
kernel_version=$(basename "${kernel}" | sed -e "s,^[^0-9]*-,,g")
zfs_linux_entry 0 "${title}" "simple" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}"
at_least_one_entry=1
;;
advanced)
# normal and recovery entries for a given kernel
if [ "${last_section}" != "${section}" ]; then
echo "submenu '$(gettext_printf "Advanced options for %s" "${main_dataset_name}" | grub_quote)' \${menuentry_id_option} 'gnulinux-advanced-${main_dataset}' {"
fi
last_booted_kernel_marker=""
if [ "${opt}" = "true" ]; then
last_booted_kernel_marker="* "
fi
kernel_version=$(basename "${kernel}" | sed -e "s,^[^0-9]*-,,g")
title="$(gettext_printf "%s%s, with Linux %s" "${last_booted_kernel_marker}" "${name}" "${kernel_version}")"
zfs_linux_entry 1 "${title}" "advanced" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}"
GRUB_DISABLE_RECOVERY=${GRUB_DISABLE_RECOVERY:-}
if [ "${GRUB_DISABLE_RECOVERY}" != "true" ]; then
title="$(gettext_printf "%s%s, with Linux %s (%s)" "${last_booted_kernel_marker}" "${name}" "${kernel_version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
zfs_linux_entry 1 "${title}" "recovery" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}"
fi
at_least_one_entry=1
;;
history)
# Revert to a snapshot
# revert system, revert system and user data and associated recovery entries
if [ "${last_section}" != "${section}" ]; then
echo "submenu '$(gettext_printf "History for %s" "${main_dataset_name}" | grub_quote)' \${menuentry_id_option} 'gnulinux-history-${main_dataset}' {"
fi
if [ "${iszsys}" = "yes" ]; then
title="$(gettext_printf "Revert to %s" "${name}" | grub_quote)"
else
title="$(gettext_printf "Boot on %s" "${name}" | grub_quote)"
fi
echo " submenu '${title}' \${menuentry_id_option} 'gnulinux-history-${dataset}' {"
kernel_version=$(basename "${kernel}" | sed -e "s,^[^0-9]*-,,g")
# Zsys only: let revert system without destroying snapshots
if [ "${iszsys}" = "yes" ]; then
echo "${grub_tab}${grub_tab}zsyshistorymenu" \"${dataset}\" \"${device}\" \"${initrd}\" \"${kernel}\" \"${kernel_version}\"
# Non-zsys: boot temporarly on snapshots or rollback (destroying intermediate snapshots)
else
title="$(gettext_printf "One time boot")"
zfs_linux_entry 2 "${title}" "simple" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}"
GRUB_DISABLE_RECOVERY="${GRUB_DISABLE_RECOVERY:-}"
if [ "${GRUB_DISABLE_RECOVERY}" != "true" ]; then
title="$(gettext_printf "One time boot (%s)" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
zfs_linux_entry 2 "${title}" "recovery" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}"
fi
title="$(gettext_printf "Revert system (all intermediate snapshots will be destroyed)")"
zfs_linux_entry 2 "${title}" "simple" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}" "rollback=yes"
fi
echo " }"
at_least_one_entry=1
;;
*)
grub_warn "unknown section: ${section}. Ignoring entry ${name} for ${dataset}"
;;
esac
last_section="${section}"
done
if [ "${at_least_one_entry}" -eq 1 ]; then
echo "}"
fi
}
}
# don't add trailing newline of variable is empty
# $1: content to write
# $2: destination file
trailing_newline_if_not_empty() {
content="$1"
dest="$2"
if [ -z "${content}" ]; then
rm -f "${dest}"
touch "${dest}"
return
fi
echo "${content}" > "${dest}"
}
GRUB_LINUX_ZFS_TEST="${GRUB_LINUX_ZFS_TEST:-}"
case "${GRUB_LINUX_ZFS_TEST}" in
bootlist)
# Import all available pools on the system and return imported list
imported_pools=$(import_pools)
boot_list="$(bootlist ${MNTDIR})"
trailing_newline_if_not_empty "${boot_list}" "${GRUB_LINUX_ZFS_TEST_OUTPUT}"
break
;;
metamenu)
boot_list="$(cat ${GRUB_LINUX_ZFS_TEST_INPUT})"
menu_metadata="$(generate_grub_menu_metadata "${boot_list}")"
trailing_newline_if_not_empty "${menu_metadata}" "${GRUB_LINUX_ZFS_TEST_OUTPUT}"
break
;;
grubmenu)
menu_metadata="$(cat ${GRUB_LINUX_ZFS_TEST_INPUT})"
grub_menu=$(generate_grub_menu "${menu_metadata}")
trailing_newline_if_not_empty "${grub_menu}" "${GRUB_LINUX_ZFS_TEST_OUTPUT}"
break
;;
*)
# Import all available pools on the system and return imported list
imported_pools=$(import_pools)
# Generate the complete list of boot entries
boot_list="$(bootlist ${MNTDIR})"
# Create boot menu meta data from the list of boot entries
menu_metadata="$(generate_grub_menu_metadata "${boot_list}")"
# Create boot menu meta data from the list of boot entries
grub_menu="$(generate_grub_menu "${menu_metadata}")"
if [ -n "${grub_menu}" ]; then
# We want the trailing newline as a marker will be added
echo "${grub_menu}"
fi
;;
esac
set -e
# grub-mkconfig helper script.
# Copyright (C) 2019 Canonical Ltd.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
prefix="/usr"
datarootdir="/usr/share"
ubuntu_recovery="1"
quiet_boot="1"
quick_boot="1"
gfxpayload_dynamic="1"
vt_handoff="1"
. "${pkgdatadir}/grub-mkconfig_lib"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
set -u
## Skip early if zfs utils isn't installed (instead of failing on first zpool list)
if ! `which zfs >/dev/null 2>&1`; then
exit 0
fi
imported_pools=""
MNTDIR="$(mktemp -d ${TMPDIR:-/tmp}/zfsmnt.XXXXXX)"
ZFSTMP="$(mktemp -d ${TMPDIR:-/tmp}/zfstmp.XXXXXX)"
RC=0
on_exit() {
# Restore initial zpool import state
for pool in ${imported_pools}; do
zpool export "${pool}"
done
mountpoint -q "${MNTDIR}" && umount "${MNTDIR}" || true
rmdir "${MNTDIR}"
rm -rf "${ZFSTMP}"
exit "${RC}"
}
trap on_exit EXIT INT QUIT ABRT PIPE TERM
# List ONLINE and DEGRADED pools
import_pools() {
# We have to ignore zpool import output, as potentially multiple / will be available,
# and we need to autodetect all zpools this way with their real mountpoints.
local initial_pools="$(zpool list | awk '{if (NR>1) print $1}')"
local all_pools=""
local imported_pools=""
local err=""
set +e
err="$(zpool import -f -a -o cachefile=none -o readonly=on -N 2>&1)"
# Only print stderr if the command returned an error
# (it can echo "No zpool to import" with success, which we don't want)
if [ $? -ne 0 ]; then
echo "Some pools couldn't be imported and will be ignored:\n${err}" >&2
fi
set -e
all_pools="$(zpool list | awk '{if (NR>1) print $1}')"
for pool in ${all_pools}; do
if echo "${initial_pools}" | grep -wq "${pool}"; then
continue
fi
imported_pools="${imported_pools} ${pool}"
done
echo "${imported_pools}"
}
# List all the dataset with a root mountpoint
get_root_datasets() {
local pools="$(zpool list | awk '{if (NR>1) print $1}')"
for p in ${pools}; do
local rel_pool_root=$(zpool get -H altroot ${p} | awk '{print $3}')
if [ "${rel_pool_root}" = "-" ]; then
rel_pool_root="/"
fi
zfs list -H -o name,canmount,mountpoint -t filesystem | grep -E '^'"${p}"'(\s|/[[:print:]]*\s)(on|noauto)\s'"${rel_pool_root}"'$' | awk '{print $1}'
done
}
# find if given datasets can be mounted for directory and return its path (snapshot or real path)
# $1 is our current dataset name
# $2 directory path we look for (cannot contains /)
# $3 is the temporary mount directory to use
# $4 is the optional snapshot name
# return path for directory (which can be a mountpoint)
validate_system_dataset() {
local dataset="$1"
local directory="$2"
local mntdir="$3"
local snapshot_name="$4"
local mount_path="${mntdir}/${directory}"
if ! zfs list "${dataset}" >/dev/null 2>&1; then
return
fi
if ! mount -o noatime,zfsutil -t zfs "${dataset}" "${mount_path}"; then
grub_warn "Failed to find a valid directory '${directory}' for dataset '${dataset}@${snapshot_name}'. Ignoring"
return
fi
local candidate_path="${mount_path}"
if [ -n "${snapshot_name}" ]; then
# WORKAROUND a bug https://github.com/zfsonlinux/zfs/issues/9958
# Reading the content of a snapshot fails if it is not the first mount
# for a given dataset
first_mntdir=$(awk '{if ($1 == "'${dataset}'") {print $2; exit;}}' /proc/mounts)
if [ "${first_mntdir}" = "/" ]; then
# prevents // on candidate_path
first_mntdir=""
fi
candidate_path="${first_mntdir}/.zfs/snapshot/${snapshot_name}"
fi
if [ -n "$(ls ${candidate_path} 2>/dev/null)" ]; then
echo "${candidate_path}"
return
else
mountpoint -q "${mount_path}" && umount "${mount_path}" || true
fi
}
# Detect system directory relevant to the other, trying to find the ones associated on the current dataset or snapshot/
# System directory should be at most a direct child dataset of main datasets (no recursivity)
# We can fallback trying other zfs pools if no match has been found.
# $1 is our current dataset name (which can have @snapshot name)
# $2 directory path we look for (cannot contains /)
# $3 restrict_to_same_pool (true|false) force looking for dataset with the same basename in the current dataset pool only
# $4 is the temporary mount directory to use
# $5 is the optional etc directory (if not $2 is not etc itself)
# return path for directory (which can be a mountpoint)
get_system_directory() {
local dataset_path="$1"
local directory="$2"
local restrict_to_same_pool="$3"
local mntdir="$4"
local etc_dir="$5"
if [ -z "${etc_dir}" ]; then
etc_dir="${mntdir}/etc"
fi
local candidate_path="${mntdir}/${directory}"
# 1. Look for /etc/fstab first (which will mount even on top of non empty $directory)
local mounted_fstab_entry="false"
if [ -f "${etc_dir}/fstab" ]; then
mount_args=$(awk '/^[^#].*[ \t]\/'"${directory}"'[ \t]/ {print "-t", $3, $1}' "${etc_dir}/fstab")
if [ -n "${mount_args}" ]; then
mounted_fstab_entry="true"
mount -o noatime ${mount_args} "${candidate_path}" || mounted_fstab_entry="false"
fi
fi
# If directory isn't empty. Only count if coming from /etc/fstab. Will be
# handled below otherwise as we are interested in potential snapshots.
if [ "${mounted_fstab_entry}" = "true" -a -n "$(ls ${candidate_path} 2>/dev/null)" ]; then
echo "${candidate_path}"
return
fi
# 2. Handle zfs case, which can be a snapshots.
local base_dataset_path="${dataset_path}"
local snapshot_name=""
# For snapshots we extract the parent dataset
if echo "${dataset_path}" | grep -q '@'; then
base_dataset_path=$(echo "${dataset_path}" | cut -d '@' -f1)
snapshot_name=$(echo "${dataset_path}" | cut -d '@' -f2)
fi
base_dataset_name="${base_dataset_path##*/}"
base_pool="$(echo "${base_dataset_path}" | cut -d'/' -f1)"
# 2.a) Look for child dataset included in base dataset, which needs to hold same snapshot if any
candidate_path=$(validate_system_dataset "${base_dataset_path}/${directory}" "${directory}" "${mntdir}" "${snapshot_name}")
if [ -n "${candidate_path}" ]; then
echo "${candidate_path}"
return
fi
# 2.b) Look for current dataset (which is already mounted as /)
candidate_path="${mntdir}/${directory}"
if [ -n "${snapshot_name}" ]; then
# WORKAROUND a bug https://github.com/zfsonlinux/zfs/issues/9958
# Reading the content of a snapshot fails if it is not the first mount
# for a given dataset
first_mntdir=$(awk '{if ($1 == "'${base_dataset_path}'") {print $2; exit;}}' /proc/mounts)
if [ "${first_mntdir}" = "/" ]; then
# prevents // on candidate_path
first_mntdir=""
fi
candidate_path="${first_mntdir}/.zfs/snapshot/${snapshot_name}/${directory}"
fi
if [ -n "$(ls ${candidate_path} 2>/dev/null)" ]; then
echo "${candidate_path}"
return
fi
# 2.c) Look for every datasets in every pool which isn't the current dataset which holds:
# - the same dataset name (last section) than our base_dataset_name
# - mountpoint=directory
# - canmount!=off
all_same_base_dataset_name="$(zfs list -H -t filesystem -o name,canmount | awk '/^[^ ]+\/'"${base_dataset_name}"'[ \t](on|noauto)/ {print $1}') "
# order by local pool datasets first
current_pool_same_base_datasets=""
other_pools_same_base_datasets=""
root_pool=$(echo "${dataset_path%%/*}")
for d in ${all_same_base_dataset_name}; do
cur_dataset_pool=$(echo "${d%%/*}")
if echo "${cur_dataset_pool}" | grep -wq "${root_pool}" 2>/dev/null ; then
current_pool_same_base_datasets="${current_pool_same_base_datasets} ${d}"
else
other_pools_same_base_datasets="${other_pools_same_base_datasets} ${d}"
fi
done
ordered_same_base_datasets="${current_pool_same_base_datasets} ${other_pools_same_base_datasets}"
if [ "${restrict_to_same_pool}" = "true" ]; then
ordered_same_base_datasets="${current_pool_same_base_datasets}"
fi
# now, loop over them
for d in ${ordered_same_base_datasets}; do
cur_dataset_pool=$(echo "${d%%/*}")
rel_pool_root=$(zpool get -H altroot ${cur_dataset_pool} | awk '{print $3}')
if [ "${rel_pool_root}" = "-" ]; then
rel_pool_root=""
fi
# check mountpoint match
candidate_dataset=$(zfs get -H mountpoint ${d} | grep -E "mountpoint\s${rel_pool_root}/${directory}\s" | awk '{print $1}')
if [ -z "${candidate_dataset}" ]; then
continue
fi
candidate_path=$(validate_system_dataset "${candidate_dataset}" "${directory}" "${mntdir}" "${snapshot_name}")
if [ -n "${candidate_path}" ]; then
echo "${candidate_path}"
return
fi
done
# 2.d) If we didn't find anything yet: check for persistent datasets corresponding to our mountpoint, with canmount=on without any snapshot associated:
# Note: we go over previous datasets as well, but this is ok, as we didn't include them before.
all_mountable_datasets="$(zfs list -t filesystem -o name,canmount | awk '/^[^ ]+[ \t]+on/ {print $1}')"
# order by local pool datasets first
current_pool_datasets=""
other_pools_datasets=""
root_pool=$(echo "${dataset_path%%/*}")
for d in ${all_mountable_datasets}; do
cur_dataset_pool=$(echo "${d%%/*}")
if echo "${cur_dataset_pool}" | grep -wq "${root_pool}" 2>/dev/null ; then
current_pool_datasets="${current_pool_datasets} ${d}"
else
other_pools_datasets="${other_pools_datasets} ${d}"
fi
done
ordered_datasets="${current_pool_datasets} ${other_pools_datasets}"
if [ "${restrict_to_same_pool}" = "true" ]; then
ordered_datasets="${current_pool_datasets}"
fi
for d in ${ordered_datasets}; do
cur_dataset_pool=$(echo "${d%%/*}")
rel_pool_root=$(zpool get -H altroot ${cur_dataset_pool} | awk '{print $3}')
if [ "${rel_pool_root}" = "-" ]; then
rel_pool_root=""
fi
# check mountpoint match
candidate_dataset=$(zfs get -H mountpoint ${d} | grep -E "mountpoint\s${rel_pool_root}/${directory}\s" | awk '{print $1}')
if [ -z "${candidate_dataset}" ]; then
continue
fi
candidate_path=$(validate_system_dataset "${d}" "${directory}" "${mntdir}" "")
if [ -n "${candidate_path}" ]; then
echo "${candidate_path}"
return
fi
done
grub_warn "Failed to find a valid directory '${directory}' for dataset '${dataset_path}'. Ignoring"
return
}
# Try our default layout bpool as a prefered layout (fast path)
# This is get_system_directory for boot optimized for our default installation layout
# $1 is our current dataset name (which can have @snapshot name)
# $2 is the temporary mount directory to use
# return path for directory (which can be a mountpoint) if found
try_default_layout_bpool() {
local root_dataset_path="$1"
local mntdir="$2"
dataset_basename="${root_dataset_path##*/}"
candidate_dataset="bpool/BOOT/${dataset_basename}"
dataset_properties="$(zfs get -H mountpoint,canmount ${candidate_dataset} | cut -f3 | paste -sd ' ')"
if [ -z "${dataset_properties}" ]; then
return
fi
rel_pool_root=$(zpool get -H altroot bpool | awk '{print $3}')
if [ "${rel_pool_root}" = "-" ]; then
rel_pool_root=""
fi
snapshot_name="${dataset_basename##*@}"
[ "${snapshot_name}" = "${dataset_basename}" ] && snapshot_name=""
if [ -z "${snapshot_name}" ]; then
if ! echo "${dataset_properties}" | grep -Eq "${rel_pool_root}/boot (on|noauto)"; then
return
fi
else
candidate_dataset=$(echo "${candidate_dataset}" | cut -d '@' -f1)
fi
validate_system_dataset "${candidate_dataset}" "boot" "${mntdir}" "${snapshot_name}"
}
# Return if secure boot is enabled on that system
is_secure_boot_enabled() {
if LANG=C mokutil --sb-state 2>/dev/null | grep -qi enabled; then
echo "true"
return
fi
echo "false"
return
}
# Given a filesystem or snapshot dataset, returns dataset|machine id|pretty name|last used
# $1 is dataset we want information from
# $2 is the temporary mount directory to use
get_dataset_info() {
local dataset="$1"
local mntdir="$2"
local base_dataset="${dataset}"
local etc_dir="${mntdir}/etc"
local is_snapshot="false"
# For snapshot we extract the parent dataset
if echo "${dataset}" | grep -q '@'; then
base_dataset=$(echo "${dataset}" | cut -d '@' -f1)
is_snapshot="true"
fi
mount -o noatime,zfsutil -t zfs "${base_dataset}" "${mntdir}"
# read machine-id/os-release from /etc
etc_dir=$(get_system_directory "${dataset}" "etc" "true" "${mntdir}" "")
if [ -z "${etc_dir}" ]; then
grub_warn "Ignoring ${dataset}"
mountpoint -q "${mntdir}/etc" && umount "${mntdir}/etc" || true
umount "${mntdir}"
return
fi
machine_id=""
if [ -f "${etc_dir}/machine-id" ]; then
machine_id=$(cat "${etc_dir}/machine-id")
fi
# We have to use a random temporary id if we don't have any machine-id file or if this one is empty
# (mostly the case of new installations before first boot).
# Let's use the dataset name directly for this.
# Consequence is that all datasets are then separated.
if [ -z "${machine_id}" ]; then
machine_id="${dataset}"
fi
pretty_name=$(. "${etc_dir}/os-release" && echo "${PRETTY_NAME}")
mountpoint -q "${mntdir}/etc" && umount "${mntdir}/etc" || true
# read available kernels from /boot
boot_dir="$(try_default_layout_bpool "${dataset}" "${mntdir}")"
if [ -z "${boot_dir}" ]; then
boot_dir=$(get_system_directory "${dataset}" "boot" "false" "${mntdir}" "${etc_dir}")
fi
if [ -z "${boot_dir}" ]; then
grub_warn "Ignoring ${dataset}"
mountpoint -q "${mntdir}/boot" && umount "${mntdir}/boot" || true
umount "${mntdir}"
return
fi
machine="$(uname -m)"
case "${machine}" in
i?86) GENKERNEL_ARCH="x86" ;;
mips|mips64) GENKERNEL_ARCH="mips" ;;
mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
arm*) GENKERNEL_ARCH="arm" ;;
*) GENKERNEL_ARCH="${machine}" ;;
esac
initrd_list=""
kernel_list=""
for linux in $(find "${boot_dir}" -maxdepth 1 -type f -regex '.*/\(vmlinuz\|vmlinux\|kernel\)-.*'|sort -V); do
if ! grub_file_is_not_garbage "${linux}" ; then
continue
fi
# Filters entry if efi/non efi.
# Note that for now we allow kernel without .efi.signed as those are signed kernel
# on ubuntu, loaded by the shim.
case "${linux}" in
*.efi.signed)
if [ "$(is_secure_boot_enabled)" = "false" ]; then
continue
fi
;;
esac
linux_basename=$(basename "${linux}")
linux_dirname=$(dirname "${linux}")
version=$(echo "${linux_basename}" | sed -e "s,^[^0-9]*-,,g")
alt_version=$(echo "${version}" | sed -e "s,\.old$,,g")
gettext_printf "Found linux image: %s in %s\n" "${linux_basename}" "${dataset}" >&2
initrd=""
for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
"initrd-${version}" "initramfs-${version}.img" \
"initrd.img-${alt_version}" "initrd-${alt_version}.img" \
"initrd-${alt_version}" "initramfs-${alt_version}.img" \
"initramfs-genkernel-${version}" \
"initramfs-genkernel-${alt_version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do
if test -e "${linux_dirname}/${i}" ; then
initrd="$i"
break
fi
done
if test -z "${initrd}" ; then
grub_warn "Couldn't find any valid initrd for dataset ${dataset}."
continue
fi
gettext_printf "Found initrd image: %s in %s\n" "${initrd}" "${dataset}" >&2
rel_linux_dirname=$(make_system_path_relative_to_its_root "${linux_dirname}")
initrd_list="${rel_linux_dirname}/${initrd}|${initrd_list}"
kernel_list="${rel_linux_dirname}/${linux_basename}|${kernel_list}"
done
initrd_list="${initrd_list%|}"
kernel_list="${kernel_list%|}"
initrd_device=$(${grub_probe} --target=device "${boot_dir}" | head -1)
mountpoint -q "${mntdir}/boot" && umount "${mntdir}/boot" || true
# We needed to look in / for snapshots on root dataset, umount there before zfs lazily unmount it
case "${boot_dir}" in /boot/.zfs/snapshot/*)
umount "${boot_dir}" || true
;;
esac
# for zsys snapshots: we want to know which kernel we successful last booted with
last_booted_kernel=$(zfs get -H com.ubuntu.zsys:last-booted-kernel "${dataset}" | awk '{print $3}')
# snapshot: last_used is dataset creation time
if [ "${is_snapshot}" = "true" ]; then
last_used="$(zfs get -pH creation "${dataset}" | awk -F '\t' '{print $3}')"
# otherwise, last_used is manually marked at boot/shutdown on a root dataset for zsys
else
# if current system, take current time
if zfs mount | awk '/[ \t]+\/$/ {print $1}' | grep -q ${dataset}; then
last_used=$(date +%s)
else
last_used=$(zfs get -H com.ubuntu.zsys:last-used "${dataset}" | awk '{print $3}')
# case of non zsys, or zsys without annotation, take /etc/machine-id stat (as we mounted with noatime).
# However, as systems can be relatime, if system is current mounted one, set current time (case of clone + reboot
# within the same d).
if [ "${last_used}" = "-" ]; then
last_used=$(stat --printf="%X" "${mntdir}/etc/os-release")
if [ -f "${mntdir}/etc/machine-id" ]; then
last_used=$(stat --printf="%X" "${mntdir}/etc/machine-id")
fi
fi
fi
fi
is_zsys=$(zfs get -H com.ubuntu.zsys:bootfs "${base_dataset}" | awk '{print $3}')
if [ -n "${initrd_list}" -a -n "${kernel_list}" ]; then
echo "${dataset}\t${is_zsys}\t${machine_id}\t${pretty_name}\t${last_used}\t${initrd_device}\t${initrd_list}\t${kernel_list}\t${last_booted_kernel}"
else
grub_warn "didn't find any valid initrd or kernel."
fi
umount "${mntdir}" || true
# We needed to look in / for snapshots on root dataset, umount the snapshot for etc before zfs lazily unmount it
case "${etc_dir}" in /.zfs/snapshot/*/etc)
snapshot_path="$(findmnt -n -o TARGET -T ${etc_dir})"
umount "${snapshot_path}" || true
;;
esac
}
# Scan available boot options and returns in a formatted list
# $1 is the temporary mount directory to use
bootlist() {
local mntdir="$1"
local boot_list=""
for dataset in $(get_root_datasets); do
# get information from current root dataset
boot_list="${boot_list}$(get_dataset_info ${dataset} ${mntdir})\n"
# get information from snapshots of this root dataset
for snapshot_dataset in $(zfs list -H -o name -t snapshot "${dataset}"); do
boot_list="${boot_list}$(get_dataset_info ${snapshot_dataset} ${mntdir})\n"
done
done
echo "${boot_list}"
}
# Order machine ids by last_used from their main entry
get_machines_sorted() {
local bootlist="$1"
local machineids="$(echo "${bootlist}" | awk '{print $3}' | sort -u)"
for machineid in ${machineids}; do
echo "${bootlist}" | awk 'BEGIN{FS="\t"} $1 !~ /.*@.*/ {print $5, $3}' | sort -nr | grep -E "[^^]\b${machineid}\b" | head -1
done | sort -nr | awk '{print $2}'
}
# Sort entries by last_used for a given machineid
sort_entries_for_machineid() {
local bootlist="$1"
local machineid="$2"
tab="$(printf '\t')"
echo "${bootlist}" | grep -E "[^^]\b${machineid}\b" | sort -k5,5r -k1,1 -t "${tab}"
}
# Return main entry index
get_main_entry() {
local entries="$1"
echo "${entries}" | awk 'BEGIN{FS="\t"} $1 !~ /.*@.*/ {print}' | head -1
}
# Return specific field at index from entry
get_field_from_entry() {
local entry="$1"
local index="$2"
echo "${entry}" | awk "BEGIN{FS=\"\t\"} {print \$$index}"
}
# Get the main entry metadata
main_entry_meta() {
local main_entry="$1"
initrd=$(get_field_from_entry "${main_entry}" 7 | cut -d'|' -f1)
kernel=$(get_field_from_entry "${main_entry}" 8 | cut -d'|' -f1)
# Take first element (most recent entry) which is not a snapshot
echo "${main_entry}" | awk "BEGIN{ FS=\"\t\"; OFS=\"\t\"} {print \$3, \$2, \"main\", \$4, \$1, \$6, \"$initrd\", \"$kernel\"}"
}
# Get advanced entries metadata
advanced_entries_meta() {
local main_entry="$1"
last_used_kernel="$(get_field_from_entry "${main_entry}" 9 )"
# We must align initrds with kernels.
# Adds initrds to the stack then pop them 1 by 1 as we process the kernels
set -- $(get_field_from_entry "${main_entry}" 7 | tr "|" " ")
for kernel in $(get_field_from_entry "${main_entry}" 8 | tr "|" " "); do
# get initrd and pop to the next one
initrd="$1"; shift
was_last_used_kernel="false"
kernel_basename=$(basename "${kernel}")
if [ "${kernel_basename}" = "${last_used_kernel}" ]; then
was_last_used_kernel="true"
fi
echo "${main_entry}" | awk "BEGIN{ FS=\"\t\"; OFS=\"\t\"} {print \$3, \$2, \"advanced\", \$4, \$1, \$6, \"$initrd\", \"$kernel\", \"$was_last_used_kernel\"}"
done
}
# Get history metadata
history_entries_meta() {
local entries="$1"
local main_dataset_name="$2"
local main_dataset_releasename="$3"
if [ -z "${entries}" ]; then
return
fi
# Traverse snapshots and clones
echo "${entries}" | while read entry; do
name=""
# Compute snapshot/filesystem dataset name
snap_dataset_name="$(get_field_from_entry "${entry}" 1)"
snapname="${snap_dataset_name##*@}"
# If, this is a clone, take what is after main_dataset_name
if [ "${snapname}" = "${snap_dataset_name}" ]; then
snapname="${snap_dataset_name##${main_dataset_name}_}"
# Handle manual user clone (not prefixed by "main_dataset_name")
snapname="${snapname##*/}"
fi
# We keep the snapname only if it is not only a zsys auto snapshot
if echo "${snapname}" | grep -q "^autozsys_"; then
snapname=""
fi
# We store the release only if it different from main dataset release (snapshot before a release upgrade)
releasename=$(get_field_from_entry "${entry}" 4)
if [ "${releasename}" = "${main_dataset_releasename}" ]; then
releasename=""
fi
# Snapshot date
foo="$(get_field_from_entry "${entry}" 5)"
snapdate="$(date -d @$(get_field_from_entry "${entry}" 5) "+%x @ %H:%M")"
# For snapshots/clones the name can have the following formats:
# <DATE>: autozsys, same release
# <OLD_RELEASE> on <DATE>: autozsys, different release
# <SNAPNAME> on <DATE>: Manual snapshot, same release
# <SNAPNAME>, <OLD_RELEASE> on <DATE>: Manual snapshot, different release
if [ "${snapname}" = "" -a "${releasename}" = "" ]; then
name="${snapdate}"
elif [ "${snapname}" = "" -a "${releasename}" != "" ]; then
name=$(gettext_printf "%s on %s" "${releasename}" "${snapdate}")
elif [ "${snapname}" != "" -a "${releasename}" = "" ]; then
name=$(gettext_printf "%s on %s" "${snapname}" "${snapdate}")
else # snapname != "" && releasename != ""
name=$(gettext_printf "%s, %s on %s" "${snapname}" "${releasename}" "${snapdate}")
fi
# Choose kernel and initrd if the snapshot was booted successfully on a specific kernel before
# Take latest by default if no match
initrd=$(get_field_from_entry "${entry}" 7 | cut -d'|' -f1)
kernel=$(get_field_from_entry "${entry}" 8 | cut -d'|' -f1)
last_used_kernel="$(get_field_from_entry "${entry}" 9)"
# We must align initrds with kernels.
# Adds initrds to the stack then pop them 1 by 1 as we process the kernels
set -- $(get_field_from_entry "${entry}" 7 | tr "|" " ")
for k in $(get_field_from_entry "${entry}" 8|tr "|" " "); do
# get initrd and pop to the next one
candidate_initrd="$1"; shift
kernel_basename=$(basename "${k}")
if [ "${kernel_basename}" = "${last_used_kernel}" ]; then
kernel="${k}"
initrd="${candidate_initrd}"
break
fi
done
echo "${entry}" | awk "BEGIN{ FS=\"\t\"; OFS=\"\t\"} {print \$3, \$2, \"history\", \"$name\", \$1, \$6, \"$initrd\", \"$kernel\"}"
done
}
# Generate metadata from a BOOTLIST that will subsequently used to generate
# the final grub menu entries
generate_grub_menu_metadata() {
local bootlist="$1"
# Sort machineids by last_used from their main entry
for machineid in $(get_machines_sorted "${bootlist}"); do
entries="$(sort_entries_for_machineid "${bootlist}" ${machineid})"
main_entry="$(get_main_entry "${entries}")"
if [ -z "$main_entry" ]; then
continue
fi
main_entry_meta "${main_entry}"
advanced_entries_meta "${main_entry}"
main_dataset_name="$(get_field_from_entry "${main_entry}" 1)"
main_dataset_releasename="$(get_field_from_entry "${main_entry}" 4)"
# grep -v errcode != 0 if there is no match. || true to not fail with -e
other_entries="$(echo "${entries}" | grep -v "${main_entry}" || true)"
history_entries_meta "${other_entries}" "${main_dataset_name}" "${main_dataset_releasename}"
done
}
# Print the configuration part common to all sections
# Note:
# If 10_linux runs these part will be defined twice in grub configuration
print_menu_prologue() {
cat << 'EOF'
function gfxmode {
set gfxpayload="${1}"
EOF
if [ "${vt_handoff}" = 1 ]; then
cat << 'EOF'
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=1
else
set vt_handoff=
fi
EOF
fi
cat << EOF
}
EOF
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
GRUB_GFXPAYLOAD_LINUX="${GRUB_GFXPAYLOAD_LINUX:-}"
if [ "${GRUB_GFXPAYLOAD_LINUX}" != "" ] || [ "${gfxpayload_dynamic}" = 0 ]; then
echo "set linux_gfx_mode=${GRUB_GFXPAYLOAD_LINUX}"
else
cat << EOF
if [ "\${recordfail}" != 1 ]; then
if [ -e \${prefix}/gfxblacklist.txt ]; then
if hwmatch \${prefix}/gfxblacklist.txt 3; then
if [ \${match} = 0 ]; then
set linux_gfx_mode=keep
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=keep
fi
else
set linux_gfx_mode=text
fi
EOF
fi
cat << EOF
export linux_gfx_mode
EOF
}
# Cache for prepare_grub_to_access_device call
# $1: boot_device
# $2: submenu_level
prepare_grub_to_access_device_cached() {
local boot_device="$1"
local submenu_level="$2"
local boot_device_idx="$(echo ${boot_device} | tr '/' '_')"
cache_file="${ZFSTMP}/$(echo boot_device${boot_device_idx})"
if [ ! -f "${cache_file}" ]; then
set +u
echo "$(prepare_grub_to_access_device "${boot_device}")" > "${cache_file}"
set -u
for i in 0 1 2; do
submenu_indentation="$(printf %${i}s | tr " " "${grub_tab}")"
sed "s/^/${submenu_indentation} /" "${cache_file}" > "${cache_file}--${i}"
done
fi
cat "${cache_file}--${submenu_level}"
}
# Print a grub menu entry
zfs_linux_entry () {
submenu_level="$1"
title="$2"
type="$3"
dataset="$4"
boot_device="$5"
initrd="$6"
kernel="$7"
kernel_version="$8"
kernel_additional_args="${9:-}"
boot_devices="${10:-}"
submenu_indentation="$(printf %${submenu_level}s | tr " " "${grub_tab}")"
echo "${submenu_indentation}menuentry '$(echo "${title}" | grub_quote)' ${CLASS} \${menuentry_id_option} 'gnulinux-${dataset}-${kernel_version}' {"
if [ "${quick_boot}" = 1 ]; then
echo "${submenu_indentation} recordfail"
fi
if [ "${type}" != "recovery" ] ; then
GRUB_SAVEDEFAULT=${GRUB_SAVEDEFAULT:-}
default_entry="$(save_default_entry)"
if [ -n "${default_entry}" ]; then
echo "${submenu_indentation} ${default_entry}"
fi
fi
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "${GRUB_GFXPAYLOAD_LINUX}" = "" ]; then
echo "${submenu_indentation} load_video"
else
if [ "${GRUB_GFXPAYLOAD_LINUX}" != "text" ]; then
echo "${submenu_indentation} load_video"
fi
fi
if ([ "${ubuntu_recovery}" = 0 ] || [ "${type}" != "recovery" ]) && \
([ "${GRUB_GFXPAYLOAD_LINUX}" != "" ] || [ "${gfxpayload_dynamic}" = 1 ]); then
echo "${submenu_indentation} gfxmode \${linux_gfx_mode}"
fi
echo "${submenu_indentation} insmod gzio"
echo "${submenu_indentation} if [ \"\${grub_platform}\" = xen ]; then insmod xzio; insmod lzopio; fi"
if [ -n "$boot_devices" ]; then
for device in ${boot_devices}; do
echo "${submenu_indentation} if [ "${boot_device}" = "${device}" ]; then"
echo "$(prepare_grub_to_access_device_cached "${device}" $(( submenu_level +1 )) )"
echo "${submenu_indentation} fi"
done
else
echo "$(prepare_grub_to_access_device_cached "${boot_device}" "${submenu_level}")"
fi
if [ "${quiet_boot}" = 0 ] || [ "${type}" != simple ]; then
echo "${submenu_indentation} echo $(gettext_printf "Loading Linux %s ..." ${kernel_version} | grub_quote)"
fi
linux_default_args="${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
if [ ${type} = "recovery" ]; then
linux_default_args="${GRUB_CMDLINE_LINUX_RECOVERY} ${GRUB_CMDLINE_LINUX}"
fi
echo "${submenu_indentation} linux ${kernel} root=ZFS=${dataset} ro ${linux_default_args} ${kernel_additional_args}"
if [ "${quiet_boot}" = 0 ] || [ "${type}" != simple ]; then
echo "${submenu_indentation} echo '$(gettext_printf "Loading initial ramdisk ..." | grub_quote)'"
fi
echo "${submenu_indentation} initrd ${initrd}"
echo "${submenu_indentation}}"
}
# Generate a GRUB Menu from menu meta data
# $1 menu metadata
generate_grub_menu() {
local menu_metadata="$1"
local last_section=""
local main_dataset_name=""
local main_dataset=""
local have_zsys=""
if [ -z "${menu_metadata}" ]; then
return
fi
CLASS="--class gnu-linux --class gnu --class os"
if [ "${GRUB_DISTRIBUTOR}" = "" ] ; then
OS=GNU/Linux
else
case ${GRUB_DISTRIBUTOR} in
Ubuntu|Kubuntu)
OS="${GRUB_DISTRIBUTOR}"
;;
*)
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
;;
esac
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1 | LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
fi
if [ -x /lib/recovery-mode/recovery-menu ]; then
GRUB_CMDLINE_LINUX_RECOVERY=recovery
else
GRUB_CMDLINE_LINUX_RECOVERY=single
fi
if [ "${ubuntu_recovery}" = 1 ]; then
GRUB_CMDLINE_LINUX_RECOVERY="${GRUB_CMDLINE_LINUX_RECOVERY} nomodeset"
fi
if [ "${vt_handoff}" = 1 ]; then
for word in ${GRUB_CMDLINE_LINUX_DEFAULT}; do
if [ "${word}" = splash ]; then
GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT} \${vt_handoff}"
fi
done
fi
print_menu_prologue
cat<<'EOF'
function zsyshistorymenu {
# $1: root dataset (eg rpool/ROOT/ubuntu_2zhm07@autozsys_k56fr6)
# $2: boot device id (eg 411f29ce1557bfed)
# $3: initrd (eg /BOOT/ubuntu_2zhm07@autozsys_k56fr6/initrd.img-5.4.0-21-generic)
# $4: kernel (eg /BOOT/ubuntu_2zhm07@autozsys_k56fr6/vmlinuz-5.4.0-21-generic)
# $5: kernel_version (eg 5.4.0-21-generic)
set root_dataset="${1}"
set boot_device="${2}"
set initrd="${3}"
set kernel="${4}"
set kversion="${5}"
EOF
boot_devices=$(echo "${menu_metadata}" | cut -d"$(printf '\t')" -f6 | sort -u)
title=$(gettext_printf "Revert system only")
zfs_linux_entry 1 "${title}" "simple" '${root_dataset}' '${boot_device}' '${initrd}' '${kernel}' '${kversion}' '' "${boot_devices}"
title="$(gettext_printf "Revert system and user data")"
zfs_linux_entry 1 "${title}" "simple" '${root_dataset}' '${boot_device}' '${initrd}' '${kernel}' '${kversion}' 'zsys-revert=userdata' "${boot_devices}"
GRUB_DISABLE_RECOVERY="${GRUB_DISABLE_RECOVERY:-}"
if [ "${GRUB_DISABLE_RECOVERY}" != "true" ]; then
title="$(gettext_printf "Revert system only (%s)" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
zfs_linux_entry 1 "${title}" "recovery" '${root_dataset}' '${boot_device}' '${initrd}' '${kernel}' '${kversion}' '' "${boot_devices}"
title="$(gettext_printf "Revert system and user data (%s)" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
zfs_linux_entry 1 "${title}" "recovery" '${root_dataset}' '${boot_device}' '${initrd}' '${kernel}' '${kversion}' 'zsys-revert=userdata' "${boot_devices}"
fi
echo "}"
echo
# IFS is set to TAB (ASCII 0x09)
echo "${menu_metadata}" |
{
at_least_one_entry=0
have_zsys="$(which zsysd || true)"
while IFS="$(printf '\t')" read -r machineid iszsys section name dataset device initrd kernel opt; do
# Disable history for non zsys system or if systems is a zsys one and zsys isn't installed.
# In pure zfs systems, we identified multiple issues due to the mount generator
# in upstream zfs which makes it incompatible. Don't show history for now.
if [ "${section}" = "history" ]; then
if [ "${iszsys}" != "yes" ] || [ "${iszsys}" = "yes" -a -z "${have_zsys}" ]; then
continue
fi
fi
if [ "${last_section}" != "${section}" -a -n "${last_section}" ]; then
# Close previous section wrapper
if [ "${last_section}" != "main" ]; then
echo "}" # Add grub_tabs
at_least_one_entry=0
fi
fi
case "${section}" in
main)
title="${name}"
main_dataset_name="${name}"
main_dataset="${dataset}"
kernel_version=$(basename "${kernel}" | sed -e "s,^[^0-9]*-,,g")
zfs_linux_entry 0 "${title}" "simple" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}"
at_least_one_entry=1
;;
advanced)
# normal and recovery entries for a given kernel
if [ "${last_section}" != "${section}" ]; then
echo "submenu '$(gettext_printf "Advanced options for %s" "${main_dataset_name}" | grub_quote)' \${menuentry_id_option} 'gnulinux-advanced-${main_dataset}' {"
fi
last_booted_kernel_marker=""
if [ "${opt}" = "true" ]; then
last_booted_kernel_marker="* "
fi
kernel_version=$(basename "${kernel}" | sed -e "s,^[^0-9]*-,,g")
title="$(gettext_printf "%s%s, with Linux %s" "${last_booted_kernel_marker}" "${name}" "${kernel_version}")"
zfs_linux_entry 1 "${title}" "advanced" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}"
GRUB_DISABLE_RECOVERY=${GRUB_DISABLE_RECOVERY:-}
if [ "${GRUB_DISABLE_RECOVERY}" != "true" ]; then
title="$(gettext_printf "%s%s, with Linux %s (%s)" "${last_booted_kernel_marker}" "${name}" "${kernel_version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
zfs_linux_entry 1 "${title}" "recovery" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}"
fi
at_least_one_entry=1
;;
history)
# Revert to a snapshot
# revert system, revert system and user data and associated recovery entries
if [ "${last_section}" != "${section}" ]; then
echo "submenu '$(gettext_printf "History for %s" "${main_dataset_name}" | grub_quote)' \${menuentry_id_option} 'gnulinux-history-${main_dataset}' {"
fi
if [ "${iszsys}" = "yes" ]; then
title="$(gettext_printf "Revert to %s" "${name}" | grub_quote)"
else
title="$(gettext_printf "Boot on %s" "${name}" | grub_quote)"
fi
echo " submenu '${title}' \${menuentry_id_option} 'gnulinux-history-${dataset}' {"
kernel_version=$(basename "${kernel}" | sed -e "s,^[^0-9]*-,,g")
# Zsys only: let revert system without destroying snapshots
if [ "${iszsys}" = "yes" ]; then
echo "${grub_tab}${grub_tab}zsyshistorymenu" \"${dataset}\" \"${device}\" \"${initrd}\" \"${kernel}\" \"${kernel_version}\"
# Non-zsys: boot temporarly on snapshots or rollback (destroying intermediate snapshots)
else
title="$(gettext_printf "One time boot")"
zfs_linux_entry 2 "${title}" "simple" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}"
GRUB_DISABLE_RECOVERY="${GRUB_DISABLE_RECOVERY:-}"
if [ "${GRUB_DISABLE_RECOVERY}" != "true" ]; then
title="$(gettext_printf "One time boot (%s)" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
zfs_linux_entry 2 "${title}" "recovery" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}"
fi
title="$(gettext_printf "Revert system (all intermediate snapshots will be destroyed)")"
zfs_linux_entry 2 "${title}" "simple" "${dataset}" "${device}" "${initrd}" "${kernel}" "${kernel_version}" "rollback=yes"
fi
echo " }"
at_least_one_entry=1
;;
*)
grub_warn "unknown section: ${section}. Ignoring entry ${name} for ${dataset}"
;;
esac
last_section="${section}"
done
if [ "${at_least_one_entry}" -eq 1 ]; then
echo "}"
fi
}
}
# don't add trailing newline of variable is empty
# $1: content to write
# $2: destination file
trailing_newline_if_not_empty() {
content="$1"
dest="$2"
if [ -z "${content}" ]; then
rm -f "${dest}"
touch "${dest}"
return
fi
echo "${content}" > "${dest}"
}
GRUB_LINUX_ZFS_TEST="${GRUB_LINUX_ZFS_TEST:-}"
case "${GRUB_LINUX_ZFS_TEST}" in
bootlist)
# Import all available pools on the system and return imported list
imported_pools=$(import_pools)
boot_list="$(bootlist ${MNTDIR})"
trailing_newline_if_not_empty "${boot_list}" "${GRUB_LINUX_ZFS_TEST_OUTPUT}"
break
;;
metamenu)
boot_list="$(cat ${GRUB_LINUX_ZFS_TEST_INPUT})"
menu_metadata="$(generate_grub_menu_metadata "${boot_list}")"
trailing_newline_if_not_empty "${menu_metadata}" "${GRUB_LINUX_ZFS_TEST_OUTPUT}"
break
;;
grubmenu)
menu_metadata="$(cat ${GRUB_LINUX_ZFS_TEST_INPUT})"
grub_menu=$(generate_grub_menu "${menu_metadata}")
trailing_newline_if_not_empty "${grub_menu}" "${GRUB_LINUX_ZFS_TEST_OUTPUT}"
break
;;
*)
# Import all available pools on the system and return imported list
imported_pools=$(import_pools)
# Generate the complete list of boot entries
boot_list="$(bootlist ${MNTDIR})"
# Create boot menu meta data from the list of boot entries
menu_metadata="$(generate_grub_menu_metadata "${boot_list}")"
# Create boot menu meta data from the list of boot entries
grub_menu="$(generate_grub_menu "${menu_metadata}")"
if [ -n "${grub_menu}" ]; then
# We want the trailing newline as a marker will be added
echo "${grub_menu}"
fi
;;
esac
LinuxMint 20 xfce не показывает меню grub после upgrade
20_linux_xen
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"
. "$pkgdatadir/grub-mkconfig_lib"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
CLASS="--class gnu-linux --class gnu --class os --class xen"
SUPPORTED_INITS="sysvinit:/lib/sysvinit/init systemd:/lib/systemd/systemd upstart:/sbin/upstart"
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
else
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
fi
# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
/dev/loop/*|/dev/loop[0-9])
GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
# We can't cope with devices loop-mounted from files here.
case ${GRUB_DEVICE} in
/dev/*) ;;
*) exit 0 ;;
esac
;;
esac
# Default to disabling partition uuid support to maintian compatibility with
# older kernels.
GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}
# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
# and mounting btrfs requires user space scanning, so force UUID in this case.
if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
|| ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
&& [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
|| ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
&& ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
|| ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
|| [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi
# Allow overriding GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT.
if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE}" ]; then
GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX_XEN_REPLACE}"
fi
if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}" ]; then
GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}"
fi
case x"$GRUB_FS" in
xbtrfs)
rootsubvol="`make_system_path_relative_to_its_root /`"
rootsubvol="${rootsubvol#/}"
if [ "x${rootsubvol}" != x ]; then
GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
fi;;
xzfs)
rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs%/}"
;;
esac
title_correction_code=
linux_entry ()
{
os="$1"
version="$2"
xen_version="$3"
type="$4"
args="$5"
xen_args="$6"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
if [ x$type != xsimple ] ; then
if [ x$type = xrecovery ] ; then
title="$(gettext_printf "%s, with Xen %s and Linux %s (%s)" "${os}" "${xen_version}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
elif [ "${type#init-}" != "$type" ] ; then
title="$(gettext_printf "%s, with Xen %s and Linux %s (%s)" "${os}" "${xen_version}" "${version}" "${type#init-}")"
else
title="$(gettext_printf "%s, with Xen %s and Linux %s" "${os}" "${xen_version}" "${version}")"
fi
replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
if [ x"Xen ${xen_version}>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")"
fi
echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'xen-gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
else
title="$(gettext_printf "%s, with Xen hypervisor" "${os}")"
echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'xen-gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
fi
if [ x$type != xrecovery ] ; then
save_default_entry | grub_add_tab | sed "s/^/$submenu_indentation/"
fi
if [ -z "${prepare_boot_cache}" ]; then
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)"
fi
printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
xmessage="$(gettext_printf "Loading Xen %s ..." ${xen_version})"
lmessage="$(gettext_printf "Loading Linux %s ..." ${version})"
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$xmessage" | grub_quote)'
if [ "\$grub_platform" = "pc" -o "\$grub_platform" = "" ]; then
xen_rm_opts=
else
xen_rm_opts="no-real-mode edd=off"
fi
${xen_loader} ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts}
echo '$(echo "$lmessage" | grub_quote)'
${module_loader} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args}
EOF
if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
message="$(gettext_printf "Loading initial ramdisk ...")"
initrd_path=
for i in ${initrd}; do
initrd_path="${initrd_path} ${rel_dirname}/${i}"
done
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
${module_loader} --nounzip $(echo $initrd_path)
EOF
fi
sed "s/^/$submenu_indentation/" << EOF
}
EOF
}
linux_list=
for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* /boot/kernel-*; do
if grub_file_is_not_garbage "$i"; then
basename=$(basename $i)
version=$(echo $basename | sed -e "s,^[^0-9]*-,,g")
dirname=$(dirname $i)
config=
for j in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
if test -e "${j}" ; then
config="${j}"
break
fi
done
if (grep -qx "CONFIG_XEN_DOM0=y" "${config}" 2> /dev/null || grep -qx "CONFIG_XEN_PRIVILEGED_GUEST=y" "${config}" 2> /dev/null); then linux_list="$linux_list $i" ; fi
fi
done
if [ "x${linux_list}" = "x" ] ; then
exit 0
fi
file_is_not_sym () {
case "$1" in
*/xen-syms-*)
return 1;;
*)
return 0;;
esac
}
xen_list=
for i in /boot/xen*; do
if grub_file_is_not_garbage "$i" && file_is_not_sym "$i" ; then xen_list="$xen_list $i" ; fi
done
prepare_boot_cache=
boot_device_id=
title_correction_code=
machine=`uname -m`
case "$machine" in
i?86) GENKERNEL_ARCH="x86" ;;
mips|mips64) GENKERNEL_ARCH="mips" ;;
mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
arm*) GENKERNEL_ARCH="arm" ;;
*) GENKERNEL_ARCH="$machine" ;;
esac
# Extra indentation to add to menu entries in a submenu. We're not in a submenu
# yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
submenu_indentation=""
is_top_level=true
while [ "x${xen_list}" != "x" ] ; do
list="${linux_list}"
current_xen=`version_find_latest $xen_list`
xen_basename=`basename ${current_xen}`
xen_dirname=`dirname ${current_xen}`
rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname`
xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"`
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
if [ "x$is_top_level" != xtrue ]; then
echo " submenu '$(gettext_printf "Xen hypervisor, version %s" "${xen_version}" | grub_quote)' \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {"
fi
if ($grub_file --is-arm64-efi $current_xen); then
xen_loader="xen_hypervisor"
module_loader="xen_module"
else
if ($grub_file --is-x86-multiboot2 $current_xen); then
xen_loader="multiboot2"
module_loader="module2"
else
xen_loader="multiboot"
module_loader="module"
fi
fi
initrd_early=
for i in ${GRUB_EARLY_INITRD_LINUX_STOCK} \
${GRUB_EARLY_INITRD_LINUX_CUSTOM}; do
if test -e "${xen_dirname}/${i}" ; then
initrd_early="${initrd_early} ${i}"
fi
done
while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`
gettext_printf "Found linux image: %s\n" "$linux" >&2
basename=`basename $linux`
dirname=`dirname $linux`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
initrd_real=
for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
"initrd-${version}" "initramfs-${version}.img" \
"initrd.img-${alt_version}" "initrd-${alt_version}.img" \
"initrd-${alt_version}" "initramfs-${alt_version}.img" \
"initramfs-genkernel-${version}" \
"initramfs-genkernel-${alt_version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}" ; do
if test -e "${dirname}/${i}" ; then
initrd_real="$i"
break
fi
done
initrd=
if test -n "${initrd_early}" || test -n "${initrd_real}"; then
initrd="${initrd_early} ${initrd_real}"
initrd_display=
for i in ${initrd}; do
initrd_display="${initrd_display} ${dirname}/${i}"
done
gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
fi
if test -z "${initrd_real}"; then
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \
|| [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then
linux_root_device_thisversion=${GRUB_DEVICE}
else
linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID}
fi
fi
if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
linux_entry "${OS}" "${version}" "${xen_version}" simple \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}"
submenu_indentation="$grub_tab$grub_tab"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
# TRANSLATORS: %s is replaced with an OS name
echo "submenu '$(gettext_printf "Advanced options for %s (with Xen hypervisor)" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
echo " submenu '$(gettext_printf "Xen hypervisor, version %s" "${xen_version}" | grub_quote)' \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {"
is_top_level=false
fi
linux_entry "${OS}" "${version}" "${xen_version}" advanced \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}"
for supported_init in ${SUPPORTED_INITS}; do
init_path="${supported_init#*:}"
if [ -x "${init_path}" ] && [ "$(readlink -f /sbin/init)" != "$(readlink -f "${init_path}")" ]; then
linux_entry "${OS}" "${version}" "${xen_version}" "init-${supported_init%%:*}" \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} init=${init_path}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}"
fi
done
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${version}" "${xen_version}" recovery \
"single ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}"
fi
list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
done
if [ x"$is_top_level" != xtrue ]; then
echo ' }'
fi
xen_list=`echo $xen_list | tr ' ' '\n' | fgrep -vx "$current_xen" | tr '\n' ' '`
done
# If at least one kernel was found, then we need to
# add a closing '}' for the submenu command.
if [ x"$is_top_level" != xtrue ]; then
echo '}'
fi
echo "$title_correction_code"
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
prefix="/usr"
exec_prefix="/usr"
datarootdir="/usr/share"
. "$pkgdatadir/grub-mkconfig_lib"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
CLASS="--class gnu-linux --class gnu --class os --class xen"
SUPPORTED_INITS="sysvinit:/lib/sysvinit/init systemd:/lib/systemd/systemd upstart:/sbin/upstart"
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
else
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
fi
# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
/dev/loop/*|/dev/loop[0-9])
GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
# We can't cope with devices loop-mounted from files here.
case ${GRUB_DEVICE} in
/dev/*) ;;
*) exit 0 ;;
esac
;;
esac
# Default to disabling partition uuid support to maintian compatibility with
# older kernels.
GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}
# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
# and mounting btrfs requires user space scanning, so force UUID in this case.
if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
|| ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
&& [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
|| ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
&& ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
|| ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
|| [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi
# Allow overriding GRUB_CMDLINE_LINUX and GRUB_CMDLINE_LINUX_DEFAULT.
if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE}" ]; then
GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX_XEN_REPLACE}"
fi
if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}" ]; then
GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}"
fi
case x"$GRUB_FS" in
xbtrfs)
rootsubvol="`make_system_path_relative_to_its_root /`"
rootsubvol="${rootsubvol#/}"
if [ "x${rootsubvol}" != x ]; then
GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
fi;;
xzfs)
rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs%/}"
;;
esac
title_correction_code=
linux_entry ()
{
os="$1"
version="$2"
xen_version="$3"
type="$4"
args="$5"
xen_args="$6"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
if [ x$type != xsimple ] ; then
if [ x$type = xrecovery ] ; then
title="$(gettext_printf "%s, with Xen %s and Linux %s (%s)" "${os}" "${xen_version}" "${version}" "$(gettext "${GRUB_RECOVERY_TITLE}")")"
elif [ "${type#init-}" != "$type" ] ; then
title="$(gettext_printf "%s, with Xen %s and Linux %s (%s)" "${os}" "${xen_version}" "${version}" "${type#init-}")"
else
title="$(gettext_printf "%s, with Xen %s and Linux %s" "${os}" "${xen_version}" "${version}")"
fi
replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
if [ x"Xen ${xen_version}>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")"
fi
echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'xen-gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
else
title="$(gettext_printf "%s, with Xen hypervisor" "${os}")"
echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'xen-gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
fi
if [ x$type != xrecovery ] ; then
save_default_entry | grub_add_tab | sed "s/^/$submenu_indentation/"
fi
if [ -z "${prepare_boot_cache}" ]; then
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)"
fi
printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
xmessage="$(gettext_printf "Loading Xen %s ..." ${xen_version})"
lmessage="$(gettext_printf "Loading Linux %s ..." ${version})"
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$xmessage" | grub_quote)'
if [ "\$grub_platform" = "pc" -o "\$grub_platform" = "" ]; then
xen_rm_opts=
else
xen_rm_opts="no-real-mode edd=off"
fi
${xen_loader} ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts}
echo '$(echo "$lmessage" | grub_quote)'
${module_loader} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args}
EOF
if test -n "${initrd}" ; then
# TRANSLATORS: ramdisk isn't identifier. Should be translated.
message="$(gettext_printf "Loading initial ramdisk ...")"
initrd_path=
for i in ${initrd}; do
initrd_path="${initrd_path} ${rel_dirname}/${i}"
done
sed "s/^/$submenu_indentation/" << EOF
echo '$(echo "$message" | grub_quote)'
${module_loader} --nounzip $(echo $initrd_path)
EOF
fi
sed "s/^/$submenu_indentation/" << EOF
}
EOF
}
linux_list=
for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* /boot/kernel-*; do
if grub_file_is_not_garbage "$i"; then
basename=$(basename $i)
version=$(echo $basename | sed -e "s,^[^0-9]*-,,g")
dirname=$(dirname $i)
config=
for j in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
if test -e "${j}" ; then
config="${j}"
break
fi
done
if (grep -qx "CONFIG_XEN_DOM0=y" "${config}" 2> /dev/null || grep -qx "CONFIG_XEN_PRIVILEGED_GUEST=y" "${config}" 2> /dev/null); then linux_list="$linux_list $i" ; fi
fi
done
if [ "x${linux_list}" = "x" ] ; then
exit 0
fi
file_is_not_sym () {
case "$1" in
*/xen-syms-*)
return 1;;
*)
return 0;;
esac
}
xen_list=
for i in /boot/xen*; do
if grub_file_is_not_garbage "$i" && file_is_not_sym "$i" ; then xen_list="$xen_list $i" ; fi
done
prepare_boot_cache=
boot_device_id=
title_correction_code=
machine=`uname -m`
case "$machine" in
i?86) GENKERNEL_ARCH="x86" ;;
mips|mips64) GENKERNEL_ARCH="mips" ;;
mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
arm*) GENKERNEL_ARCH="arm" ;;
*) GENKERNEL_ARCH="$machine" ;;
esac
# Extra indentation to add to menu entries in a submenu. We're not in a submenu
# yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
submenu_indentation=""
is_top_level=true
while [ "x${xen_list}" != "x" ] ; do
list="${linux_list}"
current_xen=`version_find_latest $xen_list`
xen_basename=`basename ${current_xen}`
xen_dirname=`dirname ${current_xen}`
rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname`
xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"`
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
if [ "x$is_top_level" != xtrue ]; then
echo " submenu '$(gettext_printf "Xen hypervisor, version %s" "${xen_version}" | grub_quote)' \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {"
fi
if ($grub_file --is-arm64-efi $current_xen); then
xen_loader="xen_hypervisor"
module_loader="xen_module"
else
if ($grub_file --is-x86-multiboot2 $current_xen); then
xen_loader="multiboot2"
module_loader="module2"
else
xen_loader="multiboot"
module_loader="module"
fi
fi
initrd_early=
for i in ${GRUB_EARLY_INITRD_LINUX_STOCK} \
${GRUB_EARLY_INITRD_LINUX_CUSTOM}; do
if test -e "${xen_dirname}/${i}" ; then
initrd_early="${initrd_early} ${i}"
fi
done
while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`
gettext_printf "Found linux image: %s\n" "$linux" >&2
basename=`basename $linux`
dirname=`dirname $linux`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
initrd_real=
for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
"initrd-${version}" "initramfs-${version}.img" \
"initrd.img-${alt_version}" "initrd-${alt_version}.img" \
"initrd-${alt_version}" "initramfs-${alt_version}.img" \
"initramfs-genkernel-${version}" \
"initramfs-genkernel-${alt_version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
"initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}" ; do
if test -e "${dirname}/${i}" ; then
initrd_real="$i"
break
fi
done
initrd=
if test -n "${initrd_early}" || test -n "${initrd_real}"; then
initrd="${initrd_early} ${initrd_real}"
initrd_display=
for i in ${initrd}; do
initrd_display="${initrd_display} ${dirname}/${i}"
done
gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
fi
if test -z "${initrd_real}"; then
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \
|| [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then
linux_root_device_thisversion=${GRUB_DEVICE}
else
linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID}
fi
fi
if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
linux_entry "${OS}" "${version}" "${xen_version}" simple \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}"
submenu_indentation="$grub_tab$grub_tab"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
# TRANSLATORS: %s is replaced with an OS name
echo "submenu '$(gettext_printf "Advanced options for %s (with Xen hypervisor)" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
echo " submenu '$(gettext_printf "Xen hypervisor, version %s" "${xen_version}" | grub_quote)' \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {"
is_top_level=false
fi
linux_entry "${OS}" "${version}" "${xen_version}" advanced \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}"
for supported_init in ${SUPPORTED_INITS}; do
init_path="${supported_init#*:}"
if [ -x "${init_path}" ] && [ "$(readlink -f /sbin/init)" != "$(readlink -f "${init_path}")" ]; then
linux_entry "${OS}" "${version}" "${xen_version}" "init-${supported_init%%:*}" \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} init=${init_path}" "${GRUB_CMDLINE_XEN} ${GRUB_CMDLINE_XEN_DEFAULT}"
fi
done
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${version}" "${xen_version}" recovery \
"single ${GRUB_CMDLINE_LINUX}" "${GRUB_CMDLINE_XEN}"
fi
list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
done
if [ x"$is_top_level" != xtrue ]; then
echo ' }'
fi
xen_list=`echo $xen_list | tr ' ' '\n' | fgrep -vx "$current_xen" | tr '\n' ' '`
done
# If at least one kernel was found, then we need to
# add a closing '}' for the submenu command.
if [ x"$is_top_level" != xtrue ]; then
echo '}'
fi
echo "$title_correction_code"
LinuxMint 20 xfce не показывает меню grub после upgrade
25_custom
#!/bin/sh
exec tail -n +3 $0
menuentry "EFI/BOOT/bkpbootx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/bkpbootx64.efi
}
menuentry "EFI/BOOT/fbx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/fbx64.efi
}
menuentry "EFI/BOOT/mmx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/mmx64.efi
}
menuentry "EFI/ubuntu/mmx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/ubuntu/mmx64.efi
}
menuentry "Windows UEFI bootmgfw.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi
}
menuentry "Windows Boot UEFI loader" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/bkpbootx64.efi
}
menuentry "Windows Boot UEFI fbx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/fbx64.efi
}
menuentry "Windows Boot UEFI mmx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/mmx64.efi
}
menuentry "EFI/ubuntu/fbx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/ubuntu/fbx64.efi
}
menuentry "EFI/ubuntu/mmx64.efi sdb2" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/ubuntu/mmx64.efi
}
menuentry "EFI/Lenovo/Boot/bootmgfw.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Lenovo/Boot/bootmgfw.efi
}
exec tail -n +3 $0
menuentry "EFI/BOOT/bkpbootx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/bkpbootx64.efi
}
menuentry "EFI/BOOT/fbx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/fbx64.efi
}
menuentry "EFI/BOOT/mmx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/BOOT/mmx64.efi
}
menuentry "EFI/ubuntu/mmx64.efi" {
search --fs-uuid --no-floppy --set=root 050A-274E
chainloader (${root})/EFI/ubuntu/mmx64.efi
}
menuentry "Windows UEFI bootmgfw.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi
}
menuentry "Windows Boot UEFI loader" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/bkpbootx64.efi
}
menuentry "Windows Boot UEFI fbx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/fbx64.efi
}
menuentry "Windows Boot UEFI mmx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Boot/mmx64.efi
}
menuentry "EFI/ubuntu/fbx64.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/ubuntu/fbx64.efi
}
menuentry "EFI/ubuntu/mmx64.efi sdb2" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/ubuntu/mmx64.efi
}
menuentry "EFI/Lenovo/Boot/bootmgfw.efi" {
search --fs-uuid --no-floppy --set=root 5217-53CE
chainloader (${root})/EFI/Lenovo/Boot/bootmgfw.efi
}
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость