(
root_path: Utf8PathBuf,
setup_type: &BootSetupType,
boot_label: String,
id: &Sha512HashValue,
esp_device: &String,
)
| 914 | |
| 915 | #[context("Writing Grub menuentry")] |
| 916 | fn write_grub_uki_menuentry( |
| 917 | root_path: Utf8PathBuf, |
| 918 | setup_type: &BootSetupType, |
| 919 | boot_label: String, |
| 920 | id: &Sha512HashValue, |
| 921 | esp_device: &String, |
| 922 | ) -> Result<()> { |
| 923 | let boot_dir = root_path.join("boot"); |
| 924 | create_dir_all(&boot_dir).context("Failed to create boot dir")?; |
| 925 | |
| 926 | let is_upgrade = matches!(setup_type, BootSetupType::Upgrade(..)); |
| 927 | |
| 928 | let efi_uuid_source = get_efi_uuid_source(); |
| 929 | |
| 930 | let user_cfg_name = if is_upgrade { |
| 931 | USER_CFG_STAGED |
| 932 | } else { |
| 933 | USER_CFG |
| 934 | }; |
| 935 | |
| 936 | let grub_dir = Dir::open_ambient_dir(boot_dir.join("grub2"), ambient_authority()) |
| 937 | .context("opening boot/grub2")?; |
| 938 | |
| 939 | // Iterate over all available deployments, and generate a menuentry for each |
| 940 | if is_upgrade { |
| 941 | let mut str_buf = String::new(); |
| 942 | let boot_dir = |
| 943 | Dir::open_ambient_dir(boot_dir, ambient_authority()).context("Opening boot dir")?; |
| 944 | let entries = get_sorted_grub_uki_boot_entries(&boot_dir, &mut str_buf)?; |
| 945 | |
| 946 | grub_dir |
| 947 | .atomic_replace_with(user_cfg_name, |f| -> std::io::Result<_> { |
| 948 | f.write_all(efi_uuid_source.as_bytes())?; |
| 949 | f.write_all( |
| 950 | MenuEntry::new(&boot_label, &id.to_hex()) |
| 951 | .to_string() |
| 952 | .as_bytes(), |
| 953 | )?; |
| 954 | |
| 955 | // Write out only the currently booted entry, which should be the very first one |
| 956 | // Even if we have booted into the second menuentry "boot entry", the default will be the |
| 957 | // first one |
| 958 | f.write_all(entries[0].to_string().as_bytes())?; |
| 959 | |
| 960 | Ok(()) |
| 961 | }) |
| 962 | .with_context(|| format!("Writing to {user_cfg_name}"))?; |
| 963 | |
| 964 | rustix::fs::fsync(grub_dir.reopen_as_ownedfd()?).context("fsync")?; |
| 965 | |
| 966 | return Ok(()); |
| 967 | } |
| 968 | |
| 969 | // Open grub2/efiuuid.cfg and write the EFI partition fs-UUID in there |
| 970 | // This will be sourced by grub2/user.cfg to be used for `--fs-uuid` |
| 971 | let esp_uuid = Task::new("blkid for ESP UUID", "blkid") |
| 972 | .args(["-s", "UUID", "-o", "value", &esp_device]) |
| 973 | .read()?; |
no test coverage detected