- convert FreeBSD FS_<type> to numbers where they don't match NetBSD

- add support for migrating NetBSD disklabel'ed disks (only 7 years late)
- use labels for partition types
This commit is contained in:
jnemeth 2013-10-19 08:13:21 +00:00
parent 793910b681
commit 000bb24ef9
1 changed files with 104 additions and 6 deletions

View File

@ -29,11 +29,12 @@
__FBSDID("$FreeBSD: src/sbin/gpt/migrate.c,v 1.16 2005/09/01 02:42:52 marcel Exp $"); __FBSDID("$FreeBSD: src/sbin/gpt/migrate.c,v 1.16 2005/09/01 02:42:52 marcel Exp $");
#endif #endif
#ifdef __RCSID #ifdef __RCSID
__RCSID("$NetBSD: migrate.c,v 1.8 2013/10/19 01:58:33 jnemeth Exp $"); __RCSID("$NetBSD: migrate.c,v 1.9 2013/10/19 08:13:21 jnemeth Exp $");
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/bootblock.h>
#include <sys/disklabel.h> #include <sys/disklabel.h>
#include <err.h> #include <err.h>
@ -119,14 +120,14 @@ migrate_disklabel(int fd, off_t start, struct gpt_ent *ent)
ent->ent_name, 36); ent->ent_name, 36);
break; break;
} }
case FS_VINUM: { case 14: { /* Vinum */
static const uuid_t vinum = GPT_ENT_TYPE_FREEBSD_VINUM; static const uuid_t vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
le_uuid_enc(ent->ent_type, &vinum); le_uuid_enc(ent->ent_type, &vinum);
utf8_to_utf16((const uint8_t *)"FreeBSD vinum partition", utf8_to_utf16((const uint8_t *)"FreeBSD vinum partition",
ent->ent_name, 36); ent->ent_name, 36);
break; break;
} }
case FS_ZFS: { case 27: { /* ZFS */
static const uuid_t zfs = GPT_ENT_TYPE_FREEBSD_ZFS; static const uuid_t zfs = GPT_ENT_TYPE_FREEBSD_ZFS;
le_uuid_enc(ent->ent_type, &zfs); le_uuid_enc(ent->ent_type, &zfs);
utf8_to_utf16((const uint8_t *)"FreeBSD ZFS partition", utf8_to_utf16((const uint8_t *)"FreeBSD ZFS partition",
@ -151,6 +152,100 @@ migrate_disklabel(int fd, off_t start, struct gpt_ent *ent)
return (ent); return (ent);
} }
static struct gpt_ent*
migrate_netbsd_disklabel(int fd, off_t start, struct gpt_ent *ent)
{
char *buf;
struct disklabel *dl;
off_t ofs, rawofs;
int i;
buf = gpt_read(fd, start + LABELSECTOR, 1);
dl = (void*)(buf + LABELOFFSET);
if (le32toh(dl->d_magic) != DISKMAGIC ||
le32toh(dl->d_magic2) != DISKMAGIC) {
warnx("%s: warning: NetBSD slice without disklabel",
device_name);
return (ent);
}
rawofs = le32toh(dl->d_partitions[RAW_PART].p_offset) *
le32toh(dl->d_secsize);
for (i = 0; i < le16toh(dl->d_npartitions); i++) {
if (dl->d_partitions[i].p_fstype == FS_UNUSED)
continue;
ofs = le32toh(dl->d_partitions[i].p_offset) *
le32toh(dl->d_secsize);
if (ofs < rawofs)
rawofs = 0;
}
rawofs /= secsz;
for (i = 0; i < le16toh(dl->d_npartitions); i++) {
switch (dl->d_partitions[i].p_fstype) {
case FS_UNUSED:
continue;
case FS_SWAP: {
static const uuid_t swap = GPT_ENT_TYPE_NETBSD_SWAP;
le_uuid_enc(ent->ent_type, &swap);
utf8_to_utf16((const uint8_t *)"NetBSD swap partition",
ent->ent_name, 36);
break;
}
case FS_BSDFFS: {
static const uuid_t ufs = GPT_ENT_TYPE_NETBSD_FFS;
le_uuid_enc(ent->ent_type, &ufs);
utf8_to_utf16((const uint8_t *)"NetBSD FFS partition",
ent->ent_name, 36);
break;
}
case FS_BSDLFS: {
static const uuid_t zfs = GPT_ENT_TYPE_NETBSD_LFS;
le_uuid_enc(ent->ent_type, &zfs);
utf8_to_utf16((const uint8_t *)"NetBSD LFS partition",
ent->ent_name, 36);
break;
}
case FS_RAID: {
static const uuid_t zfs = GPT_ENT_TYPE_NETBSD_RAIDFRAME;
le_uuid_enc(ent->ent_type, &zfs);
utf8_to_utf16((const uint8_t *)"NetBSD RAIDframe partition",
ent->ent_name, 36);
break;
}
case FS_CCD: {
static const uuid_t zfs = GPT_ENT_TYPE_NETBSD_CCD;
le_uuid_enc(ent->ent_type, &zfs);
utf8_to_utf16((const uint8_t *)"NetBSD CCD partition",
ent->ent_name, 36);
break;
}
case FS_CGD: {
static const uuid_t zfs = GPT_ENT_TYPE_NETBSD_CGD;
le_uuid_enc(ent->ent_type, &zfs);
utf8_to_utf16((const uint8_t *)"NetBSD CGD partition",
ent->ent_name, 36);
break;
}
default:
warnx("%s: warning: unknown NetBSD partition (%d)",
device_name, dl->d_partitions[i].p_fstype);
continue;
}
ofs = (le32toh(dl->d_partitions[i].p_offset) *
le32toh(dl->d_secsize)) / secsz;
ofs = (ofs > 0) ? ofs - rawofs : 0;
ent->ent_lba_start = htole64(start + ofs);
ent->ent_lba_end = htole64(start + ofs +
le32toh(dl->d_partitions[i].p_size) - 1LL);
ent++;
}
return (ent);
}
static void static void
migrate(int fd) migrate(int fd)
{ {
@ -262,9 +357,9 @@ migrate(int fd)
size = (size << 16) + le16toh(mbr->mbr_part[i].part_size_lo); size = (size << 16) + le16toh(mbr->mbr_part[i].part_size_lo);
switch (mbr->mbr_part[i].part_typ) { switch (mbr->mbr_part[i].part_typ) {
case 0: case MBR_PTYPE_UNUSED:
continue; continue;
case 165: { /* FreeBSD */ case MBR_PTYPE_386BSD: { /* FreeBSD */
if (slice) { if (slice) {
static const uuid_t freebsd = GPT_ENT_TYPE_FREEBSD; static const uuid_t freebsd = GPT_ENT_TYPE_FREEBSD;
le_uuid_enc(ent->ent_type, &freebsd); le_uuid_enc(ent->ent_type, &freebsd);
@ -277,7 +372,10 @@ migrate(int fd)
ent = migrate_disklabel(fd, start, ent); ent = migrate_disklabel(fd, start, ent);
break; break;
} }
case 239: { /* EFI */ case MBR_PTYPE_NETBSD:
ent = migrate_netbsd_disklabel(fd, start, ent);
break;
case MBR_PTYPE_EFI: {
static const uuid_t efi_slice = GPT_ENT_TYPE_EFI; static const uuid_t efi_slice = GPT_ENT_TYPE_EFI;
le_uuid_enc(ent->ent_type, &efi_slice); le_uuid_enc(ent->ent_type, &efi_slice);
ent->ent_lba_start = htole64((uint64_t)start); ent->ent_lba_start = htole64((uint64_t)start);