Module Name:    src
Committed By:   jnemeth
Date:           Sat Oct 19 08:13:21 UTC 2013

Modified Files:
        src/sbin/gpt: migrate.c

Log Message:
- 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


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sbin/gpt/migrate.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/gpt/migrate.c
diff -u src/sbin/gpt/migrate.c:1.8 src/sbin/gpt/migrate.c:1.9
--- src/sbin/gpt/migrate.c:1.8	Sat Oct 19 01:58:33 2013
+++ src/sbin/gpt/migrate.c	Sat Oct 19 08:13:21 2013
@@ -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 <sys/types.h>
 #include <sys/param.h>
+#include <sys/bootblock.h>
 #include <sys/disklabel.h>
 
 #include <err.h>
@@ -119,14 +120,14 @@ migrate_disklabel(int fd, off_t start, s
 			    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, s
 	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);

Reply via email to