mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-31 16:57:10 +00:00
Add byte swapping and UUID encoding/decoding to allow gpt to be compiled
on big-endian machines. Obtained from: Dan Markarian <markarian at apple dot com>
This commit is contained in:
parent
75d0533847
commit
6ebab76180
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=136932
@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/gpt.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stddef.h>
|
||||
@ -37,7 +36,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <uuid.h>
|
||||
|
||||
#include "map.h"
|
||||
#include "gpt.h"
|
||||
@ -88,15 +86,16 @@ add(int fd)
|
||||
}
|
||||
|
||||
hdr = gpt->map_data;
|
||||
if (entry > hdr->hdr_entries) {
|
||||
if (entry > le32toh(hdr->hdr_entries)) {
|
||||
warnx("%s: error: index %u out of range (%u max)", device_name,
|
||||
entry, hdr->hdr_entries);
|
||||
entry, le32toh(hdr->hdr_entries));
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry > 0) {
|
||||
i = entry - 1;
|
||||
ent = (void*)((char*)tbl->map_data + i * hdr->hdr_entsz);
|
||||
ent = (void*)((char*)tbl->map_data + i *
|
||||
le32toh(hdr->hdr_entsz));
|
||||
if (!uuid_is_nil(&ent->ent_type, NULL)) {
|
||||
warnx("%s: error: entry at index %u is not free",
|
||||
device_name, entry);
|
||||
@ -104,13 +103,13 @@ add(int fd)
|
||||
}
|
||||
} else {
|
||||
/* Find empty slot in GPT table. */
|
||||
for (i = 0; i < hdr->hdr_entries; i++) {
|
||||
for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
|
||||
ent = (void*)((char*)tbl->map_data + i *
|
||||
hdr->hdr_entsz);
|
||||
le32toh(hdr->hdr_entsz));
|
||||
if (uuid_is_nil(&ent->ent_type, NULL))
|
||||
break;
|
||||
}
|
||||
if (i == hdr->hdr_entries) {
|
||||
if (i == le32toh(hdr->hdr_entries)) {
|
||||
warnx("%s: error: no available table entries",
|
||||
device_name);
|
||||
return;
|
||||
@ -123,29 +122,29 @@ add(int fd)
|
||||
return;
|
||||
}
|
||||
|
||||
ent->ent_type = type;
|
||||
ent->ent_lba_start = map->map_start;
|
||||
ent->ent_lba_end = map->map_start + map->map_size - 1LL;
|
||||
le_uuid_enc(&ent->ent_type, &type);
|
||||
ent->ent_lba_start = htole64(map->map_start);
|
||||
ent->ent_lba_end = htole64(map->map_start + map->map_size - 1LL);
|
||||
|
||||
hdr->hdr_crc_table = crc32(tbl->map_data,
|
||||
hdr->hdr_entries * hdr->hdr_entsz);
|
||||
hdr->hdr_crc_table = htole32(crc32(tbl->map_data,
|
||||
le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz)));
|
||||
hdr->hdr_crc_self = 0;
|
||||
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
|
||||
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
|
||||
|
||||
gpt_write(fd, gpt);
|
||||
gpt_write(fd, tbl);
|
||||
|
||||
hdr = tpg->map_data;
|
||||
ent = (void*)((char*)lbt->map_data + i * hdr->hdr_entsz);
|
||||
ent = (void*)((char*)lbt->map_data + i * le32toh(hdr->hdr_entsz));
|
||||
|
||||
ent->ent_type = type;
|
||||
ent->ent_lba_start = map->map_start;
|
||||
ent->ent_lba_end = map->map_start + map->map_size - 1LL;
|
||||
le_uuid_enc(&ent->ent_type, &type);
|
||||
ent->ent_lba_start = htole64(map->map_start);
|
||||
ent->ent_lba_end = htole64(map->map_start + map->map_size - 1LL);
|
||||
|
||||
hdr->hdr_crc_table = crc32(lbt->map_data,
|
||||
hdr->hdr_entries * hdr->hdr_entsz);
|
||||
hdr->hdr_crc_table = htole32(crc32(lbt->map_data,
|
||||
le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz)));
|
||||
hdr->hdr_crc_self = 0;
|
||||
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
|
||||
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
|
||||
|
||||
gpt_write(fd, lbt);
|
||||
gpt_write(fd, tpg);
|
||||
|
@ -28,7 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/gpt.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stddef.h>
|
||||
@ -36,7 +35,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <uuid.h>
|
||||
|
||||
#include "map.h"
|
||||
#include "gpt.h"
|
||||
@ -55,6 +53,7 @@ usage_create(void)
|
||||
static void
|
||||
create(int fd)
|
||||
{
|
||||
uuid_t uuid;
|
||||
off_t blocks, last;
|
||||
map_t *gpt, *tpg;
|
||||
map_t *tbl, *lbt;
|
||||
@ -84,7 +83,7 @@ create(int fd)
|
||||
}
|
||||
mbr = gpt_read(fd, 0LL, 1);
|
||||
bzero(mbr, sizeof(*mbr));
|
||||
mbr->mbr_sig = MBR_SIG;
|
||||
mbr->mbr_sig = htole16(MBR_SIG);
|
||||
mbr->mbr_part[0].part_shd = 0xff;
|
||||
mbr->mbr_part[0].part_ssect = 0xff;
|
||||
mbr->mbr_part[0].part_scyl = 0xff;
|
||||
@ -92,13 +91,13 @@ create(int fd)
|
||||
mbr->mbr_part[0].part_ehd = 0xff;
|
||||
mbr->mbr_part[0].part_esect = 0xff;
|
||||
mbr->mbr_part[0].part_ecyl = 0xff;
|
||||
mbr->mbr_part[0].part_start_lo = 1;
|
||||
mbr->mbr_part[0].part_start_lo = htole16(1);
|
||||
if (mediasz > 0xffffffff) {
|
||||
mbr->mbr_part[0].part_size_lo = 0xffff;
|
||||
mbr->mbr_part[0].part_size_hi = 0xffff;
|
||||
mbr->mbr_part[0].part_size_lo = htole16(0xffff);
|
||||
mbr->mbr_part[0].part_size_hi = htole16(0xffff);
|
||||
} else {
|
||||
mbr->mbr_part[0].part_size_lo = mediasz & 0xffff;
|
||||
mbr->mbr_part[0].part_size_hi = mediasz >> 16;
|
||||
mbr->mbr_part[0].part_size_lo = htole16(mediasz);
|
||||
mbr->mbr_part[0].part_size_hi = htole16(mediasz >> 16);
|
||||
}
|
||||
map = map_add(0LL, 1LL, MAP_TYPE_PMBR, mbr);
|
||||
gpt_write(fd, map);
|
||||
@ -151,29 +150,33 @@ create(int fd)
|
||||
|
||||
hdr = gpt->map_data;
|
||||
memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
|
||||
hdr->hdr_revision = GPT_HDR_REVISION;
|
||||
hdr->hdr_revision = htole32(GPT_HDR_REVISION);
|
||||
/*
|
||||
* XXX struct gpt_hdr is not a multiple of 8 bytes in size and thus
|
||||
* contains padding we must not include in the size.
|
||||
*/
|
||||
hdr->hdr_size = offsetof(struct gpt_hdr, padding);
|
||||
hdr->hdr_lba_self = gpt->map_start;
|
||||
hdr->hdr_lba_alt = last;
|
||||
hdr->hdr_lba_start = tbl->map_start + blocks;
|
||||
hdr->hdr_lba_end = last - blocks - 1LL;
|
||||
uuid_create(&hdr->hdr_uuid, NULL);
|
||||
hdr->hdr_lba_table = tbl->map_start;
|
||||
hdr->hdr_entries = (blocks * secsz) / sizeof(struct gpt_ent);
|
||||
if (hdr->hdr_entries > parts)
|
||||
hdr->hdr_entries = parts;
|
||||
hdr->hdr_entsz = sizeof(struct gpt_ent);
|
||||
hdr->hdr_size = htole32(offsetof(struct gpt_hdr, padding));
|
||||
hdr->hdr_lba_self = htole64(gpt->map_start);
|
||||
hdr->hdr_lba_alt = htole64(last);
|
||||
hdr->hdr_lba_start = htole64(tbl->map_start + blocks);
|
||||
hdr->hdr_lba_end = htole64(last - blocks - 1LL);
|
||||
uuid_create(&uuid, NULL);
|
||||
le_uuid_enc(&hdr->hdr_uuid, &uuid);
|
||||
hdr->hdr_lba_table = htole64(tbl->map_start);
|
||||
hdr->hdr_entries = htole32((blocks * secsz) / sizeof(struct gpt_ent));
|
||||
if (le32toh(hdr->hdr_entries) > parts)
|
||||
hdr->hdr_entries = htole32(parts);
|
||||
hdr->hdr_entsz = htole32(sizeof(struct gpt_ent));
|
||||
|
||||
ent = tbl->map_data;
|
||||
for (i = 0; i < hdr->hdr_entries; i++)
|
||||
uuid_create(&ent[i].ent_uuid, NULL);
|
||||
for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
|
||||
uuid_create(&uuid, NULL);
|
||||
le_uuid_enc(&ent[i].ent_uuid, &uuid);
|
||||
}
|
||||
|
||||
hdr->hdr_crc_table = crc32(ent, hdr->hdr_entries * hdr->hdr_entsz);
|
||||
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
|
||||
hdr->hdr_crc_table = htole32(crc32(ent, le32toh(hdr->hdr_entries) *
|
||||
le32toh(hdr->hdr_entsz)));
|
||||
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
|
||||
|
||||
gpt_write(fd, gpt);
|
||||
gpt_write(fd, tbl);
|
||||
@ -188,11 +191,11 @@ create(int fd)
|
||||
tbl->map_data);
|
||||
memcpy(tpg->map_data, gpt->map_data, secsz);
|
||||
hdr = tpg->map_data;
|
||||
hdr->hdr_lba_self = tpg->map_start;
|
||||
hdr->hdr_lba_alt = gpt->map_start;
|
||||
hdr->hdr_lba_table = lbt->map_start;
|
||||
hdr->hdr_lba_self = htole64(tpg->map_start);
|
||||
hdr->hdr_lba_alt = htole64(gpt->map_start);
|
||||
hdr->hdr_lba_table = htole64(lbt->map_start);
|
||||
hdr->hdr_crc_self = 0; /* Don't ever forget this! */
|
||||
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
|
||||
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
|
||||
gpt_write(fd, lbt);
|
||||
gpt_write(fd, tpg);
|
||||
}
|
||||
|
@ -28,7 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/gpt.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stddef.h>
|
||||
|
@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/types.h>
|
||||
#include <sys/disk.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/gpt.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
@ -43,7 +42,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <uuid.h>
|
||||
|
||||
#include "map.h"
|
||||
#include "gpt.h"
|
||||
@ -127,6 +125,38 @@ unicode16(short *dst, const wchar_t *src, size_t len)
|
||||
*dst = 0;
|
||||
}
|
||||
|
||||
void
|
||||
le_uuid_dec(void const *buf, uuid_t *uuid)
|
||||
{
|
||||
u_char const *p;
|
||||
int i;
|
||||
|
||||
p = buf;
|
||||
uuid->time_low = le32dec(p);
|
||||
uuid->time_mid = le16dec(p + 4);
|
||||
uuid->time_hi_and_version = le16dec(p + 6);
|
||||
uuid->clock_seq_hi_and_reserved = p[8];
|
||||
uuid->clock_seq_low = p[9];
|
||||
for (i = 0; i < _UUID_NODE_LEN; i++)
|
||||
uuid->node[i] = p[10 + i];
|
||||
}
|
||||
|
||||
void
|
||||
le_uuid_enc(void *buf, uuid_t const *uuid)
|
||||
{
|
||||
u_char *p;
|
||||
int i;
|
||||
|
||||
p = buf;
|
||||
le32enc(p, uuid->time_low);
|
||||
le16enc(p + 4, uuid->time_mid);
|
||||
le16enc(p + 6, uuid->time_hi_and_version);
|
||||
p[8] = uuid->clock_seq_hi_and_reserved;
|
||||
p[9] = uuid->clock_seq_low;
|
||||
for (i = 0; i < _UUID_NODE_LEN; i++)
|
||||
p[10 + i] = uuid->node[i];
|
||||
}
|
||||
|
||||
void*
|
||||
gpt_read(int fd, off_t lba, size_t count)
|
||||
{
|
||||
@ -173,7 +203,7 @@ gpt_mbr(int fd, off_t lba)
|
||||
if (mbr == NULL)
|
||||
return (-1);
|
||||
|
||||
if (mbr->mbr_sig != MBR_SIG) {
|
||||
if (mbr->mbr_sig != htole16(MBR_SIG)) {
|
||||
if (verbose)
|
||||
warnx("%s: MBR not found at sector %llu", device_name,
|
||||
(long long)lba);
|
||||
@ -218,10 +248,10 @@ gpt_mbr(int fd, off_t lba)
|
||||
if (mbr->mbr_part[i].part_typ == 0 ||
|
||||
mbr->mbr_part[i].part_typ == 0xee)
|
||||
continue;
|
||||
start = mbr->mbr_part[i].part_start_hi;
|
||||
start = (start << 16) + mbr->mbr_part[i].part_start_lo;
|
||||
size = mbr->mbr_part[i].part_size_hi;
|
||||
size = (size << 16) + mbr->mbr_part[i].part_size_lo;
|
||||
start = le16toh(mbr->mbr_part[i].part_start_hi);
|
||||
start = (start << 16) + le16toh(mbr->mbr_part[i].part_start_lo);
|
||||
size = le16toh(mbr->mbr_part[i].part_size_hi);
|
||||
size = (size << 16) + le16toh(mbr->mbr_part[i].part_size_lo);
|
||||
if (start == 0 && size == 0) {
|
||||
warnx("%s: Malformed MBR at sector %llu", device_name,
|
||||
(long long)lba);
|
||||
@ -249,6 +279,7 @@ gpt_mbr(int fd, off_t lba)
|
||||
static int
|
||||
gpt_gpt(int fd, off_t lba)
|
||||
{
|
||||
uuid_t type;
|
||||
off_t size;
|
||||
struct gpt_ent *ent;
|
||||
struct gpt_hdr *hdr;
|
||||
@ -265,27 +296,28 @@ gpt_gpt(int fd, off_t lba)
|
||||
if (memcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig)))
|
||||
goto fail_hdr;
|
||||
|
||||
crc = hdr->hdr_crc_self;
|
||||
crc = le32toh(hdr->hdr_crc_self);
|
||||
hdr->hdr_crc_self = 0;
|
||||
if (crc32(hdr, hdr->hdr_size) != crc) {
|
||||
if (crc32(hdr, le32toh(hdr->hdr_size)) != crc) {
|
||||
if (verbose)
|
||||
warnx("%s: Bad CRC in GPT header at sector %llu",
|
||||
device_name, (long long)lba);
|
||||
goto fail_hdr;
|
||||
}
|
||||
|
||||
tblsz = hdr->hdr_entries * hdr->hdr_entsz;
|
||||
tblsz = le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz);
|
||||
blocks = tblsz / secsz + ((tblsz % secsz) ? 1 : 0);
|
||||
|
||||
/* Use generic pointer to deal with hdr->hdr_entsz != sizeof(*ent). */
|
||||
p = gpt_read(fd, hdr->hdr_lba_table, blocks);
|
||||
p = gpt_read(fd, le64toh(hdr->hdr_lba_table), blocks);
|
||||
if (p == NULL)
|
||||
return (-1);
|
||||
|
||||
if (crc32(p, tblsz) != hdr->hdr_crc_table) {
|
||||
if (crc32(p, tblsz) != le32toh(hdr->hdr_crc_table)) {
|
||||
if (verbose)
|
||||
warnx("%s: Bad CRC in GPT table at sector %llu",
|
||||
device_name, (long long)hdr->hdr_lba_table);
|
||||
device_name,
|
||||
(long long)le64toh(hdr->hdr_lba_table));
|
||||
goto fail_ent;
|
||||
}
|
||||
|
||||
@ -298,7 +330,7 @@ gpt_gpt(int fd, off_t lba)
|
||||
if (m == NULL)
|
||||
return (-1);
|
||||
|
||||
m = map_add(hdr->hdr_lba_table, blocks, (lba == 1)
|
||||
m = map_add(le64toh(hdr->hdr_lba_table), blocks, (lba == 1)
|
||||
? MAP_TYPE_PRI_GPT_TBL : MAP_TYPE_SEC_GPT_TBL, p);
|
||||
if (m == NULL)
|
||||
return (-1);
|
||||
@ -306,20 +338,24 @@ gpt_gpt(int fd, off_t lba)
|
||||
if (lba != 1)
|
||||
return (0);
|
||||
|
||||
for (i = 0; i < hdr->hdr_entries; i++) {
|
||||
ent = (void*)(p + i * hdr->hdr_entsz);
|
||||
for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
|
||||
ent = (void*)(p + i * le32toh(hdr->hdr_entsz));
|
||||
if (uuid_is_nil(&ent->ent_type, NULL))
|
||||
continue;
|
||||
|
||||
size = ent->ent_lba_end - ent->ent_lba_start + 1LL;
|
||||
size = le64toh(ent->ent_lba_end) - le64toh(ent->ent_lba_start) +
|
||||
1LL;
|
||||
if (verbose > 2) {
|
||||
uuid_to_string(&ent->ent_type, &s, NULL);
|
||||
le_uuid_dec(&ent->ent_type, &type);
|
||||
uuid_to_string(&type, &s, NULL);
|
||||
warnx(
|
||||
"%s: GPT partition: type=%s, start=%llu, size=%llu", device_name, s,
|
||||
(long long)ent->ent_lba_start, (long long)size);
|
||||
(long long)le64toh(ent->ent_lba_start),
|
||||
(long long)size);
|
||||
free(s);
|
||||
}
|
||||
m = map_add(ent->ent_lba_start, size, MAP_TYPE_GPT_PART, ent);
|
||||
m = map_add(le64toh(ent->ent_lba_start), size,
|
||||
MAP_TYPE_GPT_PART, ent);
|
||||
if (m == NULL)
|
||||
return (-1);
|
||||
m->map_index = i + 1;
|
||||
|
@ -29,6 +29,14 @@
|
||||
#ifndef _GPT_H_
|
||||
#define _GPT_H_
|
||||
|
||||
#include <sys/endian.h>
|
||||
#include <sys/gpt.h>
|
||||
|
||||
#include <uuid.h>
|
||||
|
||||
void le_uuid_dec(void const *, uuid_t *);
|
||||
void le_uuid_enc(void *, uuid_t const *);
|
||||
|
||||
struct mbr_part {
|
||||
uint8_t part_flag; /* bootstrap flags */
|
||||
uint8_t part_shd; /* starting head */
|
||||
|
@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/gpt.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stddef.h>
|
||||
@ -37,7 +36,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <uuid.h>
|
||||
|
||||
#include "map.h"
|
||||
#include "gpt.h"
|
||||
@ -74,31 +72,32 @@ migrate_disklabel(int fd, off_t start, struct gpt_ent *ent)
|
||||
buf = gpt_read(fd, start + LABELSECTOR, 1);
|
||||
dl = (void*)(buf + LABELOFFSET);
|
||||
|
||||
if (dl->d_magic != DISKMAGIC || dl->d_magic2 != DISKMAGIC) {
|
||||
if (le32toh(dl->d_magic) != DISKMAGIC ||
|
||||
le32toh(dl->d_magic2) != DISKMAGIC) {
|
||||
warnx("%s: warning: FreeBSD slice without disklabel",
|
||||
device_name);
|
||||
return (ent);
|
||||
}
|
||||
|
||||
for (i = 0; i < dl->d_npartitions; i++) {
|
||||
for (i = 0; i < le16toh(dl->d_npartitions); i++) {
|
||||
switch (dl->d_partitions[i].p_fstype) {
|
||||
case FS_SWAP: {
|
||||
uuid_t swap = GPT_ENT_TYPE_FREEBSD_SWAP;
|
||||
ent->ent_type = swap;
|
||||
le_uuid_enc(&ent->ent_type, &swap);
|
||||
unicode16(ent->ent_name,
|
||||
L"FreeBSD swap partition", 36);
|
||||
break;
|
||||
}
|
||||
case FS_BSDFFS: {
|
||||
uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS;
|
||||
ent->ent_type = ufs;
|
||||
le_uuid_enc(&ent->ent_type, &ufs);
|
||||
unicode16(ent->ent_name,
|
||||
L"FreeBSD UFS partition", 36);
|
||||
break;
|
||||
}
|
||||
case FS_VINUM: {
|
||||
uuid_t vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
|
||||
ent->ent_type = vinum;
|
||||
le_uuid_enc(&ent->ent_type, &vinum);
|
||||
unicode16(ent->ent_name,
|
||||
L"FreeBSD vinum partition", 36);
|
||||
break;
|
||||
@ -109,9 +108,10 @@ migrate_disklabel(int fd, off_t start, struct gpt_ent *ent)
|
||||
continue;
|
||||
}
|
||||
|
||||
ent->ent_lba_start = dl->d_partitions[i].p_offset;
|
||||
ent->ent_lba_end = ent->ent_lba_start +
|
||||
dl->d_partitions[i].p_size - 1LL;
|
||||
ent->ent_lba_start =
|
||||
htole64(le32toh(dl->d_partitions[i].p_offset));
|
||||
ent->ent_lba_end = htole64(le64toh(ent->ent_lba_start) +
|
||||
le32toh(dl->d_partitions[i].p_size) - 1LL);
|
||||
ent++;
|
||||
}
|
||||
|
||||
@ -121,6 +121,7 @@ migrate_disklabel(int fd, off_t start, struct gpt_ent *ent)
|
||||
static void
|
||||
migrate(int fd)
|
||||
{
|
||||
uuid_t uuid;
|
||||
off_t blocks, last;
|
||||
map_t *gpt, *tpg;
|
||||
map_t *tbl, *lbt;
|
||||
@ -196,33 +197,36 @@ migrate(int fd)
|
||||
|
||||
hdr = gpt->map_data;
|
||||
memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
|
||||
hdr->hdr_revision = GPT_HDR_REVISION;
|
||||
hdr->hdr_revision = htole32(GPT_HDR_REVISION);
|
||||
/*
|
||||
* XXX struct gpt_hdr is not a multiple of 8 bytes in size and thus
|
||||
* contains padding we must not include in the size.
|
||||
*/
|
||||
hdr->hdr_size = offsetof(struct gpt_hdr, padding);
|
||||
hdr->hdr_lba_self = gpt->map_start;
|
||||
hdr->hdr_lba_alt = tpg->map_start;
|
||||
hdr->hdr_lba_start = tbl->map_start + blocks;
|
||||
hdr->hdr_lba_end = lbt->map_start - 1LL;
|
||||
uuid_create(&hdr->hdr_uuid, NULL);
|
||||
hdr->hdr_lba_table = tbl->map_start;
|
||||
hdr->hdr_entries = (blocks * secsz) / sizeof(struct gpt_ent);
|
||||
if (hdr->hdr_entries > parts)
|
||||
hdr->hdr_entries = parts;
|
||||
hdr->hdr_entsz = sizeof(struct gpt_ent);
|
||||
hdr->hdr_size = htole32(offsetof(struct gpt_hdr, padding));
|
||||
hdr->hdr_lba_self = htole64(gpt->map_start);
|
||||
hdr->hdr_lba_alt = htole64(tpg->map_start);
|
||||
hdr->hdr_lba_start = htole64(tbl->map_start + blocks);
|
||||
hdr->hdr_lba_end = htole64(lbt->map_start - 1LL);
|
||||
uuid_create(&uuid, NULL);
|
||||
le_uuid_enc(&hdr->hdr_uuid, &uuid);
|
||||
hdr->hdr_lba_table = htole64(tbl->map_start);
|
||||
hdr->hdr_entries = htole32((blocks * secsz) / sizeof(struct gpt_ent));
|
||||
if (le32toh(hdr->hdr_entries) > parts)
|
||||
hdr->hdr_entries = htole32(parts);
|
||||
hdr->hdr_entsz = htole32(sizeof(struct gpt_ent));
|
||||
|
||||
ent = tbl->map_data;
|
||||
for (i = 0; i < hdr->hdr_entries; i++)
|
||||
uuid_create(&ent[i].ent_uuid, NULL);
|
||||
for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
|
||||
uuid_create(&uuid, NULL);
|
||||
le_uuid_enc(&ent[i].ent_uuid, &uuid);
|
||||
}
|
||||
|
||||
/* Mirror partitions. */
|
||||
for (i = 0; i < 4; i++) {
|
||||
start = mbr->mbr_part[i].part_start_hi;
|
||||
start = (start << 16) + mbr->mbr_part[i].part_start_lo;
|
||||
size = mbr->mbr_part[i].part_size_hi;
|
||||
size = (size << 16) + mbr->mbr_part[i].part_size_lo;
|
||||
start = le16toh(mbr->mbr_part[i].part_start_hi);
|
||||
start = (start << 16) + le16toh(mbr->mbr_part[i].part_start_lo);
|
||||
size = le16toh(mbr->mbr_part[i].part_size_hi);
|
||||
size = (size << 16) + le16toh(mbr->mbr_part[i].part_size_lo);
|
||||
|
||||
switch (mbr->mbr_part[i].part_typ) {
|
||||
case 0:
|
||||
@ -230,9 +234,9 @@ migrate(int fd)
|
||||
case 165: { /* FreeBSD */
|
||||
if (slice) {
|
||||
uuid_t freebsd = GPT_ENT_TYPE_FREEBSD;
|
||||
ent->ent_type = freebsd;
|
||||
ent->ent_lba_start = start;
|
||||
ent->ent_lba_end = start + size - 1LL;
|
||||
le_uuid_enc(&ent->ent_type, &freebsd);
|
||||
ent->ent_lba_start = htole64((uint64_t)start);
|
||||
ent->ent_lba_end = htole64(start + size - 1LL);
|
||||
unicode16(ent->ent_name,
|
||||
L"FreeBSD disklabel partition", 36);
|
||||
ent++;
|
||||
@ -242,9 +246,9 @@ migrate(int fd)
|
||||
}
|
||||
case 239: { /* EFI */
|
||||
uuid_t efi_slice = GPT_ENT_TYPE_EFI;
|
||||
ent->ent_type = efi_slice;
|
||||
ent->ent_lba_start = start;
|
||||
ent->ent_lba_end = start + size - 1LL;
|
||||
le_uuid_enc(&ent->ent_type, &efi_slice);
|
||||
ent->ent_lba_start = htole64((uint64_t)start);
|
||||
ent->ent_lba_end = htole64(start + size - 1LL);
|
||||
unicode16(ent->ent_name, L"EFI system partition", 36);
|
||||
ent++;
|
||||
break;
|
||||
@ -257,8 +261,9 @@ migrate(int fd)
|
||||
}
|
||||
ent = tbl->map_data;
|
||||
|
||||
hdr->hdr_crc_table = crc32(ent, hdr->hdr_entries * hdr->hdr_entsz);
|
||||
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
|
||||
hdr->hdr_crc_table = htole32(crc32(ent, le32toh(hdr->hdr_entries) *
|
||||
le32toh(hdr->hdr_entsz)));
|
||||
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
|
||||
|
||||
gpt_write(fd, gpt);
|
||||
gpt_write(fd, tbl);
|
||||
@ -268,11 +273,11 @@ migrate(int fd)
|
||||
*/
|
||||
memcpy(tpg->map_data, gpt->map_data, secsz);
|
||||
hdr = tpg->map_data;
|
||||
hdr->hdr_lba_self = tpg->map_start;
|
||||
hdr->hdr_lba_alt = gpt->map_start;
|
||||
hdr->hdr_lba_table = lbt->map_start;
|
||||
hdr->hdr_lba_self = htole64(tpg->map_start);
|
||||
hdr->hdr_lba_alt = htole64(gpt->map_start);
|
||||
hdr->hdr_lba_table = htole64(lbt->map_start);
|
||||
hdr->hdr_crc_self = 0; /* Don't ever forget this! */
|
||||
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
|
||||
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
|
||||
|
||||
gpt_write(fd, lbt);
|
||||
gpt_write(fd, tpg);
|
||||
@ -291,13 +296,13 @@ migrate(int fd)
|
||||
mbr->mbr_part[0].part_ehd = 0xff;
|
||||
mbr->mbr_part[0].part_esect = 0xff;
|
||||
mbr->mbr_part[0].part_ecyl = 0xff;
|
||||
mbr->mbr_part[0].part_start_lo = 1;
|
||||
mbr->mbr_part[0].part_start_lo = htole16(1);
|
||||
if (mediasz > 0xffffffff) {
|
||||
mbr->mbr_part[0].part_size_lo = 0xffff;
|
||||
mbr->mbr_part[0].part_size_hi = 0xffff;
|
||||
mbr->mbr_part[0].part_size_lo = htole16(0xffff);
|
||||
mbr->mbr_part[0].part_size_hi = htole16(0xffff);
|
||||
} else {
|
||||
mbr->mbr_part[0].part_size_lo = mediasz & 0xffff;
|
||||
mbr->mbr_part[0].part_size_hi = mediasz >> 16;
|
||||
mbr->mbr_part[0].part_size_lo = htole16(mediasz);
|
||||
mbr->mbr_part[0].part_size_hi = htole16(mediasz >> 16);
|
||||
}
|
||||
gpt_write(fd, map);
|
||||
}
|
||||
|
@ -28,7 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/gpt.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stddef.h>
|
||||
@ -116,11 +115,11 @@ recover(int fd)
|
||||
}
|
||||
memcpy(tpg->map_data, gpt->map_data, secsz);
|
||||
hdr = tpg->map_data;
|
||||
hdr->hdr_lba_self = tpg->map_start;
|
||||
hdr->hdr_lba_alt = gpt->map_start;
|
||||
hdr->hdr_lba_table = lbt->map_start;
|
||||
hdr->hdr_lba_self = htole64(tpg->map_start);
|
||||
hdr->hdr_lba_alt = htole64(gpt->map_start);
|
||||
hdr->hdr_lba_table = htole64(lbt->map_start);
|
||||
hdr->hdr_crc_self = 0;
|
||||
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
|
||||
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
|
||||
gpt_write(fd, tpg);
|
||||
warnx("%s: recovered secondary GPT header from primary",
|
||||
device_name);
|
||||
@ -134,11 +133,11 @@ recover(int fd)
|
||||
}
|
||||
memcpy(gpt->map_data, tpg->map_data, secsz);
|
||||
hdr = gpt->map_data;
|
||||
hdr->hdr_lba_self = gpt->map_start;
|
||||
hdr->hdr_lba_alt = tpg->map_start;
|
||||
hdr->hdr_lba_table = tbl->map_start;
|
||||
hdr->hdr_lba_self = htole64(gpt->map_start);
|
||||
hdr->hdr_lba_alt = htole64(tpg->map_start);
|
||||
hdr->hdr_lba_table = htole64(tbl->map_start);
|
||||
hdr->hdr_crc_self = 0;
|
||||
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
|
||||
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
|
||||
gpt_write(fd, gpt);
|
||||
warnx("%s: recovered primary GPT header from secondary",
|
||||
device_name);
|
||||
|
@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/gpt.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stddef.h>
|
||||
@ -37,7 +36,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <uuid.h>
|
||||
|
||||
#include "map.h"
|
||||
#include "gpt.h"
|
||||
@ -59,6 +57,7 @@ usage_remove(void)
|
||||
static void
|
||||
rem(int fd)
|
||||
{
|
||||
uuid_t uuid;
|
||||
map_t *gpt, *tpg;
|
||||
map_t *tbl, *lbt;
|
||||
map_t *m;
|
||||
@ -103,28 +102,31 @@ rem(int fd)
|
||||
i = m->map_index - 1;
|
||||
|
||||
hdr = gpt->map_data;
|
||||
ent = (void*)((char*)tbl->map_data + i * hdr->hdr_entsz);
|
||||
ent = (void*)((char*)tbl->map_data + i *
|
||||
le32toh(hdr->hdr_entsz));
|
||||
le_uuid_dec(&ent->ent_type, &uuid);
|
||||
if (!uuid_is_nil(&type, NULL) &&
|
||||
!uuid_equal(&type, &ent->ent_type, NULL))
|
||||
!uuid_equal(&type, &uuid, NULL))
|
||||
continue;
|
||||
uuid_create_nil(&ent->ent_type, NULL);
|
||||
|
||||
hdr->hdr_crc_table = crc32(tbl->map_data,
|
||||
hdr->hdr_entries * hdr->hdr_entsz);
|
||||
hdr->hdr_crc_table = htole32(crc32(tbl->map_data,
|
||||
le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz)));
|
||||
hdr->hdr_crc_self = 0;
|
||||
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
|
||||
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
|
||||
|
||||
gpt_write(fd, gpt);
|
||||
gpt_write(fd, tbl);
|
||||
|
||||
hdr = tpg->map_data;
|
||||
ent = (void*)((char*)lbt->map_data + i * hdr->hdr_entsz);
|
||||
ent = (void*)((char*)lbt->map_data + i *
|
||||
le32toh(hdr->hdr_entsz));
|
||||
uuid_create_nil(&ent->ent_type, NULL);
|
||||
|
||||
hdr->hdr_crc_table = crc32(lbt->map_data,
|
||||
hdr->hdr_entries * hdr->hdr_entsz);
|
||||
hdr->hdr_crc_table = htole32(crc32(lbt->map_data,
|
||||
le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz)));
|
||||
hdr->hdr_crc_self = 0;
|
||||
hdr->hdr_crc_self = crc32(hdr, hdr->hdr_size);
|
||||
hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size)));
|
||||
|
||||
gpt_write(fd, lbt);
|
||||
gpt_write(fd, tpg);
|
||||
|
@ -28,7 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/gpt.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stddef.h>
|
||||
@ -36,7 +35,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <uuid.h>
|
||||
|
||||
#include "map.h"
|
||||
#include "gpt.h"
|
||||
@ -91,6 +89,7 @@ friendly(uuid_t *t)
|
||||
static void
|
||||
show(int fd __unused)
|
||||
{
|
||||
uuid_t type;
|
||||
off_t start;
|
||||
map_t *m, *p;
|
||||
struct mbr *mbr;
|
||||
@ -138,8 +137,9 @@ show(int fd __unused)
|
||||
printf("MBR part ");
|
||||
mbr = p->map_data;
|
||||
for (i = 0; i < 4; i++) {
|
||||
start = mbr->mbr_part[i].part_start_hi << 16;
|
||||
start += mbr->mbr_part[i].part_start_lo;
|
||||
start = le16toh(mbr->mbr_part[i].part_start_hi);
|
||||
start = (start << 16) +
|
||||
le16toh(mbr->mbr_part[i].part_start_lo);
|
||||
if (m->map_start == p->map_start + start)
|
||||
break;
|
||||
}
|
||||
@ -148,7 +148,8 @@ show(int fd __unused)
|
||||
case MAP_TYPE_GPT_PART:
|
||||
printf("GPT part ");
|
||||
ent = m->map_data;
|
||||
printf("- %s", friendly(&ent->ent_type));
|
||||
le_uuid_dec(&ent->ent_type, &type);
|
||||
printf("- %s", friendly(&type));
|
||||
break;
|
||||
case MAP_TYPE_PMBR:
|
||||
printf("PMBR");
|
||||
|
Loading…
Reference in New Issue
Block a user