forked from bottlerocket-os/bottlerocket
-
Notifications
You must be signed in to change notification settings - Fork 0
/
0040-gpt-write-backup-GPT-first-skip-if-inaccessible.patch
72 lines (64 loc) · 2.74 KB
/
0040-gpt-write-backup-GPT-first-skip-if-inaccessible.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
From 114dc2c20130ebe232fb52f02ddb14d06a6ac890 Mon Sep 17 00:00:00 2001
From: Michael Marineau <[email protected]>
Date: Thu, 22 Sep 2016 11:18:42 -0700
Subject: [PATCH] gpt: write backup GPT first, skip if inaccessible.
Writing the primary GPT before the backup may lead to a confusing
situation: booting a freshly updated system could consistently fail and
next boot will fall back to the old system if writing the primary works
but writing the backup fails. If the backup is written first and fails
the primary is left in the old state so the next boot will re-try and
possibly fail in the exact same way. Making that repeatable should make
it easier for users to identify the error.
Additionally if the firmware and OS disagree on the disk size, making
the backup inaccessible to GRUB, then just skip writing the backup.
When this happens the automatic call to `coreos-setgoodroot` after boot
will take care of repairing the backup.
---
grub-core/lib/gpt.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/grub-core/lib/gpt.c b/grub-core/lib/gpt.c
index 4304048..c3e3a25 100644
--- a/grub-core/lib/gpt.c
+++ b/grub-core/lib/gpt.c
@@ -729,19 +729,39 @@ grub_gpt_write_table (grub_disk_t disk, grub_gpt_t gpt,
grub_err_t
grub_gpt_write (grub_disk_t disk, grub_gpt_t gpt)
{
+ grub_uint64_t backup_header;
+
/* TODO: update/repair protective MBRs too. */
if (!grub_gpt_both_valid (gpt))
return grub_error (GRUB_ERR_BAD_PART_TABLE, "Invalid GPT data");
+ /* Write the backup GPT first so if writing fails the update is aborted
+ * and the primary is left intact. However if the backup location is
+ * inaccessible we have to just skip and hope for the best, the backup
+ * will need to be repaired in the OS. */
+ backup_header = grub_le_to_cpu64 (gpt->backup.header_lba);
+ if (grub_gpt_disk_size_valid (disk) &&
+ backup_header >= disk->total_sectors)
+ {
+ grub_printf ("warning: backup GPT located at 0x%llx, "
+ "beyond last disk sector at 0x%llx\n",
+ (unsigned long long) backup_header,
+ (unsigned long long) disk->total_sectors - 1);
+ grub_printf ("warning: only writing primary GPT, "
+ "the backup GPT must be repaired from the OS\n");
+ }
+ else
+ {
+ grub_dprintf ("gpt", "writing backup GPT to %s\n", disk->name);
+ if (grub_gpt_write_table (disk, gpt, &gpt->backup))
+ return grub_errno;
+ }
+
grub_dprintf ("gpt", "writing primary GPT to %s\n", disk->name);
if (grub_gpt_write_table (disk, gpt, &gpt->primary))
return grub_errno;
- grub_dprintf ("gpt", "writing backup GPT to %s\n", disk->name);
- if (grub_gpt_write_table (disk, gpt, &gpt->backup))
- return grub_errno;
-
return GRUB_ERR_NONE;
}
--
2.21.3