From 3089bf955f64e54be23312f7f1f2664162338802 Mon Sep 17 00:00:00 2001 From: zj <1052308357@qq.com> Date: Thu, 12 Feb 2026 04:23:09 +0800 Subject: [PATCH] 2 --- backend.py | 155 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 137 insertions(+), 18 deletions(-) diff --git a/backend.py b/backend.py index d8c9a99..fd4e851 100644 --- a/backend.py +++ b/backend.py @@ -1377,35 +1377,61 @@ def _manual_install_efi_files(mount_point: str, efi_target: str, efi_grub_file: if success and os.path.exists(host_output_path): log_success(f"✓ 成功生成 EFI 文件: {host_output_path}") - # 对于独立 /boot 分区,创建一个辅助的 grub.cfg 来设置正确的 root + # 对于独立 /boot 分区,创建辅助配置 if has_separate_boot: - log_info("为独立 /boot 分区创建辅助 grub.cfg...") + log_info("为独立 /boot 分区创建辅助配置...") + + # 获取 /boot 分区的 UUID + boot_uuid = None + try: + success_uuid, uuid_out, _ = run_command( + ["sudo", "blkid", "-s", "UUID", "-o", "value", f"{mount_point}/boot"], + "获取 /boot 分区 UUID", + timeout=10 + ) + if success_uuid: + boot_uuid = uuid_out.strip() + except: + pass + + # 创建 EFI 分区上的 grub.cfg(GRUB 首先查找这里) 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 + if boot_uuid: + # 使用 UUID 搜索 /boot 分区 + helper_cfg = f'''# Auto-generated by BootRepairTool +# For separate /boot partition (UUID: {boot_uuid}) -# Search for the /boot partition by filesystem type and files -search --no-floppy --fs-uuid --set=root +# Search for /boot partition by UUID +search --no-floppy --fs-uuid --set=root {boot_uuid} +set prefix=($root)/grub2 -# 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 +# Load main configuration +configfile ($root)/grub2/grub.cfg +''' + else: + # 回退:尝试常见分区号 + helper_cfg = '''# Auto-generated by BootRepairTool +# For separate /boot partition + +# Try to find /boot partition by looking for grub2 directory +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 +elif [ -f (hd1,gpt2)/grub2/grub.cfg ]; then + set root=(hd1,gpt2) + set prefix=(hd1,gpt2)/grub2 fi -# Load the main configuration +# Load 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}") + log_success(f"✓ 创建 EFI 辅助 grub.cfg: {helper_cfg_path}") except Exception as e: log_warning(f"创建辅助 grub.cfg 失败: {e}") else: @@ -1501,6 +1527,51 @@ def install_efi_fallback(mount_point: str, efi_target: str, efi_grub_file: str, try: shutil.copy2(source_file, target_file) log_success(f"✓ EFI fallback 安装成功: {source_file} -> {target_file}") + + # 为 fallback 创建 grub.cfg(独立 /boot 分区时需要) + has_separate_boot = os.path.ismount(os.path.join(mount_point, "boot")) + if has_separate_boot: + log_info("检测到独立 /boot 分区,为 fallback 创建 grub.cfg...") + + # 获取 /boot 分区 UUID + boot_uuid = None + try: + success_uuid, uuid_out, _ = run_command( + ["sudo", "blkid", "-s", "UUID", "-o", "value", f"{mount_point}/boot"], + "获取 /boot UUID for fallback", + timeout=10 + ) + if success_uuid: + boot_uuid = uuid_out.strip() + except: + pass + + # 在 Boot 目录创建 grub.cfg + fallback_cfg_path = os.path.join(boot_dir, "grub.cfg") + try: + if boot_uuid: + fallback_cfg = f'''# BootRepairTool fallback config +search --no-floppy --fs-uuid --set=root {boot_uuid} +set prefix=($root)/grub2 +configfile ($root)/grub2/grub.cfg +''' + else: + fallback_cfg = '''# BootRepairTool fallback config +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 +configfile ${prefix}/grub.cfg +''' + with open(fallback_cfg_path, 'w') as f: + f.write(fallback_cfg) + log_success(f"✓ 创建 fallback grub.cfg: {fallback_cfg_path}") + except Exception as e: + log_warning(f"创建 fallback grub.cfg 失败: {e}") + return True except Exception as e: log_error(f"复制 EFI fallback 文件失败: {e}") @@ -2109,6 +2180,54 @@ def chroot_and_repair_grub(mount_point: str, target_disk: str, log_success("✓ GRUB 环境重建完成") + # 5. 为独立 /boot 分区创建 EFI 辅助 grub.cfg + has_separate_boot = os.path.ismount(os.path.join(mount_point, "boot")) + if has_separate_boot: + log_info("为独立 /boot 分区创建 EFI 辅助 grub.cfg...") + + # 获取 /boot 分区 UUID + boot_uuid = None + try: + success_uuid, uuid_out, _ = run_command( + ["sudo", "blkid", "-s", "UUID", "-o", "value", f"{mount_point}/boot"], + "获取 /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" 获取 UUID 失败: {e}") + + # 为每个 EFI 目录创建 grub.cfg + for efi_dir in [efi_bootloader_id, "Boot"]: + efi_cfg_dir = os.path.join(mount_point, "boot/efi/EFI", efi_dir) + if os.path.exists(efi_cfg_dir): + efi_cfg_path = os.path.join(efi_cfg_dir, "grub.cfg") + try: + if boot_uuid: + efi_cfg_content = f'''# BootRepairTool - Find /boot partition +search --no-floppy --fs-uuid --set=root {boot_uuid} +set prefix=($root)/grub2 +configfile ($root)/grub2/grub.cfg +''' + else: + efi_cfg_content = '''# BootRepairTool - Find /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 +configfile ${prefix}/grub.cfg +''' + with open(efi_cfg_path, 'w') as f: + f.write(efi_cfg_content) + log_success(f"✓ 创建 {efi_dir}/grub.cfg") + except Exception as e: + log_warning(f" 创建失败: {e}") + grub_install_cmd = chroot_cmd_prefix + [ _grub_install_cmd, f"--target={efi_target}",