[BACK]Return to migrate.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / gpt

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

Diff for /src/sbin/gpt/migrate.c between version 1.14 and 1.14.4.2

version 1.14, 2013/12/04 20:15:51 version 1.14.4.2, 2018/08/13 16:12:12
Line 24 
Line 24 
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */   */
   
   #if HAVE_NBTOOL_CONFIG_H
   #include "nbtool_config.h"
   #endif
   
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 #ifdef __FBSDID  #ifdef __FBSDID
 __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 $");
Line 34  __RCSID("$NetBSD$");
Line 38  __RCSID("$NetBSD$");
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/param.h>  #include <sys/param.h>
   #define FSTYPENAMES
   #define MBRPTYPENAMES
   #ifdef HAVE_NBTOOL_CONFIG_H
   #include <nbinclude/sys/bootblock.h>
   #include <nbinclude/sys/disklabel.h>
   #else
 #include <sys/bootblock.h>  #include <sys/bootblock.h>
 #include <sys/disklabel.h>  #include <sys/disklabel.h>
   #endif
   
 #include <err.h>  #include <err.h>
 #include <stddef.h>  #include <stddef.h>
Line 46  __RCSID("$NetBSD$");
Line 57  __RCSID("$NetBSD$");
   
 #include "map.h"  #include "map.h"
 #include "gpt.h"  #include "gpt.h"
   #include "gpt_private.h"
   
 /*  /*
  * Allow compilation on platforms that do not have a BSD label.   * Allow compilation on platforms that do not have a BSD label.
  * The values are valid for amd64, i386 and ia64 disklabels.   * The values are valid for amd64, i386 and ia64 disklabels.
    * XXX: use disklabel_params from disklabel.c
  */   */
 #ifndef LABELOFFSET  #ifndef LABELOFFSET
 #define LABELOFFSET     0  #define LABELOFFSET     0
Line 57  __RCSID("$NetBSD$");
Line 70  __RCSID("$NetBSD$");
 #ifndef LABELSECTOR  #ifndef LABELSECTOR
 #define LABELSECTOR     1  #define LABELSECTOR     1
 #endif  #endif
   #ifndef RAW_PART
   #define RAW_PART        3
   #endif
   
 /* FreeBSD filesystem types that don't match corresponding NetBSD types */  /* FreeBSD filesystem types that don't match corresponding NetBSD types */
 #define FREEBSD_FS_VINUM        14  #define FREEBSD_FS_VINUM        14
 #define FREEBSD_FS_ZFS          27  #define FREEBSD_FS_ZFS          27
   
 static int force;  static int cmd_migrate(gpt_t, int, char *[]);
 static int slice;  
   
 const char migratemsg[] = "migrate [-fs] device ...";  static const char *migratehelp[] = {
           "[-Afs] [-p partitions]",
   };
   
   struct gpt_cmd c_migrate = {
           "migrate",
           cmd_migrate,
           migratehelp, __arraycount(migratehelp),
           GPT_SYNC,
   };
   
 __dead static void  #define usage() gpt_usage(NULL, &c_migrate)
 usage_migrate(void)  
 {  
   
         fprintf(stderr,  static const char *
             "usage: %s %s\n", getprogname(), migratemsg);  fstypename(u_int t)
         exit(1);  {
           static char buf[64];
           if (t >= __arraycount(fstypenames)) {
                   snprintf(buf, sizeof(buf), "*%u*", t);
                   return buf;
           }
           return fstypenames[t];
 }  }
   
 static struct gpt_ent*  static const char *
 migrate_disklabel(int fd, off_t start, struct gpt_ent *ent)  mbrptypename(u_int t)
 {  {
         char *buf;          static char buf[64];
         struct disklabel *dl;          size_t i;
         off_t ofs, rawofs;  
         int i;  
   
         buf = gpt_read(fd, start + LABELSECTOR, 1);          for (i = 0; i < __arraycount(mbr_ptypes); i++)
         dl = (void*)(buf + LABELOFFSET);                  if ((u_int)mbr_ptypes[i].id == t)
                           return mbr_ptypes[i].name;
   
         if (le32toh(dl->d_magic) != DISKMAGIC ||          snprintf(buf, sizeof(buf), "*%u*", t);
             le32toh(dl->d_magic2) != DISKMAGIC) {          return buf;
                 warnx("%s: warning: FreeBSD slice without disklabel",  }
                     device_name);  
                 free(buf);  
                 return (ent);  
         }  
   
         rawofs = le32toh(dl->d_partitions[RAW_PART].p_offset) *  static gpt_type_t
             le32toh(dl->d_secsize);  freebsd_fstype_to_gpt_type(gpt_t gpt, u_int i, u_int fstype)
         for (i = 0; i < le16toh(dl->d_npartitions); i++) {  {
                 if (dl->d_partitions[i].p_fstype == FS_UNUSED)          switch (fstype) {
                         continue;          case FS_UNUSED:
                 ofs = le32toh(dl->d_partitions[i].p_offset) *                  return GPT_TYPE_INVALID;
                     le32toh(dl->d_secsize);          case FS_SWAP:
                 if (ofs < rawofs)                  return GPT_TYPE_FREEBSD_SWAP;
                         rawofs = 0;          case FS_BSDFFS:
                   return GPT_TYPE_FREEBSD_UFS;
           case FREEBSD_FS_VINUM:
                   return GPT_TYPE_FREEBSD_VINUM;
           case FREEBSD_FS_ZFS:
                   return GPT_TYPE_FREEBSD_ZFS;
           default:
                   gpt_warnx(gpt, "Unknown FreeBSD partition (%d)", fstype);
                   return GPT_TYPE_INVALID;
         }          }
         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_FREEBSD_SWAP;  
                         le_uuid_enc(ent->ent_type, &swap);  
                         utf8_to_utf16((const uint8_t *)"FreeBSD swap partition",  
                             ent->ent_name, 36);  
                         break;  
                 }  
                 case FS_BSDFFS: {  
                         static const uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS;  
                         le_uuid_enc(ent->ent_type, &ufs);  
                         utf8_to_utf16((const uint8_t *)"FreeBSD UFS partition",  
                             ent->ent_name, 36);  
                         break;  
                 }  
                 case FREEBSD_FS_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 FREEBSD_FS_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",  
                             ent->ent_name, 36);  
                         break;  
                 }  
                 default:  
                         warnx("%s: warning: unknown FreeBSD partition (%d)",  
                             device_name, dl->d_partitions[i].p_fstype);  
                         continue;  
                 }  
   
                 ofs = (le32toh(dl->d_partitions[i].p_offset) *  static gpt_type_t
                     le32toh(dl->d_secsize)) / secsz;  netbsd_fstype_to_gpt_type(gpt_t gpt, u_int i, u_int fstype)
                 ofs = (ofs > 0) ? ofs - rawofs : 0;  {
                 ent->ent_lba_start = htole64(start + ofs);          switch (fstype) {
                 ent->ent_lba_end = htole64(start + ofs +          case FS_UNUSED:
                     le32toh(dl->d_partitions[i].p_size) - 1LL);                  return GPT_TYPE_INVALID;
                 ent++;          case FS_HFS:
                   return GPT_TYPE_APPLE_HFS;
           case FS_EX2FS:
                   return GPT_TYPE_LINUX_DATA;
           case FS_SWAP:
                   return GPT_TYPE_NETBSD_SWAP;
           case FS_BSDFFS:
                   return GPT_TYPE_NETBSD_FFS;
           case FS_BSDLFS:
                   return GPT_TYPE_NETBSD_LFS;
           case FS_RAID:
                   return GPT_TYPE_NETBSD_RAIDFRAME;
           case FS_CCD:
                   return GPT_TYPE_NETBSD_CCD;
           case FS_CGD:
                   return GPT_TYPE_NETBSD_CGD;
           default:
                   gpt_warnx(gpt, "Partition %u unknown type %s, "
                       "using \"Microsoft Basic Data\"", i, fstypename(fstype));
                   return GPT_TYPE_MS_BASIC_DATA;
         }          }
   
         free(buf);  
         return (ent);  
 }  }
   
 static struct gpt_ent*  static struct gpt_ent *
 migrate_netbsd_disklabel(int fd, off_t start, struct gpt_ent *ent)  migrate_disklabel(gpt_t gpt, off_t start, struct gpt_ent *ent,
       gpt_type_t (*convert)(gpt_t, u_int, u_int))
 {  {
         char *buf;          char *buf;
         struct disklabel *dl;          struct disklabel *dl;
         off_t ofs, rawofs;          off_t ofs, rawofs;
         int i;          unsigned int i;
           gpt_type_t type;
   
         buf = gpt_read(fd, start + LABELSECTOR, 1);          buf = gpt_read(gpt, start + LABELSECTOR, 1);
           if (buf == NULL) {
                   gpt_warn(gpt, "Error reading label");
                   return NULL;
           }
         dl = (void*)(buf + LABELOFFSET);          dl = (void*)(buf + LABELOFFSET);
   
         if (le32toh(dl->d_magic) != DISKMAGIC ||          if (le32toh(dl->d_magic) != DISKMAGIC ||
             le32toh(dl->d_magic2) != DISKMAGIC) {              le32toh(dl->d_magic2) != DISKMAGIC) {
                 warnx("%s: warning: NetBSD slice without disklabel",                  gpt_warnx(gpt, "MBR partition without disklabel");
                     device_name);  
                 free(buf);                  free(buf);
                 return (ent);                  return ent;
         }          }
   
         rawofs = le32toh(dl->d_partitions[RAW_PART].p_offset) *          rawofs = le32toh(dl->d_partitions[RAW_PART].p_offset) *
Line 187  migrate_netbsd_disklabel(int fd, off_t s
Line 201  migrate_netbsd_disklabel(int fd, off_t s
                 if (ofs < rawofs)                  if (ofs < rawofs)
                         rawofs = 0;                          rawofs = 0;
         }          }
         rawofs /= secsz;  
           if (gpt->verbose > 1)
                   gpt_msg(gpt, "rawofs=%ju", (uintmax_t)rawofs);
           rawofs /= gpt->secsz;
   
         for (i = 0; i < le16toh(dl->d_npartitions); i++) {          for (i = 0; i < le16toh(dl->d_npartitions); i++) {
                 switch (dl->d_partitions[i].p_fstype) {                  if (gpt->verbose > 1)
                 case FS_UNUSED:                          gpt_msg(gpt, "Disklabel partition %u type %s", i,
                         continue;                              fstypename(dl->d_partitions[i].p_fstype));
                 case FS_SWAP: {  
                         static const uuid_t swap = GPT_ENT_TYPE_NETBSD_SWAP;                  type = (*convert)(gpt, i, dl->d_partitions[i].p_fstype);
                         le_uuid_enc(ent->ent_type, &swap);                  if (type == GPT_TYPE_INVALID)
                         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;                          continue;
                 }  
                   gpt_uuid_create(type, ent->ent_type,
                       ent->ent_name, sizeof(ent->ent_name));
   
                 ofs = (le32toh(dl->d_partitions[i].p_offset) *                  ofs = (le32toh(dl->d_partitions[i].p_offset) *
                     le32toh(dl->d_secsize)) / secsz;                      le32toh(dl->d_secsize)) / gpt->secsz;
                 ofs = (ofs > 0) ? ofs - rawofs : 0;                  ofs = (ofs > 0) ? ofs - rawofs : 0;
                 ent->ent_lba_start = htole64(ofs);                  ent->ent_lba_start = htole64((uint64_t)ofs);
                 ent->ent_lba_end = htole64(ofs +                  ent->ent_lba_end = htole64((uint64_t)(ofs +
                     le32toh(dl->d_partitions[i].p_size) - 1LL);                      (off_t)le32toh((uint64_t)dl->d_partitions[i].p_size)
                       - 1LL));
                 ent++;                  ent++;
         }          }
   
         free(buf);          free(buf);
         return (ent);          return ent;
 }  }
   
 static void  static int
 migrate(int fd)  migrate(gpt_t gpt, u_int parts, int force, int slice, int active)
 {  {
         uuid_t uuid;          off_t last = gpt_last(gpt);
         off_t blocks, last;          map_t map;
         map_t *gpt, *tpg;  
         map_t *tbl, *lbt;  
         map_t *map;  
         struct gpt_hdr *hdr;  
         struct gpt_ent *ent;          struct gpt_ent *ent;
         struct mbr *mbr;          struct mbr *mbr;
         uint32_t start, size;          uint32_t start, size;
         unsigned int i;          unsigned int i;
           gpt_type_t type = GPT_TYPE_INVALID;
   
         last = mediasz / secsz - 1LL;          map = map_find(gpt, MAP_TYPE_MBR);
   
         map = map_find(MAP_TYPE_MBR);  
         if (map == NULL || map->map_start != 0) {          if (map == NULL || map->map_start != 0) {
                 warnx("%s: error: no partitions to convert", device_name);                  gpt_warnx(gpt, "No MBR in disk to convert");
                 return;                  return -1;
         }          }
   
         mbr = map->map_data;          mbr = map->map_data;
   
         if (map_find(MAP_TYPE_PRI_GPT_HDR) != NULL ||          if (gpt_create(gpt, last, parts, 0) == -1)
             map_find(MAP_TYPE_SEC_GPT_HDR) != NULL) {                  return -1;
                 warnx("%s: error: device already contains a GPT", device_name);  
                 return;  
         }  
   
         /* Get the amount of free space after the MBR */  
         blocks = map_free(1LL, 0LL);  
         if (blocks == 0LL) {  
                 warnx("%s: error: no room for the GPT header", device_name);  
                 return;  
         }  
   
         /* Don't create more than parts entries. */  
         if ((uint64_t)(blocks - 1) * secsz > parts * sizeof(struct gpt_ent)) {  
                 blocks = (parts * sizeof(struct gpt_ent)) / secsz;  
                 if ((parts * sizeof(struct gpt_ent)) % secsz)  
                         blocks++;  
                 blocks++;               /* Don't forget the header itself */  
         }  
   
         /* Never cross the median of the device. */  
         if ((blocks + 1LL) > ((last + 1LL) >> 1))  
                 blocks = ((last + 1LL) >> 1) - 1LL;  
   
         /*          ent = gpt->tbl->map_data;
          * Get the amount of free space at the end of the device and  
          * calculate the size for the GPT structures.  
          */  
         map = map_last();  
         if (map->map_type != MAP_TYPE_UNUSED) {  
                 warnx("%s: error: no room for the backup header", device_name);  
                 return;  
         }  
   
         if (map->map_size < blocks)  
                 blocks = map->map_size;  
         if (blocks == 1LL) {  
                 warnx("%s: error: no room for the GPT table", device_name);  
                 return;  
         }  
   
         blocks--;               /* Number of blocks in the GPT table. */  
         gpt = map_add(1LL, 1LL, MAP_TYPE_PRI_GPT_HDR, calloc(1, secsz));  
         tbl = map_add(2LL, blocks, MAP_TYPE_PRI_GPT_TBL,  
             calloc(blocks, secsz));  
         if (gpt == NULL || tbl == NULL)  
                 return;  
   
         lbt = map_add(last - blocks, blocks, MAP_TYPE_SEC_GPT_TBL,  
             tbl->map_data);  
         tpg = map_add(last, 1LL, MAP_TYPE_SEC_GPT_HDR, calloc(1, secsz));  
   
         hdr = gpt->map_data;  
         memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));  
         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 = htole32(GPT_SIZE);  
         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 < le32toh(hdr->hdr_entries); i++) {  
                 uuid_create(&uuid, NULL);  
                 le_uuid_enc(ent[i].ent_uuid, &uuid);  
         }  
   
         /* Mirror partitions. */          /* Mirror partitions. */
         for (i = 0; i < 4; i++) {          for (i = 0; i < 4; i++) {
Line 364  migrate(int fd)
Line 263  migrate(int fd)
                 size = le16toh(mbr->mbr_part[i].part_size_hi);                  size = le16toh(mbr->mbr_part[i].part_size_hi);
                 size = (size << 16) + le16toh(mbr->mbr_part[i].part_size_lo);                  size = (size << 16) + le16toh(mbr->mbr_part[i].part_size_lo);
   
                   if (gpt->verbose > 1)
                           gpt_msg(gpt, "MBR partition %u type %s", i,
                               mbrptypename(mbr->mbr_part[i].part_typ));
                 switch (mbr->mbr_part[i].part_typ) {                  switch (mbr->mbr_part[i].part_typ) {
                 case MBR_PTYPE_UNUSED:                  case MBR_PTYPE_UNUSED:
                         continue;                          continue;
                 case MBR_PTYPE_386BSD: {        /* FreeBSD */  
                   case MBR_PTYPE_386BSD: /* FreeBSD */
                         if (slice) {                          if (slice) {
                                 static const uuid_t freebsd = GPT_ENT_TYPE_FREEBSD;                                  type = GPT_TYPE_FREEBSD;
                                 le_uuid_enc(ent->ent_type, &freebsd);                                  break;
                                 ent->ent_lba_start = htole64((uint64_t)start);                          } else {
                                 ent->ent_lba_end = htole64(start + size - 1LL);                                  ent = migrate_disklabel(gpt, start, ent,
                                 utf8_to_utf16((const uint8_t *)"FreeBSD disklabel partition",                                      freebsd_fstype_to_gpt_type);
                                     ent->ent_name, 36);                                  continue;
                                 ent++;                          }
                         } else  
                                 ent = migrate_disklabel(fd, start, ent);                  case MBR_PTYPE_NETBSD:  /* NetBSD */
                         break;                          ent = migrate_disklabel(gpt, start, ent,
                 }                              netbsd_fstype_to_gpt_type);
                 case MBR_PTYPE_NETBSD:                          continue;
                         ent = migrate_netbsd_disklabel(fd, start, ent);  
                         break;                  case MBR_PTYPE_EFI:
                 case MBR_PTYPE_EFI: {                          type = GPT_TYPE_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);  
                         ent->ent_lba_end = htole64(start + size - 1LL);  
                         utf8_to_utf16((const uint8_t *)"EFI system partition",  
                             ent->ent_name, 36);  
                         ent++;  
                         break;                          break;
                 }  
                 default:                  default:
                         if (!force) {                          if (!force) {
                                 warnx("%s: error: unknown partition type (%d)",                                  gpt_warnx(gpt, "unknown partition type (%d)",
                                     device_name, mbr->mbr_part[i].part_typ);                                      mbr->mbr_part[i].part_typ);
                                 return;                                  return -1;
                         }                          }
                           continue;
                 }                  }
                   gpt_uuid_create(type, ent->ent_type, ent->ent_name,
                       sizeof(ent->ent_name));
                   ent->ent_lba_start = htole64((uint64_t)start);
                   ent->ent_lba_end = htole64((uint64_t)(start + size - 1LL));
                   ent++;
         }          }
         ent = tbl->map_data;  
   
         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);          if (gpt_write_primary(gpt) == -1)
         gpt_write(fd, tbl);                  return -1;
   
         /*          if (gpt_write_backup(gpt) == -1)
          * Create backup GPT.                  return -1;
          */  
         memcpy(tpg->map_data, gpt->map_data, secsz);  
         hdr = tpg->map_data;  
         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 = htole32(crc32(hdr, le32toh(hdr->hdr_size)));  
   
         gpt_write(fd, lbt);  
         gpt_write(fd, tpg);  
   
         map = map_find(MAP_TYPE_MBR);  
         mbr = map->map_data;  
         /*          /*
          * Turn the MBR into a Protective MBR.           * Turn the MBR into a Protective MBR.
          */           */
         bzero(mbr->mbr_part, sizeof(mbr->mbr_part));          memset(mbr->mbr_part, 0, sizeof(mbr->mbr_part));
         mbr->mbr_part[0].part_shd = 0x00;          gpt_create_pmbr_part(mbr->mbr_part, last, active);
         mbr->mbr_part[0].part_ssect = 0x02;          if (gpt_write(gpt, map) == -1) {
         mbr->mbr_part[0].part_scyl = 0x00;                  gpt_warn(gpt, "Cant write PMBR");
         mbr->mbr_part[0].part_typ = MBR_PTYPE_PMBR;                  return -1;
         mbr->mbr_part[0].part_ehd = 0xfe;  
         mbr->mbr_part[0].part_esect = 0xff;  
         mbr->mbr_part[0].part_ecyl = 0xff;  
         mbr->mbr_part[0].part_start_lo = htole16(1);  
         if (last > 0xffffffff) {  
                 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 = htole16(last);  
                 mbr->mbr_part[0].part_size_hi = htole16(last >> 16);  
         }          }
         gpt_write(fd, map);          return 0;
 }  }
   
 int  static int
 cmd_migrate(int argc, char *argv[])  cmd_migrate(gpt_t gpt, int argc, char *argv[])
 {  {
         int ch, fd;          int ch;
           int force = 0;
           int slice = 0;
           int active = 0;
           u_int parts = 128;
   
         /* Get the migrate options */          /* Get the migrate options */
         while ((ch = getopt(argc, argv, "fs")) != -1) {          while ((ch = getopt(argc, argv, "Afp:s")) != -1) {
                 switch(ch) {                  switch(ch) {
                   case 'A':
                           active = 1;
                           break;
                 case 'f':                  case 'f':
                         force = 1;                          force = 1;
                         break;                          break;
                   case 'p':
                           if (gpt_uint_get(gpt, &parts) == -1)
                                   return usage();
                           break;
                 case 's':                  case 's':
                         slice = 1;                          slice = 1;
                         break;                          break;
                 default:                  default:
                         usage_migrate();                          return usage();
                 }                  }
         }          }
   
         if (argc == optind)          if (argc != optind)
                 usage_migrate();                  return usage();
   
         while (optind < argc) {  
                 fd = gpt_open(argv[optind++]);  
                 if (fd == -1) {  
                         warn("unable to open device '%s'", device_name);  
                         continue;  
                 }  
   
                 migrate(fd);  
   
                 gpt_close(fd);  
         }  
   
         return (0);          return migrate(gpt, parts, force, slice, active);
 }  }

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.14.4.2

CVSweb <webmaster@jp.NetBSD.org>