1
This commit is contained in:
110
backend.py
110
backend.py
@@ -1342,13 +1342,28 @@ def _manual_install_efi_files(mount_point: str, efi_target: str, efi_grub_file:
|
||||
# 构建 chroot 内的输出路径
|
||||
chroot_output_path = f"/boot/efi/EFI/{bootloader_id}/{efi_grub_file}"
|
||||
|
||||
# 检测是否有独立的 /boot 分区
|
||||
has_separate_boot = os.path.ismount(os.path.join(mount_point, "boot"))
|
||||
|
||||
# 确定正确的 prefix
|
||||
# 对于独立 /boot 分区,使用 '(<device>)/grub2' 格式,让 GRUB 自动搜索
|
||||
# 或者使用 '/boot/grub2' 配合 search 命令
|
||||
if has_separate_boot:
|
||||
# 独立 /boot 分区:使用相对路径,依赖 grub.cfg 中的 search 命令
|
||||
# 或者使用 '(,gpt2)/grub2' 格式指定分区
|
||||
grub_prefix = "/grub2"
|
||||
log_info(f"检测到独立 /boot 分区,使用 prefix: {grub_prefix}")
|
||||
else:
|
||||
grub_prefix = "/boot/grub2"
|
||||
log_info(f"使用标准 prefix: {grub_prefix}")
|
||||
|
||||
# 尝试使用 grub-mkimage 生成 EFI 文件
|
||||
chroot_cmd_prefix = ["sudo", "chroot", mount_point]
|
||||
mkimage_cmd = chroot_cmd_prefix + [
|
||||
"grub2-mkimage",
|
||||
"-o", chroot_output_path,
|
||||
"-O", efi_target,
|
||||
"-p", "/boot/grub2",
|
||||
"-p", grub_prefix,
|
||||
] + modules.split()
|
||||
|
||||
success, _, stderr = run_command(
|
||||
@@ -1361,6 +1376,38 @@ def _manual_install_efi_files(mount_point: str, efi_target: str, efi_grub_file:
|
||||
host_output_path = os.path.join(mount_point, chroot_output_path.lstrip('/'))
|
||||
if success and os.path.exists(host_output_path):
|
||||
log_success(f"✓ 成功生成 EFI 文件: {host_output_path}")
|
||||
|
||||
# 对于独立 /boot 分区,创建一个辅助的 grub.cfg 来设置正确的 root
|
||||
if has_separate_boot:
|
||||
log_info("为独立 /boot 分区创建辅助 grub.cfg...")
|
||||
helper_cfg_path = os.path.join(mount_point, f"boot/efi/EFI/{bootloader_id}/grub.cfg")
|
||||
try:
|
||||
helper_cfg = '''# Auto-generated by BootRepairTool for separate /boot partition
|
||||
# This file sets the correct root and loads the main config
|
||||
|
||||
# Search for the /boot partition by filesystem type and files
|
||||
search --no-floppy --fs-uuid --set=root
|
||||
|
||||
# If search fails, try common partition numbers
|
||||
if [ "${root}" = "${prefix}" ]; then
|
||||
# Try (hd0,gpt2) - common /boot partition
|
||||
if [ -f (hd0,gpt2)/grub2/grub.cfg ]; then
|
||||
set root=(hd0,gpt2)
|
||||
set prefix=(hd0,gpt2)/grub2
|
||||
elif [ -f (hd0,2)/grub2/grub.cfg ]; then
|
||||
set root=(hd0,2)
|
||||
set prefix=(hd0,2)/grub2
|
||||
fi
|
||||
fi
|
||||
|
||||
# Load the main configuration
|
||||
configfile ${prefix}/grub.cfg
|
||||
'''
|
||||
with open(helper_cfg_path, 'w') as f:
|
||||
f.write(helper_cfg)
|
||||
log_success(f"✓ 创建辅助 grub.cfg: {helper_cfg_path}")
|
||||
except Exception as e:
|
||||
log_warning(f"创建辅助 grub.cfg 失败: {e}")
|
||||
else:
|
||||
log_error(f"生成 EFI 文件失败: {stderr}")
|
||||
return False
|
||||
@@ -2519,8 +2566,65 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str,
|
||||
log_warning(f"查找内核文件失败: {e}")
|
||||
|
||||
if kernel_files and root_uuid:
|
||||
# 检测是否有独立 /boot 分区
|
||||
boot_uuid = None
|
||||
try:
|
||||
boot_mount_point = os.path.join(mount_point, "boot")
|
||||
if os.path.ismount(boot_mount_point):
|
||||
# 有独立 /boot 分区,获取其 UUID
|
||||
success_uuid, uuid_out, _ = run_command(
|
||||
["sudo", "blkid", "-s", "UUID", "-o", "value", boot_mount_point],
|
||||
"获取 /boot 分区 UUID",
|
||||
timeout=10
|
||||
)
|
||||
if success_uuid:
|
||||
boot_uuid = uuid_out.strip()
|
||||
log_info(f"检测到独立 /boot 分区,UUID: {boot_uuid}")
|
||||
except Exception as e:
|
||||
log_warning(f"获取 /boot UUID 失败: {e}")
|
||||
|
||||
# 创建基本 grub.cfg
|
||||
grub_cfg_content = f"""# Minimal GRUB config generated by BootRepairTool
|
||||
if boot_uuid:
|
||||
# 独立 /boot 分区配置 - 需要先搜索 /boot 分区
|
||||
grub_cfg_content = f"""# Minimal GRUB config generated by BootRepairTool
|
||||
# For system with separate /boot partition
|
||||
|
||||
set timeout=5
|
||||
set default=0
|
||||
|
||||
# Load necessary modules
|
||||
insmod part_gpt
|
||||
insmod xfs
|
||||
insmod fat
|
||||
|
||||
# Search for the /boot partition by UUID, then set root to the system root
|
||||
search --no-floppy --fs-uuid --set=root {boot_uuid}
|
||||
set prefix=($root)/grub2
|
||||
|
||||
menuentry 'CentOS Linux (Auto)' {{
|
||||
load_video
|
||||
set gfxpayload=keep
|
||||
insmod gzio
|
||||
insmod part_gpt
|
||||
insmod xfs
|
||||
linux /{kernel_files[0]} root=UUID={root_uuid} ro rhgb quiet
|
||||
initrd /{initramfs_files[0] if initramfs_files else ''}
|
||||
}}
|
||||
|
||||
menuentry 'CentOS Linux (Rescue)' {{
|
||||
load_video
|
||||
set gfxpayload=keep
|
||||
insmod gzio
|
||||
insmod part_gpt
|
||||
insmod xfs
|
||||
linux /{kernel_files[0]} root=UUID={root_uuid} ro rescue
|
||||
initrd /{initramfs_files[0] if initramfs_files else ''}
|
||||
}}
|
||||
"""
|
||||
else:
|
||||
# 无独立 /boot 分区配置
|
||||
grub_cfg_content = f"""# Minimal GRUB config generated by BootRepairTool
|
||||
|
||||
set timeout=5
|
||||
set default=0
|
||||
|
||||
@@ -2538,7 +2642,7 @@ menuentry 'CentOS Linux (Auto)' {{
|
||||
insmod gzio
|
||||
insmod part_gpt
|
||||
insmod xfs
|
||||
linux /{kernel_files[0]} root=UUID={root_uuid} ro
|
||||
linux /{kernel_files[0]} root=UUID={root_uuid} ro rhgb quiet
|
||||
initrd /{initramfs_files[0] if initramfs_files else ''}
|
||||
}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user