fdisk: initial stab at GPT partition support
Signed-off-by: Kevin Cernekee <cernekee@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
3b060528a2
commit
ccb070450e
@ -746,7 +746,7 @@ char *itoa(int n) FAST_FUNC;
|
|||||||
char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) FAST_FUNC;
|
char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) FAST_FUNC;
|
||||||
char *itoa_to_buf(int n, char *buf, unsigned buflen) FAST_FUNC;
|
char *itoa_to_buf(int n, char *buf, unsigned buflen) FAST_FUNC;
|
||||||
/* Intelligent formatters of bignums */
|
/* Intelligent formatters of bignums */
|
||||||
void smart_ulltoa4(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;
|
void smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) FAST_FUNC;
|
||||||
void smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;
|
void smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;
|
||||||
/* If block_size == 0, display size without fractional part,
|
/* If block_size == 0, display size without fractional part,
|
||||||
* else display (size * block_size) with one decimal digit.
|
* else display (size * block_size) with one decimal digit.
|
||||||
@ -1543,7 +1543,10 @@ void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
|
|||||||
void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
|
void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
|
||||||
void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
|
void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
|
||||||
|
|
||||||
|
/* TODO: add global crc32_table pointer and create
|
||||||
|
* LE and BE functions to calculate crc32 over given bytes.
|
||||||
|
* Currently we have about five reimplementations...
|
||||||
|
*/
|
||||||
uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
|
uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
|
||||||
|
|
||||||
typedef struct masks_labels_t {
|
typedef struct masks_labels_t {
|
||||||
|
@ -94,7 +94,7 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val,
|
|||||||
|
|
||||||
/* Convert unsigned long long value into compact 5-char representation.
|
/* Convert unsigned long long value into compact 5-char representation.
|
||||||
* String is not terminated (buf[5] is untouched) */
|
* String is not terminated (buf[5] is untouched) */
|
||||||
void FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[6], const char *scale)
|
void FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale)
|
||||||
{
|
{
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
char c;
|
char c;
|
||||||
@ -150,7 +150,7 @@ void FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[6], const char *sca
|
|||||||
/* Convert unsigned long long value into compact 4-char
|
/* Convert unsigned long long value into compact 4-char
|
||||||
* representation. Examples: "1234", "1.2k", " 27M", "123T"
|
* representation. Examples: "1234", "1.2k", " 27M", "123T"
|
||||||
* String is not terminated (buf[4] is untouched) */
|
* String is not terminated (buf[4] is untouched) */
|
||||||
void FAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[5], const char *scale)
|
void FAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale)
|
||||||
{
|
{
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
char c;
|
char c;
|
||||||
|
@ -181,6 +181,14 @@ config FEATURE_OSF_LABEL
|
|||||||
Enabling this option allows you to create or change BSD disklabels
|
Enabling this option allows you to create or change BSD disklabels
|
||||||
and define and edit BSD disk slices.
|
and define and edit BSD disk slices.
|
||||||
|
|
||||||
|
config FEATURE_GPT_LABEL
|
||||||
|
bool "Support GPT disklabels"
|
||||||
|
default n
|
||||||
|
depends on FDISK && FEATURE_FDISK_WRITABLE
|
||||||
|
help
|
||||||
|
Enabling this option allows you to view GUID Partition Table
|
||||||
|
disklabels.
|
||||||
|
|
||||||
config FEATURE_FDISK_ADVANCED
|
config FEATURE_FDISK_ADVANCED
|
||||||
bool "Support expert mode"
|
bool "Support expert mode"
|
||||||
default y
|
default y
|
||||||
|
@ -107,12 +107,30 @@ struct partition {
|
|||||||
unsigned char size4[4]; /* nr of sectors in partition */
|
unsigned char size4[4]; /* nr of sectors in partition */
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* per partition table entry data
|
||||||
|
*
|
||||||
|
* The four primary partitions have the same sectorbuffer (MBRbuffer)
|
||||||
|
* and have NULL ext_pointer.
|
||||||
|
* Each logical partition table entry has two pointers, one for the
|
||||||
|
* partition and one link to the next one.
|
||||||
|
*/
|
||||||
|
struct pte {
|
||||||
|
struct partition *part_table; /* points into sectorbuffer */
|
||||||
|
struct partition *ext_pointer; /* points into sectorbuffer */
|
||||||
|
sector_t offset_from_dev_start; /* disk sector number */
|
||||||
|
char *sectorbuffer; /* disk sector contents */
|
||||||
|
#if ENABLE_FEATURE_FDISK_WRITABLE
|
||||||
|
char changed; /* boolean */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#define unable_to_open "can't open '%s'"
|
#define unable_to_open "can't open '%s'"
|
||||||
#define unable_to_read "can't read from %s"
|
#define unable_to_read "can't read from %s"
|
||||||
#define unable_to_seek "can't seek on %s"
|
#define unable_to_seek "can't seek on %s"
|
||||||
|
|
||||||
enum label_type {
|
enum label_type {
|
||||||
LABEL_DOS, LABEL_SUN, LABEL_SGI, LABEL_AIX, LABEL_OSF
|
LABEL_DOS, LABEL_SUN, LABEL_SGI, LABEL_AIX, LABEL_OSF, LABEL_GPT
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LABEL_IS_DOS (LABEL_DOS == current_label_type)
|
#define LABEL_IS_DOS (LABEL_DOS == current_label_type)
|
||||||
@ -149,6 +167,14 @@ enum label_type {
|
|||||||
#define STATIC_OSF extern
|
#define STATIC_OSF extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_GPT_LABEL
|
||||||
|
#define LABEL_IS_GPT (LABEL_GPT == current_label_type)
|
||||||
|
#define STATIC_GPT static
|
||||||
|
#else
|
||||||
|
#define LABEL_IS_GPT 0
|
||||||
|
#define STATIC_GPT extern
|
||||||
|
#endif
|
||||||
|
|
||||||
enum action { OPEN_MAIN, TRY_ONLY, CREATE_EMPTY_DOS, CREATE_EMPTY_SUN };
|
enum action { OPEN_MAIN, TRY_ONLY, CREATE_EMPTY_DOS, CREATE_EMPTY_SUN };
|
||||||
|
|
||||||
static void update_units(void);
|
static void update_units(void);
|
||||||
@ -162,6 +188,7 @@ static sector_t read_int(sector_t low, sector_t dflt, sector_t high, sector_t ba
|
|||||||
#endif
|
#endif
|
||||||
static const char *partition_type(unsigned char type);
|
static const char *partition_type(unsigned char type);
|
||||||
static void get_geometry(void);
|
static void get_geometry(void);
|
||||||
|
static void read_pte(struct pte *pe, sector_t offset);
|
||||||
#if ENABLE_FEATURE_SUN_LABEL || ENABLE_FEATURE_FDISK_WRITABLE
|
#if ENABLE_FEATURE_SUN_LABEL || ENABLE_FEATURE_FDISK_WRITABLE
|
||||||
static int get_boot(enum action what);
|
static int get_boot(enum action what);
|
||||||
#else
|
#else
|
||||||
@ -174,24 +201,6 @@ static int get_boot(void);
|
|||||||
static sector_t get_start_sect(const struct partition *p);
|
static sector_t get_start_sect(const struct partition *p);
|
||||||
static sector_t get_nr_sects(const struct partition *p);
|
static sector_t get_nr_sects(const struct partition *p);
|
||||||
|
|
||||||
/*
|
|
||||||
* per partition table entry data
|
|
||||||
*
|
|
||||||
* The four primary partitions have the same sectorbuffer (MBRbuffer)
|
|
||||||
* and have NULL ext_pointer.
|
|
||||||
* Each logical partition table entry has two pointers, one for the
|
|
||||||
* partition and one link to the next one.
|
|
||||||
*/
|
|
||||||
struct pte {
|
|
||||||
struct partition *part_table; /* points into sectorbuffer */
|
|
||||||
struct partition *ext_pointer; /* points into sectorbuffer */
|
|
||||||
sector_t offset_from_dev_start; /* disk sector number */
|
|
||||||
char *sectorbuffer; /* disk sector contents */
|
|
||||||
#if ENABLE_FEATURE_FDISK_WRITABLE
|
|
||||||
char changed; /* boolean */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/* DOS partition types */
|
/* DOS partition types */
|
||||||
|
|
||||||
static const char *const i386_sys_types[] = {
|
static const char *const i386_sys_types[] = {
|
||||||
@ -653,6 +662,8 @@ STATIC_OSF void bsd_select(void);
|
|||||||
STATIC_OSF void xbsd_print_disklabel(int);
|
STATIC_OSF void xbsd_print_disklabel(int);
|
||||||
#include "fdisk_osf.c"
|
#include "fdisk_osf.c"
|
||||||
|
|
||||||
|
#include "fdisk_gpt.c"
|
||||||
|
|
||||||
#if ENABLE_FEATURE_SGI_LABEL || ENABLE_FEATURE_SUN_LABEL
|
#if ENABLE_FEATURE_SGI_LABEL || ENABLE_FEATURE_SUN_LABEL
|
||||||
static uint16_t
|
static uint16_t
|
||||||
fdisk_swap16(uint16_t x)
|
fdisk_swap16(uint16_t x)
|
||||||
@ -833,6 +844,11 @@ menu(void)
|
|||||||
puts("o\tcreate a new empty DOS partition table");
|
puts("o\tcreate a new empty DOS partition table");
|
||||||
puts("q\tquit without saving changes");
|
puts("q\tquit without saving changes");
|
||||||
puts("s\tcreate a new empty Sun disklabel"); /* sun */
|
puts("s\tcreate a new empty Sun disklabel"); /* sun */
|
||||||
|
} else if (LABEL_IS_GPT) {
|
||||||
|
puts("o\tcreate a new empty DOS partition table");
|
||||||
|
puts("p\tprint the partition table");
|
||||||
|
puts("q\tquit without saving changes");
|
||||||
|
puts("s\tcreate a new empty Sun disklabel"); /* sun */
|
||||||
} else {
|
} else {
|
||||||
puts("a\ttoggle a bootable flag");
|
puts("a\ttoggle a bootable flag");
|
||||||
puts("b\tedit bsd disklabel");
|
puts("b\tedit bsd disklabel");
|
||||||
@ -1308,7 +1324,18 @@ get_geometry(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Opens disk_device and optionally reads MBR.
|
* Opens disk_device and optionally reads MBR.
|
||||||
* FIXME: document what each 'what' value will do!
|
* If what == OPEN_MAIN:
|
||||||
|
* Open device, read MBR. Abort program on short read. Create empty
|
||||||
|
* disklabel if the on-disk structure is invalid (WRITABLE mode).
|
||||||
|
* If what == TRY_ONLY:
|
||||||
|
* Open device, read MBR. Return an error if anything is out of place.
|
||||||
|
* Do not create an empty disklabel. This is used for the "list"
|
||||||
|
* operations: "fdisk -l /dev/sda" and "fdisk -l" (all devices).
|
||||||
|
* If what == CREATE_EMPTY_*:
|
||||||
|
* This means that get_boot() was called recursively from create_*label().
|
||||||
|
* Do not re-open the device; just set up the ptes array and print
|
||||||
|
* geometry warnings.
|
||||||
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* -1: no 0xaa55 flag present (possibly entire disk BSD)
|
* -1: no 0xaa55 flag present (possibly entire disk BSD)
|
||||||
* 0: found or created label
|
* 0: found or created label
|
||||||
@ -1390,6 +1417,10 @@ static int get_boot(void)
|
|||||||
if (check_aix_label())
|
if (check_aix_label())
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLE_FEATURE_GPT_LABEL
|
||||||
|
if (check_gpt_label())
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
#if ENABLE_FEATURE_OSF_LABEL
|
#if ENABLE_FEATURE_OSF_LABEL
|
||||||
if (check_osf_label()) {
|
if (check_osf_label()) {
|
||||||
possibly_osf_label = 1;
|
possibly_osf_label = 1;
|
||||||
@ -1409,7 +1440,7 @@ static int get_boot(void)
|
|||||||
if (!valid_part_table_flag(MBRbuffer)) {
|
if (!valid_part_table_flag(MBRbuffer)) {
|
||||||
if (what == OPEN_MAIN) {
|
if (what == OPEN_MAIN) {
|
||||||
printf("Device contains neither a valid DOS "
|
printf("Device contains neither a valid DOS "
|
||||||
"partition table, nor Sun, SGI or OSF "
|
"partition table, nor Sun, SGI, OSF or GPT "
|
||||||
"disklabel\n");
|
"disklabel\n");
|
||||||
#ifdef __sparc__
|
#ifdef __sparc__
|
||||||
IF_FEATURE_SUN_LABEL(create_sunlabel();)
|
IF_FEATURE_SUN_LABEL(create_sunlabel();)
|
||||||
@ -2056,10 +2087,14 @@ list_table(int xtra)
|
|||||||
sun_list_table(xtra);
|
sun_list_table(xtra);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (LABEL_IS_SUN) {
|
if (LABEL_IS_SGI) {
|
||||||
sgi_list_table(xtra);
|
sgi_list_table(xtra);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (LABEL_IS_GPT) {
|
||||||
|
gpt_list_table(xtra);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
list_disk_geometry();
|
list_disk_geometry();
|
||||||
|
|
||||||
|
203
util-linux/fdisk_gpt.c
Normal file
203
util-linux/fdisk_gpt.c
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
#if ENABLE_FEATURE_GPT_LABEL
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010 Kevin Cernekee <cernekee@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2, see file LICENSE in this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GPT_MAGIC 0x5452415020494645ULL
|
||||||
|
enum {
|
||||||
|
LEGACY_GPT_TYPE = 0xee,
|
||||||
|
GPT_MAX_PARTS = 256,
|
||||||
|
GPT_MAX_PART_ENTRY_LEN = 4096,
|
||||||
|
GUID_LEN = 16,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t magic;
|
||||||
|
uint32_t revision;
|
||||||
|
uint32_t hdr_size;
|
||||||
|
uint32_t hdr_crc32;
|
||||||
|
uint32_t reserved;
|
||||||
|
uint64_t current_lba;
|
||||||
|
uint64_t backup_lba;
|
||||||
|
uint64_t first_usable_lba;
|
||||||
|
uint64_t last_usable_lba;
|
||||||
|
uint8_t disk_guid[GUID_LEN];
|
||||||
|
uint64_t first_part_lba;
|
||||||
|
uint32_t n_parts;
|
||||||
|
uint32_t part_entry_len;
|
||||||
|
uint32_t part_array_crc32;
|
||||||
|
} gpt_header;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t type_guid[GUID_LEN];
|
||||||
|
uint8_t part_guid[GUID_LEN];
|
||||||
|
uint64_t lba_start;
|
||||||
|
uint64_t lba_end;
|
||||||
|
uint64_t flags;
|
||||||
|
uint16_t name[36];
|
||||||
|
} gpt_partition;
|
||||||
|
|
||||||
|
static gpt_header *gpt_hdr;
|
||||||
|
|
||||||
|
static char *part_array;
|
||||||
|
static unsigned int n_parts;
|
||||||
|
static unsigned int part_array_len;
|
||||||
|
static unsigned int part_entry_len;
|
||||||
|
|
||||||
|
static uint32_t *crc32_table;
|
||||||
|
|
||||||
|
static inline gpt_partition *
|
||||||
|
gpt_part(int i)
|
||||||
|
{
|
||||||
|
if (i >= n_parts) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (gpt_partition *)&part_array[i * part_entry_len];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: move to libbb */
|
||||||
|
static uint32_t
|
||||||
|
gpt_crc32(void *buf, int len)
|
||||||
|
{
|
||||||
|
uint32_t crc = 0xffffffff;
|
||||||
|
|
||||||
|
for (; len > 0; len--, buf++) {
|
||||||
|
crc = crc32_table[(crc ^ *((char *)buf)) & 0xff] ^ (crc >> 8);
|
||||||
|
}
|
||||||
|
return crc ^ 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gpt_print_guid(uint8_t *buf)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||||
|
buf[3], buf[2], buf[1], buf[0],
|
||||||
|
buf[5], buf[4],
|
||||||
|
buf[7], buf[6],
|
||||||
|
buf[8], buf[9],
|
||||||
|
buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: real unicode support */
|
||||||
|
static void
|
||||||
|
gpt_print_wide(uint16_t *s, int max_len)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < max_len) {
|
||||||
|
if (*s == 0)
|
||||||
|
return;
|
||||||
|
fputc(*s, stdout);
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gpt_list_table(int xtra UNUSED_PARAM)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char numstr6[6];
|
||||||
|
|
||||||
|
numstr6[5] = '\0';
|
||||||
|
|
||||||
|
smart_ulltoa5(total_number_of_sectors, numstr6, " KMGTPEZY");
|
||||||
|
printf("Disk %s: %llu sectors, %s\n", disk_device,
|
||||||
|
(unsigned long long)total_number_of_sectors,
|
||||||
|
numstr6);
|
||||||
|
printf("Logical sector size: %u\n", sector_size);
|
||||||
|
printf("Disk identifier (GUID): ");
|
||||||
|
gpt_print_guid(gpt_hdr->disk_guid);
|
||||||
|
printf("\nPartition table holds up to %u entries\n",
|
||||||
|
(int)SWAP_LE32(gpt_hdr->n_parts));
|
||||||
|
printf("First usable sector is %llu, last usable sector is %llu\n\n",
|
||||||
|
(unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba),
|
||||||
|
(unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba));
|
||||||
|
|
||||||
|
printf("Number Start (sector) End (sector) Size Code Name\n");
|
||||||
|
for (i = 0; i < n_parts; i++) {
|
||||||
|
gpt_partition *p = gpt_part(i);
|
||||||
|
if (p->lba_start) {
|
||||||
|
smart_ulltoa5(1 + SWAP_LE64(p->lba_end) - SWAP_LE64(p->lba_start),
|
||||||
|
numstr6, " KMGTPEZY");
|
||||||
|
printf("%4u %15llu %15llu %11s %04x ",
|
||||||
|
i + 1,
|
||||||
|
(unsigned long long)SWAP_LE64(p->lba_start),
|
||||||
|
(unsigned long long)SWAP_LE64(p->lba_end),
|
||||||
|
numstr6,
|
||||||
|
0x0700 /* FIXME */);
|
||||||
|
gpt_print_wide(p->name, 18);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_gpt_label(void)
|
||||||
|
{
|
||||||
|
struct partition *first = pt_offset(MBRbuffer, 0);
|
||||||
|
struct pte pe;
|
||||||
|
uint32_t crc;
|
||||||
|
|
||||||
|
/* LBA 0 contains the legacy MBR */
|
||||||
|
|
||||||
|
if (!valid_part_table_flag(MBRbuffer)
|
||||||
|
|| first->sys_ind != LEGACY_GPT_TYPE
|
||||||
|
) {
|
||||||
|
current_label_type = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LBA 1 contains the GPT header */
|
||||||
|
|
||||||
|
read_pte(&pe, 1);
|
||||||
|
gpt_hdr = (void *)pe.sectorbuffer;
|
||||||
|
|
||||||
|
if (gpt_hdr->magic != SWAP_LE64(GPT_MAGIC)) {
|
||||||
|
current_label_type = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!crc32_table) {
|
||||||
|
crc32_table = crc32_filltable(NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
crc = SWAP_LE32(gpt_hdr->hdr_crc32);
|
||||||
|
gpt_hdr->hdr_crc32 = 0;
|
||||||
|
if (gpt_crc32(gpt_hdr, SWAP_LE32(gpt_hdr->hdr_size)) != crc) {
|
||||||
|
/* FIXME: read the backup table */
|
||||||
|
puts("\nwarning: GPT header CRC is invalid\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
n_parts = SWAP_LE32(gpt_hdr->n_parts);
|
||||||
|
part_entry_len = SWAP_LE32(gpt_hdr->part_entry_len);
|
||||||
|
if (n_parts > GPT_MAX_PARTS
|
||||||
|
|| part_entry_len > GPT_MAX_PART_ENTRY_LEN
|
||||||
|
|| SWAP_LE32(gpt_hdr->hdr_size) > sector_size
|
||||||
|
) {
|
||||||
|
puts("\nwarning: unable to parse GPT disklabel\n");
|
||||||
|
current_label_type = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
part_array_len = n_parts * part_entry_len;
|
||||||
|
part_array = xmalloc(part_array_len);
|
||||||
|
seek_sector(SWAP_LE64(gpt_hdr->first_part_lba));
|
||||||
|
if (full_read(dev_fd, part_array, part_array_len) != part_array_len) {
|
||||||
|
fdisk_fatal(unable_to_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpt_crc32(part_array, part_array_len) != gpt_hdr->part_array_crc32) {
|
||||||
|
/* FIXME: read the backup table */
|
||||||
|
puts("\nwarning: GPT array CRC is invalid\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("Found valid GPT with protective MBR; using GPT\n");
|
||||||
|
|
||||||
|
current_label_type = LABEL_GPT;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GPT_LABEL */
|
Loading…
Reference in New Issue
Block a user