Add end-alignment feature.
This commit is contained in:
10
NEWS
10
NEWS
@@ -1,9 +1,17 @@
|
|||||||
1.0.9 (?/?/2021):
|
1.0.9 (?/?/2022):
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
- Removed stray debugging code that caused "partNum is {x}" to be printed
|
- Removed stray debugging code that caused "partNum is {x}" to be printed
|
||||||
when changing a partition's name with sgdisk (-c/--change-name).
|
when changing a partition's name with sgdisk (-c/--change-name).
|
||||||
|
|
||||||
|
- Added support for aligning partitions' end points, as well as their start
|
||||||
|
points. This support affects the default partition size when using 'n' in
|
||||||
|
gdisk; it affects the default partition size in cgdisk; and it's activated
|
||||||
|
by the new '-I' option in sgdisk. See the programs' respective man pages
|
||||||
|
for details. This feature is intended to help with LUKS2 encryption, which
|
||||||
|
reacts badly to partitions that are not sized as exact multiples of the
|
||||||
|
encryption block size.
|
||||||
|
|
||||||
1.0.8 (6/9/2021):
|
1.0.8 (6/9/2021):
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|||||||
9
cgdisk.8
9
cgdisk.8
@@ -186,8 +186,13 @@ new disks, GPT fdisk attempts to align partitions on 1 MiB boundaries
|
|||||||
performance for all of these disk types. On pre\-partitioned disks, GPT
|
performance for all of these disk types. On pre\-partitioned disks, GPT
|
||||||
fdisk attempts to identify the alignment value used on that disk, but will
|
fdisk attempts to identify the alignment value used on that disk, but will
|
||||||
set 8-sector alignment on disks larger than 300 GB even if lesser alignment
|
set 8-sector alignment on disks larger than 300 GB even if lesser alignment
|
||||||
values are detected. In either case, it can be changed by using this
|
values are detected. In either case, it can be changed by using this option.
|
||||||
option.
|
The alignment value also affects the default end sector value when creating
|
||||||
|
a new partition; it will be aligned to one less than a multiple of the
|
||||||
|
alignment value, when possible. This should keep partitions a multiple of
|
||||||
|
the alignment value in size. Some disk encryption tools require partitions
|
||||||
|
to be sized to some value, typically 4096 bytes, so the default alignment of
|
||||||
|
1 MiB works well for them.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B Backup
|
.B Backup
|
||||||
|
|||||||
16
gdisk.8
16
gdisk.8
@@ -210,7 +210,8 @@ default start sector, or \fI\fB\-200M\fR\fR to specify a point 200MiB
|
|||||||
before the last available sector. Pressing the Enter key with no input
|
before the last available sector. Pressing the Enter key with no input
|
||||||
specifies the default value, which is the start of the largest available
|
specifies the default value, which is the start of the largest available
|
||||||
block for the start sector and the end of the same block for the end
|
block for the start sector and the end of the same block for the end
|
||||||
sector.
|
sector. Default start and end points may be adjusted to optimize partition
|
||||||
|
alignment.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B o
|
.B o
|
||||||
@@ -491,13 +492,18 @@ Change the sector alignment value. Disks with more logical sectors per
|
|||||||
physical sectors (such as modern Advanced Format drives), some RAID
|
physical sectors (such as modern Advanced Format drives), some RAID
|
||||||
configurations, and many SSD devices, can suffer performance problems if
|
configurations, and many SSD devices, can suffer performance problems if
|
||||||
partitions are not aligned properly for their internal data structures. On
|
partitions are not aligned properly for their internal data structures. On
|
||||||
new disks, GPT fdisk attempts to align partitions on 1 MiB boundaries
|
new disks, GPT fdisk attempts to align partitions on 1 MiB boundaries (2048
|
||||||
(2048\-sectors on disks with 512-byte sectors) by default, which optimizes
|
sectors on disks with 512-byte sectors) by default, which optimizes
|
||||||
performance for all of these disk types. On pre\-partitioned disks, GPT
|
performance for all of these disk types. On pre\-partitioned disks, GPT
|
||||||
fdisk attempts to identify the alignment value used on that disk, but will
|
fdisk attempts to identify the alignment value used on that disk, but will
|
||||||
set 8-sector alignment on disks larger than 300 GB even if lesser alignment
|
set 8-sector alignment on disks larger than 300 GB even if lesser alignment
|
||||||
values are detected. In either case, it can be changed by using this
|
values are detected. In either case, it can be changed by using this option.
|
||||||
option.
|
The alignment value also affects the default end sector value when creating
|
||||||
|
a new partition; it will be aligned to one less than a multiple of the
|
||||||
|
alignment value, if possible. This should keep partitions a multiple of the
|
||||||
|
alignment value in size. Some disk encryption tools require partitions to be
|
||||||
|
sized to some value, typically 4096 bytes, so the default alignment of 1 MiB
|
||||||
|
works well for them.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B m
|
.B m
|
||||||
|
|||||||
34
gpt.cc
34
gpt.cc
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
/* By Rod Smith, initial coding January to February, 2009 */
|
/* By Rod Smith, initial coding January to February, 2009 */
|
||||||
|
|
||||||
/* This program is copyright (c) 2009-2018 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2022 by Roderick W. Smith. It is distributed
|
||||||
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
@@ -410,6 +410,11 @@ int GPTData::Verify(void) {
|
|||||||
<< "in degraded performance on some modern (2009 and later) hard disks.\n";
|
<< "in degraded performance on some modern (2009 and later) hard disks.\n";
|
||||||
alignProbs++;
|
alignProbs++;
|
||||||
} // if
|
} // if
|
||||||
|
if ((partitions[i].IsUsed()) && ((partitions[i].GetLastLBA() + 1) % testAlignment) != 0) {
|
||||||
|
cout << "\nCaution: Partition " << i + 1 << " doesn't end on a "
|
||||||
|
<< testAlignment << "-sector boundary. This may\nresult "
|
||||||
|
<< "in problems with some disk encryption tools.\n";
|
||||||
|
} // if
|
||||||
} // for
|
} // for
|
||||||
if (alignProbs > 0)
|
if (alignProbs > 0)
|
||||||
cout << "\nConsult http://www.ibm.com/developerworks/linux/library/l-4kb-sector-disks/\n"
|
cout << "\nConsult http://www.ibm.com/developerworks/linux/library/l-4kb-sector-disks/\n"
|
||||||
@@ -2334,18 +2339,28 @@ uint64_t GPTData::FindLastAvailable(void) {
|
|||||||
} // GPTData::FindLastAvailable()
|
} // GPTData::FindLastAvailable()
|
||||||
|
|
||||||
// Find the last available block in the free space pointed to by start.
|
// Find the last available block in the free space pointed to by start.
|
||||||
uint64_t GPTData::FindLastInFree(uint64_t start) {
|
// If align == true, returns the last sector that's aligned on the
|
||||||
uint64_t nearestStart;
|
// system alignment value (unless that's less than the start value);
|
||||||
|
// if align == false, returns the last available block regardless of
|
||||||
|
// alignment. (The align variable is set to false by default.)
|
||||||
|
uint64_t GPTData::FindLastInFree(uint64_t start, bool align) {
|
||||||
|
uint64_t nearestEnd, endPlus;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
nearestStart = mainHeader.lastUsableLBA;
|
nearestEnd = mainHeader.lastUsableLBA;
|
||||||
for (i = 0; i < numParts; i++) {
|
for (i = 0; i < numParts; i++) {
|
||||||
if ((nearestStart > partitions[i].GetFirstLBA()) &&
|
if ((nearestEnd > partitions[i].GetFirstLBA()) &&
|
||||||
(partitions[i].GetFirstLBA() > start)) {
|
(partitions[i].GetFirstLBA() > start)) {
|
||||||
nearestStart = partitions[i].GetFirstLBA() - 1;
|
nearestEnd = partitions[i].GetFirstLBA() - 1;
|
||||||
} // if
|
} // if
|
||||||
} // for
|
} // for
|
||||||
return (nearestStart);
|
if (align) {
|
||||||
|
endPlus = nearestEnd + 1;
|
||||||
|
if (Align(&endPlus) && IsFree(endPlus - 1) && (endPlus > start)) {
|
||||||
|
nearestEnd = endPlus - 1;
|
||||||
|
} // if
|
||||||
|
} // if
|
||||||
|
return (nearestEnd);
|
||||||
} // GPTData::FindLastInFree()
|
} // GPTData::FindLastInFree()
|
||||||
|
|
||||||
// Finds the total number of free blocks, the number of segments in which
|
// Finds the total number of free blocks, the number of segments in which
|
||||||
@@ -2422,7 +2437,10 @@ int GPTData::IsUsedPartNum(uint32_t partNum) {
|
|||||||
***********************************************************/
|
***********************************************************/
|
||||||
|
|
||||||
// Set partition alignment value; partitions will begin on multiples of
|
// Set partition alignment value; partitions will begin on multiples of
|
||||||
// the specified value
|
// the specified value, and the default end values will be set so that
|
||||||
|
// partition sizes are multiples of this value in cgdisk and gdisk, too.
|
||||||
|
// (In sgdisk, end-alignment is done only if the '-I' command-line option
|
||||||
|
// is used.)
|
||||||
void GPTData::SetAlignment(uint32_t n) {
|
void GPTData::SetAlignment(uint32_t n) {
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
sectorAlignment = n;
|
sectorAlignment = n;
|
||||||
|
|||||||
4
gpt.h
4
gpt.h
@@ -1,7 +1,7 @@
|
|||||||
/* gpt.h -- GPT and data structure definitions, types, and
|
/* gpt.h -- GPT and data structure definitions, types, and
|
||||||
functions */
|
functions */
|
||||||
|
|
||||||
/* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2022 by Roderick W. Smith. It is distributed
|
||||||
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#ifndef __GPTSTRUCTS
|
#ifndef __GPTSTRUCTS
|
||||||
@@ -185,7 +185,7 @@ public:
|
|||||||
uint64_t FindFirstUsedLBA(void);
|
uint64_t FindFirstUsedLBA(void);
|
||||||
uint64_t FindFirstInLargest(void);
|
uint64_t FindFirstInLargest(void);
|
||||||
uint64_t FindLastAvailable();
|
uint64_t FindLastAvailable();
|
||||||
uint64_t FindLastInFree(uint64_t start);
|
uint64_t FindLastInFree(uint64_t start, bool align = false);
|
||||||
uint64_t FindFreeBlocks(uint32_t *numSegments, uint64_t *largestSegment);
|
uint64_t FindFreeBlocks(uint32_t *numSegments, uint64_t *largestSegment);
|
||||||
int IsFree(uint64_t sector, uint32_t *partNum = NULL);
|
int IsFree(uint64_t sector, uint32_t *partNum = NULL);
|
||||||
int IsFreePartNum(uint32_t partNum);
|
int IsFreePartNum(uint32_t partNum);
|
||||||
|
|||||||
15
gptcl.cc
15
gptcl.cc
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Implementation of GPTData class derivative with popt-based command
|
Implementation of GPTData class derivative with popt-based command
|
||||||
line processing
|
line processing
|
||||||
Copyright (C) 2010-2014 Roderick W. Smith
|
Copyright (C) 2010-2022 Roderick W. Smith
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -30,6 +30,7 @@ GPTDataCL::GPTDataCL(void) {
|
|||||||
attributeOperation = backupFile = partName = hybrids = newPartInfo = NULL;
|
attributeOperation = backupFile = partName = hybrids = newPartInfo = NULL;
|
||||||
mbrParts = twoParts = outDevice = typeCode = partGUID = diskGUID = NULL;
|
mbrParts = twoParts = outDevice = typeCode = partGUID = diskGUID = NULL;
|
||||||
alignment = DEFAULT_ALIGNMENT;
|
alignment = DEFAULT_ALIGNMENT;
|
||||||
|
alignEnd = false;
|
||||||
deletePartNum = infoPartNum = largestPartNum = bsdPartNum = 0;
|
deletePartNum = infoPartNum = largestPartNum = bsdPartNum = 0;
|
||||||
tableSize = GPT_SIZE;
|
tableSize = GPT_SIZE;
|
||||||
} // GPTDataCL constructor
|
} // GPTDataCL constructor
|
||||||
@@ -90,6 +91,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) {
|
|||||||
{"randomize-guids", 'G', POPT_ARG_NONE, NULL, 'G', "randomize disk and partition GUIDs", ""},
|
{"randomize-guids", 'G', POPT_ARG_NONE, NULL, 'G', "randomize disk and partition GUIDs", ""},
|
||||||
{"hybrid", 'h', POPT_ARG_STRING, &hybrids, 'h', "create hybrid MBR", "partnum[:partnum...][:EE]"},
|
{"hybrid", 'h', POPT_ARG_STRING, &hybrids, 'h', "create hybrid MBR", "partnum[:partnum...][:EE]"},
|
||||||
{"info", 'i', POPT_ARG_INT, &infoPartNum, 'i', "show detailed information on partition", "partnum"},
|
{"info", 'i', POPT_ARG_INT, &infoPartNum, 'i', "show detailed information on partition", "partnum"},
|
||||||
|
{"align-end", 'I', POPT_ARG_NONE, NULL, 'I', "align partition end points", ""},
|
||||||
{"move-main-table", 'j', POPT_ARG_INT, &mainTableLBA, 'j', "adjust the location of the main partition table", "sector"},
|
{"move-main-table", 'j', POPT_ARG_INT, &mainTableLBA, 'j', "adjust the location of the main partition table", "sector"},
|
||||||
{"load-backup", 'l', POPT_ARG_STRING, &backupFile, 'l', "load GPT backup from file", "file"},
|
{"load-backup", 'l', POPT_ARG_STRING, &backupFile, 'l', "load GPT backup from file", "file"},
|
||||||
{"list-types", 'L', POPT_ARG_NONE, NULL, 'L', "list known partition types", ""},
|
{"list-types", 'L', POPT_ARG_NONE, NULL, 'L', "list known partition types", ""},
|
||||||
@@ -272,6 +274,9 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) {
|
|||||||
case 'i':
|
case 'i':
|
||||||
ShowPartDetails(infoPartNum - 1);
|
ShowPartDetails(infoPartNum - 1);
|
||||||
break;
|
break;
|
||||||
|
case 'I':
|
||||||
|
alignEnd = true;
|
||||||
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
if (MoveMainTable(mainTableLBA)) {
|
if (MoveMainTable(mainTableLBA)) {
|
||||||
JustLooking(0);
|
JustLooking(0);
|
||||||
@@ -307,9 +312,9 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) {
|
|||||||
newPartNum = FindFirstFreePart();
|
newPartNum = FindFirstFreePart();
|
||||||
low = FindFirstInLargest();
|
low = FindFirstInLargest();
|
||||||
Align(&low);
|
Align(&low);
|
||||||
high = FindLastInFree(low);
|
high = FindLastInFree(low, alignEnd);
|
||||||
startSector = IeeeToInt(GetString(newPartInfo, 2), sSize, low, high, low);
|
startSector = IeeeToInt(GetString(newPartInfo, 2), sSize, low, high, sectorAlignment, low);
|
||||||
endSector = IeeeToInt(GetString(newPartInfo, 3), sSize, startSector, high, high);
|
endSector = IeeeToInt(GetString(newPartInfo, 3), sSize, startSector, high, sectorAlignment, high);
|
||||||
if (CreatePartition(newPartNum, startSector, endSector)) {
|
if (CreatePartition(newPartNum, startSector, endSector)) {
|
||||||
saveData = 1;
|
saveData = 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -323,7 +328,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) {
|
|||||||
JustLooking(0);
|
JustLooking(0);
|
||||||
startSector = FindFirstInLargest();
|
startSector = FindFirstInLargest();
|
||||||
Align(&startSector);
|
Align(&startSector);
|
||||||
endSector = FindLastInFree(startSector);
|
endSector = FindLastInFree(startSector, alignEnd);
|
||||||
if (largestPartNum <= 0)
|
if (largestPartNum <= 0)
|
||||||
largestPartNum = FindFirstFreePart() + 1;
|
largestPartNum = FindFirstFreePart() + 1;
|
||||||
if (CreatePartition(largestPartNum - 1, startSector, endSector)) {
|
if (CreatePartition(largestPartNum - 1, startSector, endSector)) {
|
||||||
|
|||||||
3
gptcl.h
3
gptcl.h
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Implementation of GPTData class derivative with popt-based command
|
Implementation of GPTData class derivative with popt-based command
|
||||||
line processing
|
line processing
|
||||||
Copyright (C) 2010-2013 Roderick W. Smith
|
Copyright (C) 2010-2022 Roderick W. Smith
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -34,6 +34,7 @@ class GPTDataCL : public GPTData {
|
|||||||
char *newPartInfo, *mbrParts, *twoParts, *outDevice, *typeCode;
|
char *newPartInfo, *mbrParts, *twoParts, *outDevice, *typeCode;
|
||||||
char *partGUID, *diskGUID;
|
char *partGUID, *diskGUID;
|
||||||
int alignment, deletePartNum, infoPartNum, largestPartNum, bsdPartNum;
|
int alignment, deletePartNum, infoPartNum, largestPartNum, bsdPartNum;
|
||||||
|
bool alignEnd;
|
||||||
uint32_t tableSize;
|
uint32_t tableSize;
|
||||||
poptContext poptCon;
|
poptContext poptCon;
|
||||||
|
|
||||||
|
|||||||
19
gptcurses.cc
19
gptcurses.cc
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Implementation of GPTData class derivative with curses-based text-mode
|
* Implementation of GPTData class derivative with curses-based text-mode
|
||||||
* interaction
|
* interaction
|
||||||
* Copyright (C) 2011-2018 Roderick W. Smith
|
* Copyright (C) 2011-2022 Roderick W. Smith
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -430,12 +430,18 @@ void GPTDataCurses::Verify(void) {
|
|||||||
|
|
||||||
// Create a new partition in the space pointed to by currentSpace.
|
// Create a new partition in the space pointed to by currentSpace.
|
||||||
void GPTDataCurses::MakeNewPart(void) {
|
void GPTDataCurses::MakeNewPart(void) {
|
||||||
uint64_t size, newFirstLBA = 0, newLastLBA = 0;
|
uint64_t size, newFirstLBA = 0, newLastLBA = 0, lastAligned;
|
||||||
int partNum;
|
int partNum;
|
||||||
char inLine[80];
|
char inLine[80];
|
||||||
|
|
||||||
move(LINES - 4, 0);
|
move(LINES - 4, 0);
|
||||||
clrtobot();
|
clrtobot();
|
||||||
|
lastAligned = currentSpace->lastLBA + 1;
|
||||||
|
Align(&lastAligned);
|
||||||
|
lastAligned--;
|
||||||
|
// Discard end-alignment attempt if it's giving us an invalid end point....
|
||||||
|
if (!IsFree(lastAligned))
|
||||||
|
lastAligned = currentSpace->lastLBA;
|
||||||
while ((newFirstLBA < currentSpace->firstLBA) || (newFirstLBA > currentSpace->lastLBA)) {
|
while ((newFirstLBA < currentSpace->firstLBA) || (newFirstLBA > currentSpace->lastLBA)) {
|
||||||
move(LINES - 4, 0);
|
move(LINES - 4, 0);
|
||||||
clrtoeol();
|
clrtoeol();
|
||||||
@@ -445,10 +451,13 @@ void GPTDataCurses::MakeNewPart(void) {
|
|||||||
echo();
|
echo();
|
||||||
getnstr(inLine, 79);
|
getnstr(inLine, 79);
|
||||||
noecho();
|
noecho();
|
||||||
newFirstLBA = IeeeToInt(inLine, blockSize, currentSpace->firstLBA, currentSpace->lastLBA, newFirstLBA);
|
newFirstLBA = IeeeToInt(inLine, blockSize, currentSpace->firstLBA, currentSpace->lastLBA, sectorAlignment, newFirstLBA);
|
||||||
Align(&newFirstLBA);
|
Align(&newFirstLBA);
|
||||||
} // while
|
} // while
|
||||||
size = currentSpace->lastLBA - newFirstLBA + 1;
|
if (newFirstLBA > lastAligned)
|
||||||
|
size = currentSpace->lastLBA - newFirstLBA + 1;
|
||||||
|
else
|
||||||
|
size = lastAligned - newFirstLBA + 1;
|
||||||
while ((newLastLBA > currentSpace->lastLBA) || (newLastLBA < newFirstLBA)) {
|
while ((newLastLBA > currentSpace->lastLBA) || (newLastLBA < newFirstLBA)) {
|
||||||
move(LINES - 3, 0);
|
move(LINES - 3, 0);
|
||||||
clrtoeol();
|
clrtoeol();
|
||||||
@@ -456,7 +465,7 @@ void GPTDataCurses::MakeNewPart(void) {
|
|||||||
echo();
|
echo();
|
||||||
getnstr(inLine, 79);
|
getnstr(inLine, 79);
|
||||||
noecho();
|
noecho();
|
||||||
newLastLBA = newFirstLBA + IeeeToInt(inLine, blockSize, 1, size, size) - 1;
|
newLastLBA = newFirstLBA + IeeeToInt(inLine, blockSize, 1, size, sectorAlignment, size) - 1;
|
||||||
} // while
|
} // while
|
||||||
partNum = FindFirstFreePart();
|
partNum = FindFirstFreePart();
|
||||||
if (CreatePartition(partNum, newFirstLBA, newLastLBA)) { // created OK; set type code & name....
|
if (CreatePartition(partNum, newFirstLBA, newLastLBA)) { // created OK; set type code & name....
|
||||||
|
|||||||
36
gpttext.cc
36
gpttext.cc
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (C) 2010-2018 <Roderick W. Smith>
|
Copyright (C) 2010-2022 <Roderick W. Smith>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -199,7 +199,7 @@ void GPTDataTextUI::MoveMainTable(void) {
|
|||||||
|
|
||||||
// Interactively create a partition
|
// Interactively create a partition
|
||||||
void GPTDataTextUI::CreatePartition(void) {
|
void GPTDataTextUI::CreatePartition(void) {
|
||||||
uint64_t firstBlock, firstInLargest, lastBlock, sector, origSector;
|
uint64_t firstBlock, firstInLargest, lastBlock, sector, origSector, lastAligned;
|
||||||
uint32_t firstFreePart = 0;
|
uint32_t firstFreePart = 0;
|
||||||
ostringstream prompt1, prompt2, prompt3;
|
ostringstream prompt1, prompt2, prompt3;
|
||||||
int partNum;
|
int partNum;
|
||||||
@@ -229,7 +229,7 @@ void GPTDataTextUI::CreatePartition(void) {
|
|||||||
prompt2 << "First sector (" << firstBlock << "-" << lastBlock << ", default = "
|
prompt2 << "First sector (" << firstBlock << "-" << lastBlock << ", default = "
|
||||||
<< firstInLargest << ") or {+-}size{KMGTP}: ";
|
<< firstInLargest << ") or {+-}size{KMGTP}: ";
|
||||||
do {
|
do {
|
||||||
sector = GetSectorNum(firstBlock, lastBlock, firstInLargest, blockSize, prompt2.str());
|
sector = GetSectorNum(firstBlock, lastBlock, firstInLargest, prompt2.str());
|
||||||
} while (IsFree(sector) == 0);
|
} while (IsFree(sector) == 0);
|
||||||
origSector = sector;
|
origSector = sector;
|
||||||
if (Align(§or)) {
|
if (Align(§or)) {
|
||||||
@@ -239,15 +239,15 @@ void GPTDataTextUI::CreatePartition(void) {
|
|||||||
if (!beQuiet)
|
if (!beQuiet)
|
||||||
cout << "Use 'l' on the experts' menu to adjust alignment\n";
|
cout << "Use 'l' on the experts' menu to adjust alignment\n";
|
||||||
} // if
|
} // if
|
||||||
// Align(§or); // Align sector to correct multiple
|
|
||||||
firstBlock = sector;
|
firstBlock = sector;
|
||||||
|
|
||||||
// Get last block for new partitions...
|
// Get last block for new partitions...
|
||||||
lastBlock = FindLastInFree(firstBlock);
|
lastBlock = FindLastInFree(firstBlock, false);
|
||||||
|
lastAligned = FindLastInFree(firstBlock, true);
|
||||||
prompt3 << "Last sector (" << firstBlock << "-" << lastBlock << ", default = "
|
prompt3 << "Last sector (" << firstBlock << "-" << lastBlock << ", default = "
|
||||||
<< lastBlock << ") or {+-}size{KMGTP}: ";
|
<< lastAligned << ") or {+-}size{KMGTP}: ";
|
||||||
do {
|
do {
|
||||||
sector = GetSectorNum(firstBlock, lastBlock, lastBlock, blockSize, prompt3.str());
|
sector = GetSectorNum(firstBlock, lastBlock, lastAligned, prompt3.str());
|
||||||
} while (IsFree(sector) == 0);
|
} while (IsFree(sector) == 0);
|
||||||
lastBlock = sector;
|
lastBlock = sector;
|
||||||
|
|
||||||
@@ -548,6 +548,28 @@ int GPTDataTextUI::XFormToMBR(void) {
|
|||||||
return protectiveMBR.DoMenu();
|
return protectiveMBR.DoMenu();
|
||||||
} // GPTDataTextUI::XFormToMBR()
|
} // GPTDataTextUI::XFormToMBR()
|
||||||
|
|
||||||
|
// Obtains a sector number, between low and high, from the
|
||||||
|
// user, accepting values prefixed by "+" to add sectors to low,
|
||||||
|
// or the same with "K", "M", "G", "T", or "P" as suffixes to add
|
||||||
|
// kibibytes, mebibytes, gibibytes, tebibytes, or pebibytes,
|
||||||
|
// respectively. If a "-" prefix is used, use the high value minus
|
||||||
|
// the user-specified number of sectors (or KiB, MiB, etc.). Use the
|
||||||
|
// def value as the default if the user just hits Enter.
|
||||||
|
uint64_t GPTDataTextUI::GetSectorNum(uint64_t low, uint64_t high, uint64_t def,
|
||||||
|
const string & prompt) {
|
||||||
|
uint64_t response;
|
||||||
|
char line[255];
|
||||||
|
|
||||||
|
do {
|
||||||
|
cout << prompt;
|
||||||
|
cin.getline(line, 255);
|
||||||
|
if (!cin.good())
|
||||||
|
exit(5);
|
||||||
|
response = IeeeToInt(line, blockSize, low, high, sectorAlignment, def);
|
||||||
|
} while ((response < low) || (response > high));
|
||||||
|
return response;
|
||||||
|
} // GPTDataTextUI::GetSectorNum()
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* *
|
* *
|
||||||
* Display informational messages for the user.... *
|
* Display informational messages for the user.... *
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Implementation of GPTData class derivative with basic text-mode interaction
|
Implementation of GPTData class derivative with basic text-mode interaction
|
||||||
Copyright (C) 2010-2018 Roderick W. Smith
|
Copyright (C) 2010-2022 Roderick W. Smith
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -55,6 +55,7 @@ class GPTDataTextUI : public GPTData {
|
|||||||
void ShowDetails(void);
|
void ShowDetails(void);
|
||||||
void MakeHybrid(void);
|
void MakeHybrid(void);
|
||||||
int XFormToMBR(void); // convert GPT to MBR, wiping GPT afterwards. Returns 1 if successful
|
int XFormToMBR(void); // convert GPT to MBR, wiping GPT afterwards. Returns 1 if successful
|
||||||
|
uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, const string & prompt);
|
||||||
|
|
||||||
// An informational function....
|
// An informational function....
|
||||||
void WarnAboutIffyMBRPart(int partNum);
|
void WarnAboutIffyMBRPart(int partNum);
|
||||||
|
|||||||
19
sgdisk.8
19
sgdisk.8
@@ -154,7 +154,10 @@ to sectors that are multiples of this value, which defaults to 1 MiB (2048
|
|||||||
on disks with 512-byte sectors) on freshly formatted disks. This alignment
|
on disks with 512-byte sectors) on freshly formatted disks. This alignment
|
||||||
value is necessary to obtain optimum performance with Western Digital
|
value is necessary to obtain optimum performance with Western Digital
|
||||||
Advanced Format and similar drives with larger physical than logical sector
|
Advanced Format and similar drives with larger physical than logical sector
|
||||||
sizes, with some types of RAID arrays, and with SSD devices.
|
sizes, with some types of RAID arrays, and with SSD devices. When the
|
||||||
|
\fI\-I\fR option is used, this same alignment value is used to determine
|
||||||
|
partition end points; but partitions end at one less than a multiple of this
|
||||||
|
value, to keep the partition length a multiple of this value.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-A, \-\-attributes=list|[partnum:show|or|nand|xor|=|set|clear|toggle|get[:bitnum|hexbitmask]]
|
.B \-A, \-\-attributes=list|[partnum:show|or|nand|xor|=|set|clear|toggle|get[:bitnum|hexbitmask]]
|
||||||
@@ -280,7 +283,7 @@ is usually correct for Windows partitions. If the active/bootable flag should
|
|||||||
be set, you must do so in another program, such as \fBfdisk\fR. The \fBgdisk\fR
|
be set, you must do so in another program, such as \fBfdisk\fR. The \fBgdisk\fR
|
||||||
program offers additional hybrid MBR creation options.
|
program offers additional hybrid MBR creation options.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-i, \-\-info=partnum
|
.B \-i, \-\-info=partnum
|
||||||
Show detailed partition information. The summary information produced by
|
Show detailed partition information. The summary information produced by
|
||||||
the \fI\-p\fR command necessarily omits many details, such as the partition's
|
the \fI\-p\fR command necessarily omits many details, such as the partition's
|
||||||
@@ -288,6 +291,18 @@ unique GUID and the translation of \fBsgdisk\fR's
|
|||||||
internal partition type code to a plain type name. The \fI\-i\fR option
|
internal partition type code to a plain type name. The \fI\-i\fR option
|
||||||
displays this information for a single partition.
|
displays this information for a single partition.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B \-I, \-\-align\-end
|
||||||
|
When possible, align the end points of partitions to one less than a
|
||||||
|
multiple of the alignment value. When both start and end points are aligned,
|
||||||
|
partitions should be multiples of the alignment value in size, which is
|
||||||
|
necessary for some partition encryption tools to function correctly. This
|
||||||
|
option applies to all partitions created \fBafter\fR this option on the
|
||||||
|
command line. Note that this alignment is not always possible; for instance,
|
||||||
|
if the free space at the end of a disk is less than the alignment value,
|
||||||
|
with the current final partition being aligned, and if \fBsgdisk\fR is asked
|
||||||
|
to create a partition in that space, then it will \fBnot\fR be end\-aligned.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-j, \-\-adjust\-main\-table=sector
|
.B \-j, \-\-adjust\-main\-table=sector
|
||||||
Adjust the location of the main partition table. This value is normally 2,
|
Adjust the location of the main partition table. This value is normally 2,
|
||||||
|
|||||||
40
support.cc
40
support.cc
@@ -3,7 +3,7 @@
|
|||||||
// Primarily by Rod Smith, February 2009, but with a few functions
|
// Primarily by Rod Smith, February 2009, but with a few functions
|
||||||
// copied from other sources (see attributions below).
|
// copied from other sources (see attributions below).
|
||||||
|
|
||||||
/* This program is copyright (c) 2009-2018 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2022 by Roderick W. Smith. It is distributed
|
||||||
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
@@ -113,34 +113,11 @@ char GetYN(void) {
|
|||||||
return response;
|
return response;
|
||||||
} // GetYN(void)
|
} // GetYN(void)
|
||||||
|
|
||||||
// Obtains a sector number, between low and high, from the
|
|
||||||
// user, accepting values prefixed by "+" to add sectors to low,
|
|
||||||
// or the same with "K", "M", "G", "T", or "P" as suffixes to add
|
|
||||||
// kilobytes, megabytes, gigabytes, terabytes, or petabytes,
|
|
||||||
// respectively. If a "-" prefix is used, use the high value minus
|
|
||||||
// the user-specified number of sectors (or KiB, MiB, etc.). Use the
|
|
||||||
// def value as the default if the user just hits Enter. The sSize is
|
|
||||||
// the sector size of the device.
|
|
||||||
uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, uint64_t sSize,
|
|
||||||
const string & prompt) {
|
|
||||||
uint64_t response;
|
|
||||||
char line[255];
|
|
||||||
|
|
||||||
do {
|
|
||||||
cout << prompt;
|
|
||||||
cin.getline(line, 255);
|
|
||||||
if (!cin.good())
|
|
||||||
exit(5);
|
|
||||||
response = IeeeToInt(line, sSize, low, high, def);
|
|
||||||
} while ((response < low) || (response > high));
|
|
||||||
return response;
|
|
||||||
} // GetSectorNum()
|
|
||||||
|
|
||||||
// Convert an IEEE-1541-2002 value (K, M, G, T, P, or E) to its equivalent in
|
// Convert an IEEE-1541-2002 value (K, M, G, T, P, or E) to its equivalent in
|
||||||
// number of sectors. If no units are appended, interprets as the number
|
// number of sectors. If no units are appended, interprets as the number
|
||||||
// of sectors; otherwise, interprets as number of specified units and
|
// of sectors; otherwise, interprets as number of specified units and
|
||||||
// converts to sectors. For instance, with 512-byte sectors, "1K" converts
|
// converts to sectors. For instance, with 512-byte sectors, "1K" converts
|
||||||
// to 2. If value includes a "+", adds low and subtracts 1; if SIValue
|
// to 2. If value includes a "+", adds low and subtracts 1; if inValue
|
||||||
// inclues a "-", subtracts from high. If IeeeValue is empty, returns def.
|
// inclues a "-", subtracts from high. If IeeeValue is empty, returns def.
|
||||||
// Returns final sector value. In case inValue is invalid, returns 0 (a
|
// Returns final sector value. In case inValue is invalid, returns 0 (a
|
||||||
// sector value that's always in use on GPT and therefore invalid); and if
|
// sector value that's always in use on GPT and therefore invalid); and if
|
||||||
@@ -153,7 +130,7 @@ uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, uint64_t sSize,
|
|||||||
// 0 values. The result is that IeeeToInt() returns UINT64_MAX when
|
// 0 values. The result is that IeeeToInt() returns UINT64_MAX when
|
||||||
// compiled with GCC (and so the value is rejected), whereas when VC++
|
// compiled with GCC (and so the value is rejected), whereas when VC++
|
||||||
// is used, the default value is returned.
|
// is used, the default value is returned.
|
||||||
uint64_t IeeeToInt(string inValue, uint64_t sSize, uint64_t low, uint64_t high, uint64_t def) {
|
uint64_t IeeeToInt(string inValue, uint64_t sSize, uint64_t low, uint64_t high, uint32_t sectorAlignment, uint64_t def) {
|
||||||
uint64_t response = def, bytesPerUnit, mult = 1, divide = 1;
|
uint64_t response = def, bytesPerUnit, mult = 1, divide = 1;
|
||||||
size_t foundAt = 0;
|
size_t foundAt = 0;
|
||||||
char suffix = ' ', plusFlag = ' ';
|
char suffix = ' ', plusFlag = ' ';
|
||||||
@@ -208,11 +185,12 @@ uint64_t IeeeToInt(string inValue, uint64_t sSize, uint64_t low, uint64_t high,
|
|||||||
} // if/elseif
|
} // if/elseif
|
||||||
|
|
||||||
if (plusFlag == '+') {
|
if (plusFlag == '+') {
|
||||||
// Recompute response based on low part of range (if default == high
|
// Recompute response based on low part of range (if default is within
|
||||||
// value, which should be the case when prompting for the end of a
|
// sectorAlignment sectors of high, which should be the case when
|
||||||
// range) or the defaut value (if default != high, which should be
|
// prompting for the end of a range) or the defaut value (if default is
|
||||||
// the case for the first sector of a partition).
|
// further away from the high value, which should be the case for the
|
||||||
if (def == high) {
|
// first sector of a partition).
|
||||||
|
if ((high - def) < sectorAlignment) {
|
||||||
if (response > 0)
|
if (response > 0)
|
||||||
response--;
|
response--;
|
||||||
if (response > (UINT64_MAX - low))
|
if (response > (UINT64_MAX - low))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* This program is copyright (c) 2009-2018 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2022 by Roderick W. Smith. It is distributed
|
||||||
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#ifndef __GPTSUPPORT
|
#ifndef __GPTSUPPORT
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define GPTFDISK_VERSION "1.0.8"
|
#define GPTFDISK_VERSION "1.0.8.2"
|
||||||
|
|
||||||
#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
|
#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
|
||||||
// Darwin (Mac OS) & FreeBSD: disk IOCTLs are different, and there is no lseek64
|
// Darwin (Mac OS) & FreeBSD: disk IOCTLs are different, and there is no lseek64
|
||||||
@@ -74,8 +74,7 @@ using namespace std;
|
|||||||
string ReadString(void);
|
string ReadString(void);
|
||||||
uint64_t GetNumber(uint64_t low, uint64_t high, uint64_t def, const string & prompt);
|
uint64_t GetNumber(uint64_t low, uint64_t high, uint64_t def, const string & prompt);
|
||||||
char GetYN(void);
|
char GetYN(void);
|
||||||
uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, uint64_t sSize, const std::string& prompt);
|
uint64_t IeeeToInt(string IeeeValue, uint64_t sSize, uint64_t low, uint64_t high, uint32_t sectorAlignment, uint64_t def = 0);
|
||||||
uint64_t IeeeToInt(string IeeeValue, uint64_t sSize, uint64_t low, uint64_t high, uint64_t def = 0);
|
|
||||||
string BytesToIeee(uint64_t size, uint32_t sectorSize);
|
string BytesToIeee(uint64_t size, uint32_t sectorSize);
|
||||||
unsigned char StrToHex(const string & input, unsigned int position);
|
unsigned char StrToHex(const string & input, unsigned int position);
|
||||||
int IsHex(string input); // Returns 1 if input can be hexadecimal number....
|
int IsHex(string input); // Returns 1 if input can be hexadecimal number....
|
||||||
|
|||||||
Reference in New Issue
Block a user