summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsrs5694 <srs5694@users.sourceforge.net>2010-09-22 01:07:31 -0400
committersrs5694 <srs5694@users.sourceforge.net>2010-09-22 01:07:31 -0400
commit327129e9331f888a8fc08d688dcb0a739a3c17be (patch)
treed47eeb130686d47a0800d45e6f2a530374f4c293
parent659eaf1552778f5d62878e59bb66ba6fe404a6bf (diff)
downloadsgdisk-327129e9331f888a8fc08d688dcb0a739a3c17be.tar.gz
sgdisk can now accept GUID values with its -t option. Also some
additional checks for hybrid MBR issues.
-rw-r--r--NEWS19
-rw-r--r--gpt.cc15
-rw-r--r--gpt.h4
-rw-r--r--mbr.cc38
-rw-r--r--mbr.h1
-rw-r--r--partnotes.cc24
-rw-r--r--partnotes.h1
-rw-r--r--sgdisk.87
-rw-r--r--sgdisk.cc18
9 files changed, 115 insertions, 12 deletions
diff --git a/NEWS b/NEWS
index 2394dfb..441c9f1 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,24 @@
0.6.11 (??/??/2010):
--------------------
--
+- The -t option to sgdisk now accepts GUID values as well as the
+ sgdisk/gdisk-specific two-byte hex codes.
+
+- Added check that the protective 0xEE MBR partition begins on sector 1
+ to the verify function. If it doesn't, a warning message is displayed,
+ but it doesn't count as an error.
+
+- Added check for overlapping MBR partitions to verify function (gdisk "v"
+ function on all menus; sgdisk -v/--verify function). Also warns about
+ multiple MBR 0xEE partitions (causes problems in some OSes).
+
+- Added check to GPT-to-MBR and hybrid MBR creation options to prevent
+ creation of disks with duplicate partitions. When told to create a disk
+ with duplicates, sgdisk now aborts with the error message "Problem
+ creating MBR!" When attempting to create a hybrid MBR with duplicates,
+ gdisk silently drops duplicate partitions, leaving fewer than requested.
+ Creating duplicates should not be possible in sgdisk when converting to
+ MBR form.
0.6.10 (8/22/2010):
-------------------
diff --git a/gpt.cc b/gpt.cc
index 7dcbc86..85176b8 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -227,6 +227,9 @@ int GPTData::Verify(void) {
// Check for mismatched MBR and GPT partitions...
problems += FindHybridMismatches();
+ // Check for MBR-specific problems....
+ problems += VerifyMBR();
+
// Verify that partitions don't run into GPT data areas....
problems += CheckGPTSize();
@@ -1512,6 +1515,7 @@ int GPTData::PartsToMBR(PartNotes & notes) {
protectiveMBR.EmptyMBR(0);
protectiveMBR.SetDiskSize(diskSize);
+ notes.MakeItLegal();
notes.Rewind();
while (notes.GetNextInfo(&convInfo) >= 0) {
if ((convInfo.gptPartNum >= 0) && (convInfo.type == PRIMARY)) {
@@ -1860,6 +1864,17 @@ int GPTData::ChangePartType(uint32_t partNum, uint16_t hexCode) {
return retval;
} // GPTData::ChangePartType()
+// Change partition type code non-interactively. Returns 1 if
+// successful, 0 if not....
+int GPTData::ChangePartType(uint32_t partNum, PartType theGUID) {
+ int retval = 1;
+
+ if (!IsFreePartNum(partNum)) {
+ partitions[partNum].SetType(theGUID);
+ } else retval = 0;
+ return retval;
+} // GPTData::ChangePartType()
+
// Recompute the CHS values of all the MBR partitions. Used to reset
// CHS values that some BIOSes require, despite the fact that the
// resulting CHS values violate the GPT standard.
diff --git a/gpt.h b/gpt.h
index 4f0ccf7..6566a64 100644
--- a/gpt.h
+++ b/gpt.h
@@ -16,7 +16,7 @@
#ifndef __GPTSTRUCTS
#define __GPTSTRUCTS
-#define GPTFDISK_VERSION "0.6.10"
+#define GPTFDISK_VERSION "0.6.11-pre1"
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
// numbered value to refer to partition numbers. (Most will be 0 or positive,
@@ -113,6 +113,7 @@ public:
void RecomputeCRCs(void);
void RebuildMainHeader(void);
void RebuildSecondHeader(void);
+ int VerifyMBR(void) {return protectiveMBR.Verify();}
int FindHybridMismatches(void);
int FindOverlaps(void);
int FindInsanePartitions(void);
@@ -162,6 +163,7 @@ public:
int SetPartitionGUID(uint32_t pn, GUIDData theGUID);
void RandomizeGUIDs(void);
int ChangePartType(uint32_t pn, uint16_t hexCode);
+ int ChangePartType(uint32_t pn, PartType theGUID);
void MakeProtectiveMBR(void) {protectiveMBR.MakeProtectiveMBR();}
void RecomputeCHS(void);
int Align(uint64_t* sector);
diff --git a/mbr.cc b/mbr.cc
index 3a5aec4..e0e92a3 100644
--- a/mbr.cc
+++ b/mbr.cc
@@ -535,6 +535,44 @@ int MBRData::LBAtoCHS(uint64_t lba, uint8_t * chs) {
return (retval);
} // MBRData::LBAtoCHS()
+// Look for problems -- overlapping partitions, etc.
+int MBRData::Verify(void) {
+ int i, j, theyOverlap, numProbs = 0, numEE = 0;
+ uint32_t firstLBA1, firstLBA2, lastLBA1, lastLBA2;
+
+ for (i = 0; i < MAX_MBR_PARTS; i++) {
+ for (j = i + 1; j < MAX_MBR_PARTS; j++) {
+ theyOverlap = 0;
+ firstLBA1 = partitions[i].firstLBA;
+ firstLBA2 = partitions[j].firstLBA;
+ if ((firstLBA1 != 0) && (firstLBA2 != 0)) {
+ lastLBA1 = partitions[i].firstLBA + partitions[i].lengthLBA - 1;
+ lastLBA2 = partitions[j].firstLBA + partitions[j].lengthLBA - 1;
+ if ((firstLBA1 < lastLBA2) && (lastLBA1 >= firstLBA2))
+ theyOverlap = 1;
+ if ((firstLBA2 < lastLBA1) && (lastLBA2 >= firstLBA1))
+ theyOverlap = 1;
+ } // if
+ if (theyOverlap) {
+ numProbs++;
+ cout << "\nProblem: MBR partitions " << i + 1 << " and " << j + 1
+ << " overlap!\n";
+ } // if
+ } // for (j...)
+ if (partitions[i].partitionType == 0xEE) {
+ numEE++;
+ if (partitions[i].firstLBA != 1)
+ cout << "\nWarning: 0xEE partition doesn't start on sector 1. This can cause problems\n"
+ << "in some OSes.\n";
+ } // if
+ } // for (i...)
+ if (numEE > 1)
+ cout << "\nCaution: More than one 0xEE MBR partition found. This can cause problems\n"
+ << "in some OSes.\n";
+
+ return numProbs;
+} // MBRData::Verify()
+
/*****************************************************
* *
* Functions to create, delete, or change partitions *
diff --git a/mbr.h b/mbr.h
index a8e348e..b434ac0 100644
--- a/mbr.h
+++ b/mbr.h
@@ -110,6 +110,7 @@ public:
void SetHybrid(void) {state = hybrid;} // Set hybrid flag
void SetCHSGeom(uint32_t h, uint32_t s);
int LBAtoCHS(uint64_t lba, uint8_t * chs); // Convert LBA to CHS
+ int Verify(void);
// Functions to create, delete, or change partitions
// Pass EmptyMBR 1 to clear the boot loader code, 0 to leave it intact
diff --git a/partnotes.cc b/partnotes.cc
index c7954e7..1edd5b8 100644
--- a/partnotes.cc
+++ b/partnotes.cc
@@ -451,8 +451,28 @@ int PartNotes::IsLegal(void) {
* *
*************************************************************************/
+// Remove duplicate partitions from the list.
+void PartNotes::RemoveDuplicates(void) {
+ struct PartInfo *n1, *n2;
+
+ n1 = notes;
+ while (n1 != NULL) {
+ n2 = n1->next;
+ while (n2 != NULL) {
+ if ((n1->firstLBA == n2->firstLBA) && (n1->lastLBA == n2->lastLBA)) {
+ n1->next = n2->next;
+ delete n2;
+ n2 = n1->next;
+ } else {
+ n2 = n2->next;
+ } // if/else
+ } // while (n2 != NULL)
+ n1 = n1->next;
+ } // while (n1 != NULL)
+} // PartNotes::RemoveDuplicates()
+
// Creates a legal mix of primaries and logicals, maximizing the number
-// of included partitions.
+// of included partitions. Also removes duplicates.
// Returns 1 if successful, 0 if not (if missing notes list, say)
int PartNotes::MakeItLegal(void) {
struct PartInfo *theNote, *lastPrimary;
@@ -460,6 +480,8 @@ int PartNotes::MakeItLegal(void) {
if (notes == NULL)
return 0;
+ RemoveDuplicates();
+
if (!IsLegal()) {
// Start by eliminating or converting excessive extended partitions...
while (GetNumExtended() > 1)
diff --git a/partnotes.h b/partnotes.h
index 31b850c..735e1df 100644
--- a/partnotes.h
+++ b/partnotes.h
@@ -89,6 +89,7 @@ class PartNotes {
int IsLegal(void); // returns boolean
// Manipulate data or metadata
+ void RemoveDuplicates(void);
int MakeItLegal(void);
void TrimSmallestExtended(void);
diff --git a/sgdisk.8 b/sgdisk.8
index 4794faf..dfdd9a7 100644
--- a/sgdisk.8
+++ b/sgdisk.8
@@ -369,9 +369,10 @@ changes. Such changes will be reflected in your device filenames, so you
may need to edit \fI/etc/fstab\fR if you use this option.
.TP
-.B \-t, \-\-typecode=partnum:hexcode
-Change a single partition's type code. You enter the type code using a
-two\-byte hexadecimal number, as described earlier.
+.B \-t, \-\-typecode=partnum:{hexcode|GUID}
+Change a single partition's type code. You enter the type code using either
+a two\-byte hexadecimal number, as described earlier, or a fully-specified
+GUID value, such as EBD0A0A2-B9E5-4433-87C0-68B6B72699C7.
.TP
.B \-T, \-\-transform\-bsd=partnum
diff --git a/sgdisk.cc b/sgdisk.cc
index 3927d26..612c526 100644
--- a/sgdisk.cc
+++ b/sgdisk.cc
@@ -43,7 +43,7 @@ int main(int argc, char *argv[]) {
char *newPartInfo = NULL, *typeCode = NULL, *partName = NULL;
char *backupFile = NULL, *twoParts = NULL, *hybrids = NULL, *mbrParts;
char *partGUID = NULL, *diskGUID = NULL, *outDevice = NULL;
- string cmd;
+ string cmd, typeGUID;
PartType typeHelper;
poptContext poptCon;
@@ -75,7 +75,7 @@ int main(int argc, char *argv[]) {
{"replicate", 'R', POPT_ARG_STRING, &outDevice, 'R', "replicate partition table", "device_filename"},
{"sort", 's', POPT_ARG_NONE, NULL, 's', "sort partition table entries", ""},
{"resize-table", 'S', POPT_ARG_INT, &tableSize, 'S', "resize partition table", "numparts"},
- {"typecode", 't', POPT_ARG_STRING, &typeCode, 't', "change partition type code", "partnum:hexcode"},
+ {"typecode", 't', POPT_ARG_STRING, &typeCode, 't', "change partition type code", "partnum:{hexcode|GUID}"},
{"transform-bsd", 'T', POPT_ARG_INT, &bsdPartNum, 'T', "transform BSD disklabel partition to GPT", "partnum"},
{"partition-guid", 'u', POPT_ARG_STRING, &partGUID, 'u', "set partition GUID", "partnum:guid"},
{"disk-guid", 'U', POPT_ARG_STRING, &diskGUID, 'U', "set disk GUID", "guid"},
@@ -305,12 +305,18 @@ int main(int argc, char *argv[]) {
case 't':
theGPT.JustLooking(0);
partNum = (int) GetInt(typeCode, 1) - 1;
- sscanf(GetString(typeCode, 2).c_str(), "%x", &hexCode);
- if (theGPT.ChangePartType(partNum, hexCode)) {
+ cout << "Got string '" << GetString(typeCode, 2) << "'\n";
+ if (GetString(typeCode, 2).length() < 10) {
+ sscanf(GetString(typeCode, 2).c_str(), "%x", &hexCode);
+ typeHelper = hexCode;
+ } else {
+ typeHelper = GetString(typeCode, 2);
+ } // if/else hexCode or GUID
+ if (theGPT.ChangePartType(partNum, typeHelper)) {
saveData = 1;
} else {
cerr << "Could not change partition " << partNum + 1
- << "'s type code to " << hex << hexCode << "!\n" << dec;
+ << "'s type code to " << GetString(typeCode, 2) << "!\n";
neverSaveData = 1;
} // if/else
free(typeCode);
@@ -370,7 +376,7 @@ int main(int argc, char *argv[]) {
while ((opt = poptGetNextOpt(poptCon)) > 0) {
switch (opt) {
case 'v':
- cout << "Verification may miss some problems!\n";
+ cout << "Verification may miss some problems or report too many!\n";
theGPT.Verify();
break;
case 'z':