Version 0.5.1-pre2; additional changes to support detection and

correction of incorrect placement of the secondary header and partition
table.
This commit is contained in:
srs5694
2009-11-24 18:28:18 -05:00
parent 8bb7876224
commit 3f2fe99e72
3 changed files with 31 additions and 12 deletions

View File

@@ -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.

View File

@@ -29,7 +29,7 @@ int main(int argc, char* argv[]) {
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 ExpertsMenu(char* filename, struct GPTData* theGPT) {
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");

35
gpt.cc
View File

@@ -122,11 +122,10 @@ int GPTData::Verify(void) {
} // 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 @@ int GPTData::CheckHeaderValidity(void) {
(((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 @@ int GPTData::ForceLoadGPTData(int fd) {
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 @@ int GPTData::ForceLoadGPTData(int fd) {
} 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