Version 0.5.1-pre2; additional changes to support detection and
correction of incorrect placement of the secondary header and partition
table.
diff --git a/CHANGELOG b/CHANGELOG
index 984f90e..c853e5b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,10 @@
- Incorporated RPM .spec file changes contributed by Scott Collier
(boodle11@gmail.com).
+- Changed method of locating and loading backup GPT data, to use the
+ main header's pointer, if it's valid, rather than seeking to the
+ end of the disk.
+
- Added 'e' option (relocate backup GPT data structures) to the experts'
menu.
diff --git a/gdisk.cc b/gdisk.cc
index d86a9a4..ef42ea8 100644
--- a/gdisk.cc
+++ b/gdisk.cc
@@ -29,7 +29,7 @@
int doMore = 1;
char* device = NULL;
- printf("GPT fdisk (gdisk) version 0.5.1-pre1\n\n");
+ printf("GPT fdisk (gdisk) version 0.5.1-pre2\n\n");
if (argc == 2) { // basic usage
if (SizesOK()) {
@@ -366,7 +366,7 @@
void ShowExpertCommands(void) {
printf("a\tset attributes\n");
printf("c\tchange partition GUID\n");
- printf("e\trelocate backup data structures\n");
+ printf("e\trelocate backup data structures to the end of the disk\n");
printf("g\tchange disk GUID\n");
printf("i\tshow detailed information on a partition\n");
printf("m\treturn to main menu\n");
diff --git a/gpt.cc b/gpt.cc
index 3a98037..f339a72 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -122,11 +122,10 @@
} // if
if (secondHeader.currentLBA != (diskSize - UINT64_C(1))) {
problems++;
- printf("\nProblem: The secondary header's self-pointer doesn't point to itself. This\n"
- "problem is being automatically corrected, but it may be a symptom of more\n"
- "serious problems. Think carefully before saving changes with 'w' or using this\n"
- "disk.\n");
- secondHeader.currentLBA = diskSize - UINT64_C(1);
+ printf("\nProblem: The secondary header's self-pointer indicates that it doesn't reside\n"
+ "at the end of the disk. If you've added a disk to a RAID array, use the 'e'\n"
+ "option on the experts' menu to adjust the secondary header's and partition"
+ "table's locations.");
} // if
// Now check that critical main and backup GPT entries match each other
@@ -303,7 +302,7 @@
(((mainHeader.signature << 32) == APM_SIGNATURE1) ||
(mainHeader.signature << 32) == APM_SIGNATURE2)) {
apmFound = 1; // Will display warning message later
- } // if
+ } // if
return valid;
} // GPTData::CheckHeaderValidity()
@@ -589,9 +588,25 @@
if (IsLittleEndian() == 0) // big-endian system; adjust header byte order....
ReverseHeaderBytes(&mainHeader);
- // Load backup header, check its CRC, and store the results of
- // the check for future reference
- seekTo = (diskSize * blockSize) - UINT64_C(512);
+ // Load backup header, check its CRC, and store the results of the
+ // check for future reference. Load backup header using pointer in main
+ // header if possible; but if main header has a CRC error, or if it
+ // points to beyond the end of the disk, load the last sector of the
+ // disk instead.
+ if (mainCrcOk) {
+ if (mainHeader.backupLBA < diskSize) {
+ seekTo = mainHeader.backupLBA * blockSize;
+ } else {
+ seekTo = (diskSize * blockSize) - UINT64_C(512);
+ printf("Warning! Disk size is smaller than the main header indicates! Loading\n"
+ "secondary header from the last sector of the disk! You should use 'v' to\n"
+ "verify disk integrity, and perhaps options on the experts' menu to repair\n"
+ "the disk.\n");
+ } // else
+ } else {
+ seekTo = (diskSize * blockSize) - UINT64_C(512);
+ } // if/else (mainCrcOk)
+
if (lseek64(fd, seekTo, SEEK_SET) != (off_t) -1) {
read(fd, &secondHeader, 512); // read secondary GPT header
secondCrcOk = CheckHeaderCRC(&secondHeader);
@@ -600,7 +615,7 @@
} else {
allOK = 0;
state = gpt_invalid;
- fprintf(stderr, "Unable to seek to secondary GPT at sector %llu!\n",
+ fprintf(stderr, "Unable to seek to secondary GPT header at sector %llu!\n",
diskSize - (UINT64_C(1)));
} // if/else lseek