From e79a11bddc282675b25ce88640ec7dfa771f55ec Mon Sep 17 00:00:00 2001 From: vasilito Date: Thu, 2 Jul 2026 10:14:35 +0300 Subject: [PATCH] fix: rename hlnk->vlnk in grub.cfg + fix mcopy recursion bug Two critical fixes that unblock the hardlink/chain boot paths: 1. hlnk->vlnk rename in src/grub2/grub/grub.cfg The in-tree grub.cfg calls GRUB commands with rebrand 'hlnk' naming (vt_is_hlnk_name, vt_get_hlnk_dst, etc.) but the GRUB binary built from vendor/grub2-modsrc.tar.xz has Ventoy's original 'vlnk' naming. This mismatch caused 'can't find command' errors for any menu item using the hardlink path (which is most ISO files). Renamed all hlnk references to vlnk in the source grub.cfg. Added an automatic hlnk->vlnk sed pass to package_release.sh so future edits stay in sync. 2. mcopy recursion bug in package_release.sh The single-mcopy optimization (commit 17094e5) used 'mcopy -s -i ESP IMG STAGING/* ::/' which only created empty top-level directories without copying file contents into them. This meant the deployed ESP image had empty EFI/, grub/, hiperiso/ directories. Replaced with explicit per-subdirectory copy loop that recursively copies each top-level entry with 'mcopy -s -i ESP IMG STAGE/DIR ::/DIR'. Verified files are now in the deployed image. QEMU test confirms: - Disk boots, GRUB 2.04 loads - ESP contains BOOTX64.EFI, grub.cfg, ventoy.cpio, chain files - hlnk/vlnk mismatch fixed: 0 hlnk refs, 20 vlnk refs in grub.cfg --- scripts/package_release.sh | 30 ++++++++++++++++++++++++- src/grub2/grub/grub.cfg | 46 +++++++++++++++++++------------------- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/scripts/package_release.sh b/scripts/package_release.sh index f94348e..d8b5468 100755 --- a/scripts/package_release.sh +++ b/scripts/package_release.sh @@ -160,6 +160,24 @@ cp "$PAYLOAD/EFI/hiperiso/vmlinuz" "$PAYLOAD/EFI/hiperiso/initramfs.cpio.gz" \ cp "$PAYLOAD"/EFI/hiperiso/trace/*.events "$ESP_STAGING/EFI/hiperiso/trace/" 2>/dev/null || true cp "$PAYLOAD/grub/grub.cfg" "$ESP_STAGING/grub/" + +# The vendored modsrc uses Ventoy's 'vlnk' naming; in-tree grub.cfg +# uses rebrand 'hlnk'. Rewrite the deployed config to match the binary. +if [ -f "$ESP_STAGING/grub/grub.cfg" ]; then + sed -i \ + -e 's/vt_is_hlnk_name/vt_is_vlnk_name/g' \ + -e 's/vt_get_hlnk_dst/vt_get_vlnk_dst/g' \ + -e 's/vt_hlnk_dst/vt_vlnk_dst/g' \ + -e 's/vt_set_fake_hlnk/vt_set_fake_vlnk/g' \ + -e 's/vt_reset_fake_hlnk/vt_reset_fake_vlnk/g' \ + -e 's/vt_unix_check_hlnk/vt_unix_check_vlnk/g' \ + -e 's/vt_hlnk_check/vt_vlnk_check/g' \ + -e 's/vt_hlnk_dump_part/vt_vlnk_dump_part/g' \ + -e 's/HLNK FILE NOT FOUND/VLNK FILE NOT FOUND/g' \ + -e 's/HLNK 文件不存在/VLNK 文件不存在/g' \ + -e 's/HLNK/VLNK/g' \ + "$ESP_STAGING/grub/grub.cfg" +fi # Copy chain-boot EFI binaries + helpers to the ESP at /hiperiso/ # (grub.cfg looks for them at \$hiso_path which is the data partition; # having them also on the ESP helps when the data partition fails to @@ -210,7 +228,17 @@ dd if=/dev/zero of="$ESP_IMG" bs=1M count=32 2>/dev/null mkfs.vfat -F 16 -n "VTOYEFI" "$ESP_IMG" >/dev/null 2>&1 _progress 7 "Populating ESP (single mcopy)..." -mcopy -s -i "$ESP_IMG" "$ESP_STAGING/"* ::/ 2>/dev/null +# mcopy with a wildcard of subdirs + ::/ does not recurse reliably +# in all mtools versions. Loop the subdirs explicitly to ensure full +# recursion into the staging tree. +for entry in "$ESP_STAGING"/*; do + name=$(basename "$entry") + if [ -d "$entry" ]; then + mcopy -s -i "$ESP_IMG" "$entry" "::/$name" 2>/dev/null || true + elif [ -f "$entry" ]; then + mcopy -i "$ESP_IMG" "$entry" "::/$name" 2>/dev/null || true + fi +done rm -rf "$ESP_STAGING" trap - EXIT INT TERM diff --git a/src/grub2/grub/grub.cfg b/src/grub2/grub/grub.cfg index 012dbd1..0c50569 100644 --- a/src/grub2/grub/grub.cfg +++ b/src/grub2/grub/grub.cfg @@ -586,7 +586,7 @@ function hiperiso_dragonfly_proc { function hiperiso_unix_comm_proc { vt_unix_reset - vt_unix_check_hlnk "${1}${chosen_path}" + vt_unix_check_vlnk "${1}${chosen_path}" if [ "$hiperiso_compatible" = "NO" ]; then loopback vtunix $hiso_efi_part/hiperiso/hiperiso_unix.cpio @@ -1668,16 +1668,16 @@ function efi_common_menuentry { return fi - unset vt_hlnk_dst - if vt_is_hlnk_name "${vt_chosen_path}"; then - vt_get_hlnk_dst "${hiso_iso_part}${vt_chosen_path}" vt_hlnk_dst - if [ -z "$vt_hlnk_dst" ]; then - echo -e "\n### HLNK FILE NOT FOUND ###\n### HLNK 文件不存在 ###\n" + unset vt_vlnk_dst + if vt_is_vlnk_name "${vt_chosen_path}"; then + vt_get_vlnk_dst "${hiso_iso_part}${vt_chosen_path}" vt_vlnk_dst + if [ -z "$vt_vlnk_dst" ]; then + echo -e "\n### VLNK FILE NOT FOUND ###\n### VLNK 文件不存在 ###\n" hiperiso_pause return fi else - vt_hlnk_dst="${hiso_iso_part}${vt_chosen_path}" + vt_vlnk_dst="${hiso_iso_part}${vt_chosen_path}" fi hiperiso_debug_pause @@ -1687,12 +1687,12 @@ function efi_common_menuentry { #first try with chainload set vtOldRoot=$root set root=$hiso_iso_part - chainloader "${vt_hlnk_dst}" + chainloader "${vt_vlnk_dst}" boot #retry with isoboot set root=$vtOldRoot - vt_concat_efi_iso "${vt_hlnk_dst}" hiso_iso_buf + vt_concat_efi_iso "${vt_vlnk_dst}" hiso_iso_buf chainloader ${hiso_path}/hiperiso_${HISO_EFI_ARCH}.efi memdisk env_param=${env_param} dotefi isoefi=on ${vtdebug_flag} mem:${hiso_iso_buf_addr}:size:${hiso_iso_buf_size} boot @@ -1743,16 +1743,16 @@ function vhd_common_menuentry { return fi - unset vt_hlnk_dst - if vt_is_hlnk_name "${vt_chosen_path}"; then - vt_get_hlnk_dst "${hiso_iso_part}${vt_chosen_path}" vt_hlnk_dst - if [ -z "$vt_hlnk_dst" ]; then - echo -e "\n### HLNK FILE NOT FOUND ###\n### HLNK 文件不存在 ###\n" + unset vt_vlnk_dst + if vt_is_vlnk_name "${vt_chosen_path}"; then + vt_get_vlnk_dst "${hiso_iso_part}${vt_chosen_path}" vt_vlnk_dst + if [ -z "$vt_vlnk_dst" ]; then + echo -e "\n### VLNK FILE NOT FOUND ###\n### VLNK 文件不存在 ###\n" hiperiso_pause return fi else - vt_hlnk_dst="${vt_chosen_path}" + vt_vlnk_dst="${vt_chosen_path}" if [ "$HISO_VHD_NO_WARNING" != "1" ]; then if [ "$hiso_iso_fs" != "ntfs" ]; then echo -e "!!! WARNING !!!\n" @@ -1764,7 +1764,7 @@ function vhd_common_menuentry { fi fi - vhdboot_common_func "${vt_hlnk_dst}" + vhdboot_common_func "${vt_vlnk_dst}" } function vhd_unsupport_menuentry { @@ -1845,19 +1845,19 @@ function hiso_common_menuentry { return fi - unset vt_hlnk_dst - if vt_is_hlnk_name "${vt_chosen_path}"; then - vt_get_hlnk_dst "${hiso_iso_part}${vt_chosen_path}" vt_hlnk_dst - if [ -z "$vt_hlnk_dst" ]; then - echo -e "\n### HLNK FILE NOT FOUND ###\n### HLNK 文件不存在 ###\n" + unset vt_vlnk_dst + if vt_is_vlnk_name "${vt_chosen_path}"; then + vt_get_vlnk_dst "${hiso_iso_part}${vt_chosen_path}" vt_vlnk_dst + if [ -z "$vt_vlnk_dst" ]; then + echo -e "\n### VLNK FILE NOT FOUND ###\n### VLNK 文件不存在 ###\n" hiperiso_pause return fi else - vt_hlnk_dst="${hiso_iso_part}${vt_chosen_path}" + vt_vlnk_dst="${hiso_iso_part}${vt_chosen_path}" fi - hisoboot_common_func "${vt_hlnk_dst}" + hisoboot_common_func "${vt_vlnk_dst}" } function hiso_unsupport_menuentry {