From 000bb24ef9fd12e7aca549902b3af5b5b6f66c1c Mon Sep 17 00:00:00 2001 From: jnemeth Date: Sat, 19 Oct 2013 08:13:21 +0000 Subject: [PATCH] - convert FreeBSD FS_ 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 --- sbin/gpt/migrate.c | 110 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 6 deletions(-) diff --git a/sbin/gpt/migrate.c b/sbin/gpt/migrate.c index 1bc0fee06497..130e7fd5e5a7 100644 --- a/sbin/gpt/migrate.c +++ b/sbin/gpt/migrate.c @@ -29,11 +29,12 @@ __FBSDID("$FreeBSD: src/sbin/gpt/migrate.c,v 1.16 2005/09/01 02:42:52 marcel Exp $"); #endif #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 #include #include +#include #include #include @@ -119,14 +120,14 @@ migrate_disklabel(int fd, off_t start, struct gpt_ent *ent) ent->ent_name, 36); break; } - case FS_VINUM: { + case 14: { /* Vinum */ static const uuid_t vinum = GPT_ENT_TYPE_FREEBSD_VINUM; le_uuid_enc(ent->ent_type, &vinum); utf8_to_utf16((const uint8_t *)"FreeBSD vinum partition", ent->ent_name, 36); break; } - case FS_ZFS: { + case 27: { /* ZFS */ static const uuid_t zfs = GPT_ENT_TYPE_FREEBSD_ZFS; le_uuid_enc(ent->ent_type, &zfs); 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); } +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 migrate(int fd) { @@ -262,9 +357,9 @@ migrate(int fd) size = (size << 16) + le16toh(mbr->mbr_part[i].part_size_lo); switch (mbr->mbr_part[i].part_typ) { - case 0: + case MBR_PTYPE_UNUSED: continue; - case 165: { /* FreeBSD */ + case MBR_PTYPE_386BSD: { /* FreeBSD */ if (slice) { static const uuid_t freebsd = GPT_ENT_TYPE_FREEBSD; le_uuid_enc(ent->ent_type, &freebsd); @@ -277,7 +372,10 @@ migrate(int fd) ent = migrate_disklabel(fd, start, ent); 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; le_uuid_enc(ent->ent_type, &efi_slice); ent->ent_lba_start = htole64((uint64_t)start);