Lines Matching defs:gpt
35 __FBSDID("$FreeBSD: src/sbin/gpt/gpt.c,v 1.16 2006/07/07 02:44:23 marcel Exp $");
38 __RCSID("$NetBSD: gpt.c,v 1.90 2024/10/20 08:21:30 mlelstv Exp $");
60 #include "gpt.h"
247 gpt_read(gpt_t gpt, off_t lba, size_t count)
252 count *= gpt->secsz;
257 ofs = lba * gpt->secsz;
258 if (lseek(gpt->fd, ofs, SEEK_SET) == ofs &&
259 read(gpt->fd, buf, count) == (ssize_t)count)
267 gpt_write(gpt_t gpt, map_t map)
272 count = (size_t)(map->map_size * gpt->secsz);
273 ofs = map->map_start * gpt->secsz;
274 if (lseek(gpt->fd, ofs, SEEK_SET) != ofs ||
275 write(gpt->fd, map->map_data, count) != (ssize_t)count)
277 gpt->flags |= GPT_MODIFIED;
282 gpt_mbr(gpt_t gpt, off_t lba, unsigned int *next_index, off_t ext_offset)
289 mbr = gpt_read(gpt, lba, 1);
291 gpt_warn(gpt, "Read failed");
296 if (gpt->verbose)
297 gpt_msg(gpt,
314 else if ((gpt->flags & GPT_HYBRID) == 0)
319 gpt_warnx(gpt, "Suspicious PMBR at sector %ju",
321 else if (gpt->verbose > 1)
322 gpt_msg(gpt, "PMBR at sector %ju", (uintmax_t)lba);
323 p = map_add(gpt, lba, 1LL, MAP_TYPE_PMBR, mbr, 1);
327 gpt_warnx(gpt, "Suspicious MBR at sector %ju", (uintmax_t)lba);
328 else if (gpt->verbose > 1)
329 gpt_msg(gpt, "MBR at sector %ju", (uintmax_t)lba);
331 p = map_add(gpt, lba, 1LL, MAP_TYPE_MBR, mbr, 1);
344 gpt_warnx(gpt, "Malformed MBR at sector %ju",
348 if (gpt->verbose > 2)
349 gpt_msg(gpt, "MBR part: flag=%#x type=%d, start=%ju, "
355 m = map_add(gpt, start, size, MAP_TYPE_MBR_PART, p, 0);
362 if (gpt_mbr(gpt, start, next_index,
377 gpt_gpt(gpt_t gpt, off_t lba, int found)
388 hdr = gpt_read(gpt, lba, 1);
390 gpt_warn(gpt, "Read failed");
400 if (gpt->verbose)
401 gpt_msg(gpt, "Bad CRC in GPT header at sector %ju",
407 blocks = tblsz / gpt->secsz + ((tblsz % gpt->secsz) ? 1 : 0);
410 p = gpt_read(gpt, (off_t)le64toh((uint64_t)hdr->hdr_lba_table), blocks);
413 if (gpt->verbose)
414 gpt_msg(gpt,
423 if (gpt->verbose)
424 gpt_msg(gpt, "Bad CRC in GPT table at sector %ju",
429 if (gpt->verbose > 1)
430 gpt_msg(gpt, "%s GPT at sector %ju",
433 m = map_add(gpt, lba, 1, (lba == 1)
438 m = map_add(gpt, (off_t)le64toh((uint64_t)hdr->hdr_lba_table),
454 if (gpt->verbose > 2) {
458 gpt_msg(gpt, "GPT partition: type=%s, start=%ju, "
463 m = map_add(gpt, (off_t)le64toh((uint64_t)ent->ent_lba_start),
485 gpt_t gpt;
488 if ((gpt = calloc(1, sizeof(*gpt))) == NULL) {
493 gpt->flags = flags;
494 gpt->verbose = verbose;
495 gpt->mediasz = mediasz;
496 gpt->secsz = secsz;
497 gpt->timestamp = timestamp;
498 gpt->uuidgen = 0;
500 mode = (gpt->flags & GPT_READONLY) ? O_RDONLY : O_RDWR|O_EXCL;
502 gpt->fd = opendisk(dev, mode, gpt->device_name,
503 sizeof(gpt->device_name), 0);
504 if (gpt->fd == -1) {
505 strlcpy(gpt->device_name, dev, sizeof(gpt->device_name));
506 gpt_warn(gpt, "Cannot open");
510 if (fstat(gpt->fd, &gpt->sb) == -1) {
511 gpt_warn(gpt, "Cannot stat");
515 if ((gpt->sb.st_mode & S_IFMT) != S_IFREG) {
516 if (gpt->secsz == 0) {
518 if (ioctl(gpt->fd, DIOCGSECTORSIZE, &gpt->secsz) == -1) {
519 gpt_warn(gpt, "Cannot get sector size");
523 if (gpt->secsz == 0) {
524 gpt_warnx(gpt, "Sector size can't be 0");
528 if (gpt->mediasz == 0) {
530 if (ioctl(gpt->fd, DIOCGMEDIASIZE, &gpt->mediasz) == -1) {
531 gpt_warn(gpt, "Cannot get media size");
535 if (gpt->mediasz == 0) {
536 gpt_warnx(gpt, "Media size can't be 0");
541 gpt->flags |= GPT_FILE;
542 if (gpt->secsz == 0)
543 gpt->secsz = 512; /* Fixed size for files. */
544 if (gpt->mediasz == 0) {
545 if (gpt->sb.st_size % gpt->secsz) {
546 gpt_warn(gpt, "Media size not a multiple of sector size (%u)\n", gpt->secsz);
550 gpt->mediasz = gpt->sb.st_size;
552 gpt->flags |= GPT_NOSYNC;
561 devsz = gpt->mediasz / gpt->secsz;
563 gpt_warnx(gpt, "Need 6 sectors, we have %ju",
568 if (gpt->verbose) {
569 gpt_msg(gpt, "mediasize=%ju; sectorsize=%u; blocks=%ju",
570 (uintmax_t)gpt->mediasz, gpt->secsz, (uintmax_t)devsz);
573 if (map_init(gpt, devsz) == -1)
577 if (gpt_mbr(gpt, 0LL, &index, 0U) == -1)
579 if ((found = gpt_gpt(gpt, 1LL, 1)) == -1)
591 map = map_find(gpt, MAP_TYPE_PRI_GPT_HDR);
595 if (gpt_gpt(gpt, (off_t)lba, found) == -1)
599 if (gpt_gpt(gpt, devsz - 1LL, found) == -1)
603 return gpt;
606 if (gpt->fd != -1)
607 close(gpt->fd);
608 gpt_warn(gpt, "No GPT found");
609 free(gpt);
614 gpt_close(gpt_t gpt)
617 if (gpt == NULL)
620 if (!(gpt->flags & GPT_MODIFIED) || !(gpt->flags & GPT_SYNC))
623 if (!(gpt->flags & GPT_NOSYNC)) {
626 if (ioctl(gpt->fd, DIOCMWEDGES, &bits) == -1)
627 gpt_warn(gpt, "Can't update wedge information");
632 if (!(gpt->flags & GPT_FILE))
633 gpt_msg(gpt, "You need to run \"dkctl %s makewedges\""
634 " for the changes to take effect\n", gpt->device_name);
637 close(gpt->fd);
642 gpt_vwarnx(gpt_t gpt, const char *fmt, va_list ap, const char *e)
644 if (gpt && (gpt->flags & GPT_QUIET))
647 if (gpt)
648 fprintf(stderr, "%s: ", gpt->device_name);
657 gpt_warnx(gpt_t gpt, const char *fmt, ...)
662 gpt_vwarnx(gpt, fmt, ap, NULL);
667 gpt_warn(gpt_t gpt, const char *fmt, ...)
672 gpt_vwarnx(gpt, fmt, ap, strerror(errno));
677 gpt_msg(gpt_t gpt, const char *fmt, ...)
681 if (gpt && (gpt->flags & GPT_QUIET))
683 if (gpt)
684 printf("%s: ", gpt->device_name);
692 gpt_hdr(gpt_t gpt)
694 gpt->gpt = map_find(gpt, MAP_TYPE_PRI_GPT_HDR);
695 if (gpt->gpt == NULL) {
696 gpt_warnx(gpt, "No primary GPT header; run create or recover");
700 gpt->tpg = map_find(gpt, MAP_TYPE_SEC_GPT_HDR);
701 if (gpt->tpg == NULL) {
702 gpt_warnx(gpt, "No secondary GPT header; run recover");
706 gpt->tbl = map_find(gpt, MAP_TYPE_PRI_GPT_TBL);
707 gpt->lbt = map_find(gpt, MAP_TYPE_SEC_GPT_TBL);
708 if (gpt->tbl == NULL || gpt->lbt == NULL) {
709 gpt_warnx(gpt, "Corrupt maps, run recover");
713 return gpt->gpt->map_data;
717 gpt_write_crc(gpt_t gpt, map_t map, map_t tbl)
726 if (gpt_write(gpt, map) == -1) {
727 gpt_warn(gpt, "Error writing crc map");
731 if (gpt_write(gpt, tbl) == -1) {
732 gpt_warn(gpt, "Error writing crc table");
740 gpt_write_primary(gpt_t gpt)
742 return gpt_write_crc(gpt, gpt->gpt, gpt->tbl);
747 gpt_write_backup(gpt_t gpt)
749 return gpt_write_crc(gpt, gpt->tpg, gpt->lbt);
781 gpt_ent_primary(gpt_t gpt, unsigned int i)
783 return gpt_ent(gpt->gpt, gpt->tbl, i);
787 gpt_ent_backup(gpt_t gpt, unsigned int i)
789 return gpt_ent(gpt->tpg, gpt->lbt, i);
803 if (strcmp(pname, "gpt") == 0) {
825 gpt_last(gpt_t gpt)
827 return gpt->mediasz / gpt->secsz - 1LL;
831 gpt_create(gpt_t gpt, off_t last, u_int parts, int primary_only)
840 if (map_find(gpt, MAP_TYPE_PRI_GPT_HDR) != NULL ||
841 map_find(gpt, MAP_TYPE_SEC_GPT_HDR) != NULL) {
842 gpt_warnx(gpt, "Device already contains a GPT, "
848 blocks = map_free(gpt, 1LL, 0LL);
850 gpt_warnx(gpt, "No room for the GPT header");
855 if ((uint64_t)(blocks - 1) * gpt->secsz >
857 blocks = (off_t)((parts * sizeof(struct gpt_ent)) / gpt->secsz);
858 if ((parts * sizeof(struct gpt_ent)) % gpt->secsz)
871 map = map_last(gpt);
873 gpt_warnx(gpt, "No room for the backup header");
880 gpt_warnx(gpt, "No room for the GPT table");
886 if (gpt_add_hdr(gpt, MAP_TYPE_PRI_GPT_HDR, 1) == -1)
889 if ((p = calloc((size_t)blocks, gpt->secsz)) == NULL) {
890 gpt_warnx(gpt, "Can't allocate the primary GPT table");
893 if ((gpt->tbl = map_add(gpt, 2LL, blocks,
896 gpt_warnx(gpt, "Can't add the primary GPT table");
900 hdr = gpt->gpt->map_data;
909 hdr->hdr_lba_self = htole64((uint64_t)gpt->gpt->map_start);
911 hdr->hdr_lba_start = htole64((uint64_t)(gpt->tbl->map_start + blocks));
913 if (gpt_uuid_generate(gpt, hdr->hdr_guid) == -1)
915 hdr->hdr_lba_table = htole64((uint64_t)(gpt->tbl->map_start));
916 hdr->hdr_entries = htole32((uint32_t)(((uint64_t)blocks * gpt->secsz) /
922 ent = gpt->tbl->map_data;
924 if (gpt_uuid_generate(gpt, ent[i].ent_guid) == -1)
934 if (gpt_add_hdr(gpt, MAP_TYPE_SEC_GPT_HDR, last) == -1)
937 if ((gpt->lbt = map_add(gpt, last - blocks, blocks,
938 MAP_TYPE_SEC_GPT_TBL, gpt->tbl->map_data, 0)) == NULL) {
939 gpt_warnx(gpt, "Can't add the secondary GPT table");
943 memcpy(gpt->tpg->map_data, gpt->gpt->map_data, gpt->secsz);
945 hdr = gpt->tpg->map_data;
946 hdr->hdr_lba_self = htole64((uint64_t)gpt->tpg->map_start);
947 hdr->hdr_lba_alt = htole64((uint64_t)gpt->gpt->map_start);
948 hdr->hdr_lba_table = htole64((uint64_t)gpt->lbt->map_start);
953 gpt_size_get(gpt_t gpt, off_t *size)
965 *size = sectors * gpt->secsz;
979 gpt_human_get(gpt_t gpt, off_t *human)
984 gpt_warn(gpt, "Already set to %jd new `%s'", (intmax_t)*human,
989 gpt_warn(gpt, "Bad number `%s'", optarg);
994 gpt_warn(gpt, "Number `%s' < 1", optarg);
1001 gpt_add_find(gpt_t gpt, struct gpt_find *find, int ch)
1006 gpt_warn(gpt, "-a is already set");
1012 if (gpt_human_get(gpt, &find->block) == -1)
1016 if (gpt_uint_get(gpt, &find->entry) == -1)
1020 if (gpt_name_get(gpt, &find->label) == -1)
1024 if (gpt_size_get(gpt, &find->size) == -1)
1034 gpt_warn(gpt, "Unknown find option `%c'", ch);
1041 gpt_change_ent(gpt_t gpt, const struct gpt_find *find,
1055 if ((hdr = gpt_hdr(gpt)) == NULL)
1059 for (m = map_first(gpt); m != NULL; m = m->map_next) {
1071 ent = gpt_ent_primary(gpt, i);
1087 if (gpt_write_primary(gpt) == -1)
1090 ent = gpt_ent_backup(gpt, i);
1094 if (gpt_write_backup(gpt) == -1)
1097 gpt_msg(gpt, "Partition %d %s", m->map_index, find->msg);
1103 gpt_change_hdr(gpt_t gpt, const struct gpt_find *find,
1108 if ((hdr = gpt_hdr(gpt)) == NULL)
1114 if (gpt_write_primary(gpt) == -1)
1117 hdr = gpt->tpg->map_data;
1121 if (gpt_write_backup(gpt) == -1)
1124 gpt_msg(gpt, "Header %s", find->msg);
1130 gpt_add_ais(gpt_t gpt, off_t *alignment, u_int *entry, off_t *size, int ch)
1134 if (gpt_human_get(gpt, alignment) == -1)
1138 if (gpt_uint_get(gpt, entry) == -1)
1142 if (gpt_size_get(gpt, size) == -1)
1146 gpt_warn(gpt, "Unknown alignment/index/size option `%c'", ch);
1152 gpt_check_ais(gpt_t gpt, off_t alignment, u_int entry, off_t size)
1155 gpt_warnx(gpt, "Entry not specified");
1158 if (alignment % gpt->secsz != 0) {
1159 gpt_warnx(gpt, "Alignment (%#jx) must be a multiple of "
1160 "sector size (%#x)", (uintmax_t)alignment, gpt->secsz);
1164 if (size % gpt->secsz != 0) {
1165 gpt_warnx(gpt, "Size (%#jx) must be a multiple of "
1166 "sector size (%#x)", (uintmax_t)size, gpt->secsz);
1170 return size / gpt->secsz;
1212 gpt_attr_get(gpt_t gpt, uint64_t *attributes)
1225 gpt_warnx(gpt, "Unrecognized attribute `%s'", ptr);
1307 gpt_attr_update(gpt_t gpt, u_int entry, uint64_t set, uint64_t clr)
1314 gpt_warnx(gpt, "Nothing to set");
1318 if ((hdr = gpt_hdr(gpt)) == NULL)
1322 gpt_warnx(gpt, "Index %u out of range (%u max)",
1328 ent = gpt_ent_primary(gpt, i);
1330 gpt_warnx(gpt, "Entry at index %u is unused", entry);
1337 if (gpt_write_primary(gpt) == -1)
1340 ent = gpt_ent_backup(gpt, i);
1344 if (gpt_write_backup(gpt) == -1)
1346 gpt_msg(gpt, "Partition %d attributes updated", entry);
1351 gpt_uint_get(gpt_t gpt, u_int *entry)
1358 gpt_warn(gpt, "Bad number `%s'", optarg);
1364 gpt_uuid_get(gpt_t gpt, gpt_uuid_t *uuid)
1369 gpt_warnx(gpt, "Can't parse uuid/type `%s'", optarg);
1376 gpt_name_get(gpt_t gpt, void *v)
1383 gpt_warn(gpt, "Can't copy string");
1407 gpt_add_hdr(gpt_t gpt, int type, off_t loc)
1415 t = &gpt->gpt;
1419 t = &gpt->tpg;
1423 gpt_warnx(gpt, "Unknown GPT header type %d", type);
1427 if ((p = calloc(1, gpt->secsz)) == NULL) {
1428 gpt_warn(gpt, "Error allocating %s GPT header", msg);
1432 *t = map_add(gpt, loc, 1LL, type, p, 1);
1434 gpt_warn(gpt, "Error adding %s GPT header", msg);