Version 0.6.0 release; adds support for >512-byte sectors, sgdisk

program.
This commit is contained in:
srs5694
2010-01-15 19:19:18 -05:00
parent ba00fed2ef
commit 3c0af38237
7 changed files with 80 additions and 60 deletions

View File

@@ -1,7 +1,7 @@
CC=gcc CC=gcc
CXX=g++ CXX=g++
CFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -g CFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -g
CXXFLAGS=-O2 -Wuninitialized -Wreturn-type -D_FILE_OFFSET_BITS=64 -I/opt/local/include -g CXXFLAGS=-O2 -Wuninitialized -Wreturn-type -D_FILE_OFFSET_BITS=64 -I /usr/local/include -I/opt/local/include -g
LIB_NAMES=crc32 support gptpart mbr gpt bsd parttypes attributes LIB_NAMES=crc32 support gptpart mbr gpt bsd parttypes attributes
LIB_SRCS=$(NAMES:=.cc) LIB_SRCS=$(NAMES:=.cc)
LIB_OBJS=$(LIB_NAMES:=.o) LIB_OBJS=$(LIB_NAMES:=.o)
@@ -17,7 +17,7 @@ gdisk: $(LIB_OBJS) gdisk.o
$(CXX) $(LIB_OBJS) gdisk.o -o gdisk $(CXX) $(LIB_OBJS) gdisk.o -o gdisk
sgdisk: $(LIB_OBJS) sgdisk.o sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -lpopt -o sgdisk $(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -L/usr/local/lib -lpopt -o sgdisk
wipegpt: $(LIB_OBJS) wipegpt.o wipegpt: $(LIB_OBJS) wipegpt.o
$(CXX) $(LIB_OBJS) wipegpt.o -o wipegpt $(CXX) $(LIB_OBJS) wipegpt.o -o wipegpt

36
README
View File

@@ -7,8 +7,8 @@ Introduction
This software is intended as a (somewhat) fdisk-workalike program for This software is intended as a (somewhat) fdisk-workalike program for
GPT-partitioned disks. Although libparted and programs that use it (GNU GPT-partitioned disks. Although libparted and programs that use it (GNU
Parted, gparted, etc.) provide the ability to handle GPT disks, they have Parted, gparted, etc.) provide the ability to handle GPT disks, they have
certain limitations that gdisk overcomes. Specific advantages of gdisk certain limitations that gdisk overcomes. Specific advantages of gdisk and
include: sgdisk include:
* The ability to convert MBR-partitioned disks in-place to GPT format, * The ability to convert MBR-partitioned disks in-place to GPT format,
without losing data without losing data
@@ -25,7 +25,7 @@ include:
disk disk
* A user interface that's familiar to long-time users of Linux * A user interface that's familiar to long-time users of Linux
fdisk fdisk (gdisk only)
* The MBR boot loader code is left alone (GNU Parted tends to * The MBR boot loader code is left alone (GNU Parted tends to
wipe it out with every change) wipe it out with every change)
@@ -33,25 +33,31 @@ include:
* The ability to create a hybrid MBR, which permits GPT-unaware * The ability to create a hybrid MBR, which permits GPT-unaware
OSes to access up to three GPT partitions on the disk OSes to access up to three GPT partitions on the disk
Of course, gdisk isn't without its limitations. Most notably, it lacks the Of course, GPT fdisk isn't without its limitations. Most notably, it lacks
filesystem awareness and filesystem-related features of GNU Parted. You the filesystem awareness and filesystem-related features of GNU Parted. You
can't resize a partition's filesystem or create a partition with a can't resize a partition's filesystem or create a partition with a
filesystem already in place with gdisk, for instance. There's no GUI filesystem already in place with gdisk, for instance. There's no GUI
version of gdisk. version of gdisk.
The GPT fdisk package provides two program files: the interactive text-mode
gdisk and the command-line-driven sgdisk. The former is intended for use in
manually partitioning disks or changing partitioning details; the latter is
intended for use in scripts to help automate tasks such as disk cloning or
preparing multiple disks for Linux installation.
Installing Installing
---------- ----------
To compile gdisk, you must have appropriate development tools installed, To compile GPT fdisk, you must have appropriate development tools
most notably the GNU Compiler Collection (GCC) and its g++ compiler for installed, most notably the GNU Compiler Collection (GCC) and its g++
C++. The sgdisk program also requires the popt library and its development compiler for C++. The sgdisk program also requires the popt library and its
files (headers). Most Linux distributions install popt by default, but you development files (headers). Most Linux distributions install popt by
may need to install a package called popt-dev, popt-devel, or something default, but you may need to install a package called popt-dev, popt-devel,
similar to obtain the development libraries. Mac OS users can find a version or something similar to obtain the header files. Mac OS users can find a
of popt for Mac OS from http://popt.darwinports.com; however, you'll first version of popt for Mac OS from http://popt.darwinports.com; however,
need to install DarwinPorts (instructions exist on the preceding page). you'll first need to install DarwinPorts (instructions exist on the
Alternatively, you can compile gdisk alone, without sgdisk; gdisk doesn't preceding page). Alternatively, you can compile gdisk alone, without
require popt. sgdisk; gdisk doesn't require popt.
When all the necessary development tools and libraries are installed, you When all the necessary development tools and libraries are installed, you
can uncompress the package and type "make" at the command prompt in the can uncompress the package and type "make" at the command prompt in the

View File

@@ -28,7 +28,7 @@ int main(int argc, char* argv[]) {
int doMore = 1; int doMore = 1;
char* device = NULL; char* device = NULL;
printf("GPT fdisk (gdisk) version 0.5.4-pre1\n\n"); printf("GPT fdisk (gdisk) version %s\n\n", GPTFDISK_VERSION);
if (argc == 2) { // basic usage if (argc == 2) { // basic usage
if (SizesOK()) { if (SizesOK()) {

85
gpt.cc
View File

@@ -74,7 +74,8 @@ GPTData::GPTData(char* filename) {
whichWasUsed = use_new; whichWasUsed = use_new;
srand((unsigned int) time(NULL)); srand((unsigned int) time(NULL));
mainHeader.numParts = 0; mainHeader.numParts = 0;
LoadPartitions(filename); if (!LoadPartitions(filename))
exit(2);
} // GPTData(char* filename) constructor } // GPTData(char* filename) constructor
// Destructor // Destructor
@@ -573,6 +574,10 @@ int GPTData::LoadPartitions(char* deviceFilename) {
ClearGPTData(); ClearGPTData();
protectiveMBR.MakeProtectiveMBR(); protectiveMBR.MakeProtectiveMBR();
break; break;
case use_abort:
allOK = 0;
printf("Aborting because of invalid partition data!\n");
break;
} // switch } // switch
// Now find the first and last sectors used by partitions... // Now find the first and last sectors used by partitions...
@@ -586,8 +591,8 @@ int GPTData::LoadPartitions(char* deviceFilename) {
if (partitions[i].GetLastLBA() > lastBlock) if (partitions[i].GetLastLBA() > lastBlock)
lastBlock = partitions[i].GetLastLBA(); lastBlock = partitions[i].GetLastLBA();
} // for } // for
CheckGPTSize();
} // if } // if
CheckGPTSize();
} else { } else {
allOK = 0; allOK = 0;
fprintf(stderr, "Problem opening %s for reading! Error is %d\n", fprintf(stderr, "Problem opening %s for reading! Error is %d\n",
@@ -1427,12 +1432,14 @@ WhichToUse GPTData::UseWhichPartitions(void) {
} // if } // if
if ((state == gpt_valid) && (mbrState == gpt)) { if ((state == gpt_valid) && (mbrState == gpt)) {
printf("Found valid GPT with protective MBR; using GPT.\n");
which = use_gpt; which = use_gpt;
if (!beQuiet)
printf("Found valid GPT with protective MBR; using GPT.\n");
} // if } // if
if ((state == gpt_valid) && (mbrState == hybrid)) { if ((state == gpt_valid) && (mbrState == hybrid)) {
printf("Found valid GPT with hybrid MBR; using GPT.\n");
which = use_gpt; which = use_gpt;
if (!beQuiet)
printf("Found valid GPT with hybrid MBR; using GPT.\n");
} // if } // if
if ((state == gpt_valid) && (mbrState == invalid)) { if ((state == gpt_valid) && (mbrState == invalid)) {
printf("\aFound valid GPT with corrupt MBR; using GPT and will create new\nprotective MBR on save.\n"); printf("\aFound valid GPT with corrupt MBR; using GPT and will create new\nprotective MBR on save.\n");
@@ -1440,44 +1447,50 @@ WhichToUse GPTData::UseWhichPartitions(void) {
protectiveMBR.MakeProtectiveMBR(); protectiveMBR.MakeProtectiveMBR();
} // if } // if
if ((state == gpt_valid) && (mbrState == mbr)) { if ((state == gpt_valid) && (mbrState == mbr)) {
printf("Found valid MBR and GPT. Which do you want to use?\n"); if (!beQuiet) {
answer = GetNumber(1, 3, 2, (char*) " 1 - MBR\n 2 - GPT\n 3 - Create blank GPT\n\nYour answer: "); printf("Found valid MBR and GPT. Which do you want to use?\n");
if (answer == 1) { answer = GetNumber(1, 3, 2, (char*) " 1 - MBR\n 2 - GPT\n 3 - Create blank GPT\n\nYour answer: ");
which = use_mbr; if (answer == 1) {
} else if (answer == 2) { which = use_mbr;
which = use_gpt; } else if (answer == 2) {
protectiveMBR.MakeProtectiveMBR(); which = use_gpt;
printf("Using GPT and creating fresh protective MBR.\n"); protectiveMBR.MakeProtectiveMBR();
} else which = use_new; printf("Using GPT and creating fresh protective MBR.\n");
} else which = use_new;
} else which = use_abort;
} // if } // if
// Nasty decisions here -- GPT is present, but corrupt (bad CRCs or other // Nasty decisions here -- GPT is present, but corrupt (bad CRCs or other
// problems) // problems)
if (state == gpt_corrupt) { if (state == gpt_corrupt) {
if ((mbrState == mbr) || (mbrState == hybrid)) { if (beQuiet) {
printf("Found valid MBR and corrupt GPT. Which do you want to use? (Using the\n" which = use_abort;
"GPT MAY permit recovery of GPT data.)\n"); } else {
answer = GetNumber(1, 3, 2, (char*) " 1 - MBR\n 2 - GPT\n 3 - Create blank GPT\n\nYour answer: "); if ((mbrState == mbr) || (mbrState == hybrid)) {
if (answer == 1) { printf("Found valid MBR and corrupt GPT. Which do you want to use? (Using the\n"
which = use_mbr; "GPT MAY permit recovery of GPT data.)\n");
// protectiveMBR.MakeProtectiveMBR(); answer = GetNumber(1, 3, 2, (char*) " 1 - MBR\n 2 - GPT\n 3 - Create blank GPT\n\nYour answer: ");
} else if (answer == 2) { if (answer == 1) {
which = use_mbr;
// protectiveMBR.MakeProtectiveMBR();
} else if (answer == 2) {
which = use_gpt;
} else which = use_new;
} else if (mbrState == invalid) {
printf("Found invalid MBR and corrupt GPT. What do you want to do? (Using the\n"
"GPT MAY permit recovery of GPT data.)\n");
answer = GetNumber(1, 2, 1, (char*) " 1 - GPT\n 2 - Create blank GPT\n\nYour answer: ");
if (answer == 1) {
which = use_gpt;
} else which = use_new;
} else { // corrupt GPT, MBR indicates it's a GPT disk....
printf("\a\a****************************************************************************\n"
"Caution: Found protective or hybrid MBR and corrupt GPT. Using GPT, but disk\n"
"verification and recovery are STRONGLY recommended.\n"
"****************************************************************************\n");
which = use_gpt; which = use_gpt;
} else which = use_new; } // if/else/else
} else if (mbrState == invalid) { } // else (beQuiet)
printf("Found invalid MBR and corrupt GPT. What do you want to do? (Using the\n"
"GPT MAY permit recovery of GPT data.)\n");
answer = GetNumber(1, 2, 1, (char*) " 1 - GPT\n 2 - Create blank GPT\n\nYour answer: ");
if (answer == 1) {
which = use_gpt;
} else which = use_new;
} else { // corrupt GPT, MBR indicates it's a GPT disk....
printf("\a\a****************************************************************************\n"
"Caution: Found protective or hybrid MBR and corrupt GPT. Using GPT, but disk\n"
"verification and recovery are STRONGLY recommended.\n"
"****************************************************************************\n");
which = use_gpt;
} // if/else/else
} // if (corrupt GPT) } // if (corrupt GPT)
if (which == use_new) if (which == use_new)

3
gpt.h
View File

@@ -16,6 +16,7 @@
#ifndef __GPTSTRUCTS #ifndef __GPTSTRUCTS
#define __GPTSTRUCTS #define __GPTSTRUCTS
#define GPTFDISK_VERSION "0.6.0"
using namespace std; using namespace std;
@@ -29,7 +30,7 @@ using namespace std;
enum GPTValidity {gpt_valid, gpt_corrupt, gpt_invalid}; enum GPTValidity {gpt_valid, gpt_corrupt, gpt_invalid};
// Which set of partition data to use // Which set of partition data to use
enum WhichToUse {use_gpt, use_mbr, use_bsd, use_new}; enum WhichToUse {use_gpt, use_mbr, use_bsd, use_new, use_abort};
// Header (first 512 bytes) of GPT table // Header (first 512 bytes) of GPT table
#pragma pack(1) #pragma pack(1)

View File

@@ -206,9 +206,9 @@ sectors are available, this function returns the value 0.
.TP .TP
.B \-g, \-\-mbrtogpt .B \-g, \-\-mbrtogpt
Convert an MBR disk to a GPT disk. As a safety measure, use of this option Convert an MBR or BSD disklabel disk to a GPT disk. As a safety measure, use of
is required on MBR or BSD disklabel disks if you intend to save your changes, this option is required on MBR or BSD disklabel disks if you intend to save your
in order to prevent accidentally damaging such disks. changes, in order to prevent accidentally damaging such disks.
.TP .TP
.B \-i, \-\-info=partnum .B \-i, \-\-info=partnum
@@ -342,7 +342,7 @@ Normal program execution
Too few arguments Too few arguments
.TP .TP
.B 4 .B 2
An error occurred while reading the partition table An error occurred while reading the partition table
.TP .TP

View File

@@ -87,7 +87,7 @@ int main(int argc, char *argv[]) {
pretend = 1; pretend = 1;
break; break;
case 'V': case 'V':
printf("GPT fdisk (sgdisk) version 0.5.4-pre1\n\n"); printf("GPT fdisk (sgdisk) version %s\n\n", GPTFDISK_VERSION);
break; break;
default: default:
break; break;