Bug 59632
| Summary: | grub-efi-install: installing Secure Boot binaries to ESP mv: cannot overwrite '/boot/efi/EFI/BOOT/BOOTX64.EFI': Файл существует | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Branch p11 | Reporter: | Vyacheslav Bocharov <vebocharov> | ||||
| Component: | grub-efi | Assignee: | Egor Ignatov <egori> | ||||
| Status: | ASSIGNED --- | QA Contact: | qa-p11 <qa-p11> | ||||
| Severity: | normal | ||||||
| Priority: | P5 | CC: | egori, glinkinvd, me, vebocharov | ||||
| Version: | unspecified | ||||||
| Hardware: | x86_64 | ||||||
| OS: | Linux | ||||||
| Attachments: |
|
||||||
Добрый день. Спасибо за репорт! Подскажите еще, пожалуйста, опции с которыми смонтирован /boot/efi: ``` sudo mount | grep /boot/efi sudo grep '/boot/efi' /etc/fstab ``` И версию ядра на момент возникновения ошибки. Здравствуйте. $ sudo mount | grep /boot/efi /dev/nvme0n1p1 on /boot/efi type vfat (rw,relatime,fmask=0000,dmask=0000,allow_utime=0022,codepage=866,iocharset=utf8,shortname=mixed,quiet,showexec,utf8,errors=remount-ro) journalctl -b -3 -k --grep "Linux version" | head -1 июн 12 00:59:03 <hostname> kernel: Linux version 6.12.74-6.12-alt1 (builder@localhost.localdomain) (gcc-13 (GCC) 13.2.1 20240128 (ALT Sisyphus 13.2.1-alt3), GNU ld (GNU Binutils) 2.41.0.20230826) #1 SMP PREEMPT_DYNAMIC Fri Mar 6 13:49:54 UTC 2026 $ sudo grep '/boot/efi' /etc/fstab UUID=4201-1CF6 /boot/efi vfat umask=0,quiet,showexec,iocharset=utf8,codepage=866 1 2 На MSI-B850-GAMING-PLUS-WIFI столкнулся с такой же проблемой при обновлении: ``` [root@MSI-B850-GAMING-PLUS-WIFI ~]# journalctl | grep "grub-efi" июн 24 18:04:24 host-189 apt-get[4056]: grub-efi-2.14-alt7 p11+411845.254.13.1 1781794123 installed июн 24 18:04:35 host-189 apt-get[4056]: grub-efi-2.12-alt14 p11+387320.100.1.1 1750090330 removed ``` Как следствие, загрузка с включенным Secure Boot невозможна. ``` [root@MSI-B850-GAMING-PLUS-WIFI ~]# pesign -i /boot/efi/EFI/altlinux/shimx64.efi -S --------------------------------------------- certificate address is 0x7f7c4bcb8f00 Content was not encrypted. Content is detached; signature cannot be verified. The signer's common name is Microsoft Windows UEFI Driver Publisher No signer email address. No signing time included. There were certs or crls included. --------------------------------------------- [root@MSI-B850-GAMING-PLUS-WIFI ~]# pesign -i /boot/efi/EFI/altlinux/grubx64.efi -S No signatures found. ``` Выполнение grub-efi-autoupdate помогло. Created attachment 22070 [details] Исправление guile-evms Нашёл решение данной проблемы. Она идёт с Сизифа и связана с пакетом guile-evms. Проблема в том, что ESP монтируется с iocharset=utf8, при котором VFAT некорректно сопоставляет имена, отличающиеся только регистром. Файл bootx64.efi, созданный Windows, хранится как короткая 8.3-запись BOOTX64.EFI со специальными lowercase-флагами. Linux ядро показывает его как bootx64.efi, но при iocharset=utf8 запрос к BOOTX64.EFI не находит существующий файл. В результате grub-efi-install создаёт BOOTX64.EFI.new, после чего выполняет: > mv BOOTX64.EFI.new BOOTX64.EFI VFAT сначала считает, что целевой файл отсутствует, а при попытке создать запись обнаруживает и возвращает EEXIST. Для воспроизведения ошибки, в Linux подобный bootx64.efi файл можно получить, создав файл на VFAT при shortname=winnt, а затем перемонтировав раздел с shortname=mixed,iocharset=utf8 Прикладываю патч, добавляющий iocharset=ascii, который обеспечивает корректное сравнение ASCII-регистра. Да, конечно можно обновить ещё утилиту обновления grub, чтобы она обнаруживала этот файл и что-то с ним делала. Но это дополнительное исправление. Нашел решение данной проблемы, исправлю в ближайшем релизе. Вот как это решили в debian [1]. По сути перед записью нужно узнать существует ли уже такой файл, и если есть, то использовать его точное имя учитывая регистр. [1] https://salsa.debian.org/grub-team/grub/-/blob/master/debian/patches/grub-install-extra-removable.patch?ref_type=heads#L76 Примерная реализация на shell: ``` # esp_resolve_name DIR NAME # Print the on-disk spelling of NAME in DIR: an exact match wins, then # the first case-insensitive match (with a warning if there are # several), then NAME itself (for a component that does not exist yet). # Never fails. esp_resolve_name() ( dir="$1" want="$2" lower_want="$(printf '%s' "$want" | tr '[:upper:]' '[:lower:]')" found= nmatches=0 for entry in "$dir"/*; do [ -e "$entry" ] || [ -L "$entry" ] || continue name="${entry##*/}" if [ "$name" = "$want" ]; then printf '%s\n' "$name" return 0 fi if [ "$(printf '%s' "$name" | tr '[:upper:]' '[:lower:]')" = "$lower_want" ]; then [ -n "$found" ] || found="$name" nmatches=$((nmatches + 1)) fi done if [ -n "$found" ]; then if [ "$nmatches" -gt 1 ]; then echo "${PROG:-grub-efi}: warning: $nmatches case-insensitive matches for '$want' in $dir; using '$found'" >&2 fi printf '%s\n' "$found" return 0 fi printf '%s\n' "$want" ) ``` |

Description
Vyacheslav Bocharov 2026-06-24 00:11:45 MSK