Lines Matching +full:ps +full:- +full:seq +full:- +full:id

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
83 * We do not keep all fields of on-disk structures, only most useful.
84 * All numbers in an on-disk structures are in big-endian format.
90 * - the first offset is relative to the disk start;
91 * - the second and third offset are relative to the LDM database start.
172 * Volumes <- Components <- Partitions -> Disks
182 uint64_t id; /* object id */ member
183 uint64_t vol_id; /* parent volume object id */
191 uint64_t id; /* object id */ member
202 uint64_t id; /* object id */ member
210 uint64_t id; /* object id */
219 uint64_t id; /* object id */ member
220 uint64_t disk_id; /* disk object id */
221 uint64_t comp_id; /* parent component object id */
234 * Strings with fixed size are NULL-terminated, others are not.
237 * ---------------+---------------+--------------------------
241 * 0x18 PS object id
244 * o Offset 0x18+ means '0x18 + length of all variable-width fields'
245 * o 'P' in size column means 'prefixed' (variable-width),
246 * 'S' - string, 'N' - number.
256 uint32_t seq; /* sequence number */ member
272 uint64_t id; member
387 pp = cp->provider; in ldm_privhdr_read()
388 buf = g_read_data(cp, off, pp->sectorsize, error); in ldm_privhdr_read()
394 pp->name); in ldm_privhdr_read()
414 cp->provider->name, version >> 16, in ldm_privhdr_parse()
418 error = parse_uuid(buf + LDM_PH_DISKGUID_OFF, &hdr->disk_guid); in ldm_privhdr_parse()
421 error = parse_uuid(buf + LDM_PH_DGGUID_OFF, &hdr->dg_guid); in ldm_privhdr_parse()
424 strncpy(hdr->dg_name, buf + LDM_PH_DGNAME_OFF, sizeof(hdr->dg_name)); in ldm_privhdr_parse()
425 hdr->start = be64dec(buf + LDM_PH_START_OFF); in ldm_privhdr_parse()
426 hdr->size = be64dec(buf + LDM_PH_SIZE_OFF); in ldm_privhdr_parse()
427 hdr->db_offset = be64dec(buf + LDM_PH_DB_OFF); in ldm_privhdr_parse()
428 hdr->db_size = be64dec(buf + LDM_PH_DBSIZE_OFF); in ldm_privhdr_parse()
429 hdr->th_offset[0] = be64dec(buf + LDM_PH_TH1_OFF); in ldm_privhdr_parse()
430 hdr->th_offset[1] = be64dec(buf + LDM_PH_TH2_OFF); in ldm_privhdr_parse()
431 hdr->conf_size = be64dec(buf + LDM_PH_CONFSIZE_OFF); in ldm_privhdr_parse()
432 hdr->log_size = be64dec(buf + LDM_PH_LOGSIZE_OFF); in ldm_privhdr_parse()
446 pp = cp->provider; in ldm_privhdr_check()
453 cp2 = LIST_FIRST(&pp->geom->consumer); in ldm_privhdr_check()
455 cp2->provider->mediasize / cp2->provider->sectorsize - 1; in ldm_privhdr_check()
457 last = pp->mediasize / pp->sectorsize - 1; in ldm_privhdr_check()
465 offset += db->ph.db_offset; in ldm_privhdr_check()
472 db->ph.db_offset = last - LDM_DB_SIZE; in ldm_privhdr_check()
474 buf = ldm_privhdr_read(cp, offset * pp->sectorsize, &error); in ldm_privhdr_check()
477 "%d at LBA %ju", pp->name, i, (uintmax_t)offset); in ldm_privhdr_check()
483 "header %d", pp->name, i); in ldm_privhdr_check()
484 LDM_DUMP(buf, pp->sectorsize); in ldm_privhdr_check()
490 hdr.start + hdr.size - 1 > last || in ldm_privhdr_check()
491 (hdr.start + hdr.size - 1 > hdr.db_offset && !is_gpt) || in ldm_privhdr_check()
493 hdr.db_offset + LDM_DB_SIZE - 1 > last || in ldm_privhdr_check()
498 "private header %d", pp->name, i); in ldm_privhdr_check()
502 "last: %jd", pp->name, hdr.start, hdr.size, in ldm_privhdr_check()
508 if (found != 0 && memcmp(&db->ph, &hdr, sizeof(hdr)) != 0) { in ldm_privhdr_check()
510 pp->name); in ldm_privhdr_check()
517 pp->name); in ldm_privhdr_check()
528 memcpy(&db->ph, &hdr, sizeof(hdr)); in ldm_privhdr_check()
533 pp->name); in ldm_privhdr_check()
549 gpt = cp->provider->geom->softc; in ldm_gpt_check()
551 LIST_FOREACH(e, &gpt->gpt_entry, gpe_entry) { in ldm_gpt_check()
552 if (cp->provider == e->gpe_pp) { in ldm_gpt_check()
553 /* ms-ldm-metadata partition */ in ldm_gpt_check()
554 if (e->gpe_start != db->ph.db_offset || in ldm_gpt_check()
555 e->gpe_end != db->ph.db_offset + LDM_DB_SIZE - 1) in ldm_gpt_check()
557 } else if (cp2->provider == e->gpe_pp) { in ldm_gpt_check()
558 /* ms-ldm-data partition */ in ldm_gpt_check()
559 if (e->gpe_start != db->ph.start || in ldm_gpt_check()
560 e->gpe_end != db->ph.start + db->ph.size - 1) in ldm_gpt_check()
566 e->gpe_pp->name, e->gpe_index); in ldm_gpt_check()
584 pp = cp->provider; in ldm_tochdr_check()
586 offset = db->ph.db_offset + db->ph.th_offset[i]; in ldm_tochdr_check()
588 offset * pp->sectorsize, pp->sectorsize, &error); in ldm_tochdr_check()
591 "at LBA %ju", pp->name, (uintmax_t)offset); in ldm_tochdr_check()
600 "at LBA %ju", pp->name, (uintmax_t)offset); in ldm_tochdr_check()
601 LDM_DUMP(buf, pp->sectorsize); in ldm_tochdr_check()
609 if (conf_size != db->ph.conf_size || in ldm_tochdr_check()
611 log_size != db->ph.log_size || in ldm_tochdr_check()
614 "TOC header at LBA %ju", pp->name, in ldm_tochdr_check()
616 LDM_DUMP(buf, pp->sectorsize); in ldm_tochdr_check()
622 memcpy(&db->th, &hdr, sizeof(hdr)); in ldm_tochdr_check()
627 pp->name); in ldm_tochdr_check()
643 pp = cp->provider; in ldm_vmdbhdr_check()
644 offset = db->ph.db_offset + db->th.conf_offset; in ldm_vmdbhdr_check()
645 buf = g_read_data(cp, offset * pp->sectorsize, pp->sectorsize, in ldm_vmdbhdr_check()
649 "LBA %ju", pp->name, (uintmax_t)offset); in ldm_vmdbhdr_check()
655 "LBA %ju", pp->name, (uintmax_t)offset); in ldm_vmdbhdr_check()
663 pp->name, version >> 16, version & 0xFFFF); in ldm_vmdbhdr_check()
668 * 1 - in a consistent state; in ldm_vmdbhdr_check()
669 * 2 - in a creation phase; in ldm_vmdbhdr_check()
670 * 3 - in a deletion phase; in ldm_vmdbhdr_check()
675 pp->name); in ldm_vmdbhdr_check()
678 db->dh.last_seq = be32dec(buf + LDM_DB_LASTSEQ_OFF); in ldm_vmdbhdr_check()
679 db->dh.size = be32dec(buf + LDM_DB_SIZE_OFF); in ldm_vmdbhdr_check()
682 if (error != 0 || db->dh.size == 0 || in ldm_vmdbhdr_check()
683 pp->sectorsize % db->dh.size != 0 || in ldm_vmdbhdr_check()
684 strncmp(buf + LDM_DB_DGNAME_OFF, db->ph.dg_name, 31) != 0 || in ldm_vmdbhdr_check()
685 memcmp(&dg_guid, &db->ph.dg_guid, sizeof(dg_guid)) != 0 || in ldm_vmdbhdr_check()
686 db->dh.size * db->dh.last_seq > in ldm_vmdbhdr_check()
687 db->ph.conf_size * pp->sectorsize) { in ldm_vmdbhdr_check()
689 pp->name); in ldm_vmdbhdr_check()
690 LDM_DUMP(buf, pp->sectorsize); in ldm_vmdbhdr_check()
704 size = db->dh.size - 16; in ldm_xvblk_handle()
705 LIST_FOREACH(blk, &db->xvblks, entry) in ldm_xvblk_handle()
706 if (blk->group == vh->group) in ldm_xvblk_handle()
710 blk->group = vh->group; in ldm_xvblk_handle()
711 blk->size = size * vh->count + 16; in ldm_xvblk_handle()
712 blk->data = g_malloc(blk->size, M_WAITOK | M_ZERO); in ldm_xvblk_handle()
713 blk->map = 0xFF << vh->count; in ldm_xvblk_handle()
714 LIST_INSERT_HEAD(&db->xvblks, blk, entry); in ldm_xvblk_handle()
716 if ((blk->map & (1 << vh->index)) != 0) { in ldm_xvblk_handle()
721 memcpy(blk->data + size * vh->index + 16, p + 16, size); in ldm_xvblk_handle()
722 blk->map |= 1 << vh->index; in ldm_xvblk_handle()
726 /* Read the variable-width numeric field and return new offset */
735 return (-1); in ldm_vnum_get()
736 for (num = 0; len > 0; len--) in ldm_vnum_get()
742 /* Read the variable-width string and return new offset */
751 return (-1); in ldm_vstr_get()
757 /* Just skip the variable-width variable and return new offset */
765 return (-1); in ldm_vparm_skip()
780 blk->type = p[LDM_VBLK_TYPE_OFF]; in ldm_vblk_handle()
781 offset = ldm_vnum_get(p, LDM_VBLK_OID_OFF, &blk->u.id, size); in ldm_vblk_handle()
783 errstr = "object id"; in ldm_vblk_handle()
791 switch (blk->type) { in ldm_vblk_handle()
795 * ------------+-------+------------------------ in ldm_vblk_handle()
796 * 0x18+ PS volume state in ldm_vblk_handle()
798 * 0x1D+16 PN parent's volume object id in ldm_vblk_handle()
813 &blk->u.comp.vol_id, size); in ldm_vblk_handle()
815 errstr = "volume id"; in ldm_vblk_handle()
822 * ------------+-------+------------------------ in ldm_vblk_handle()
826 * 0x34+ PN parent's component object id in ldm_vblk_handle()
827 * 0x34+ PN disk's object id in ldm_vblk_handle()
834 blk->u.part.start = be64dec(p + offset + 12); in ldm_vblk_handle()
835 blk->u.part.offset = be64dec(p + offset + 20); in ldm_vblk_handle()
836 offset = ldm_vnum_get(p, offset + 28, &blk->u.part.size, size); in ldm_vblk_handle()
841 offset = ldm_vnum_get(p, offset, &blk->u.part.comp_id, size); in ldm_vblk_handle()
843 errstr = "component id"; in ldm_vblk_handle()
846 offset = ldm_vnum_get(p, offset, &blk->u.part.disk_id, size); in ldm_vblk_handle()
848 errstr = "disk id"; in ldm_vblk_handle()
855 * ------------+-------+------------------------ in ldm_vblk_handle()
856 * 0x18+ PS disk GUID in ldm_vblk_handle()
863 error = parse_uuid(vstr, &blk->u.disk.guid); in ldm_vblk_handle()
866 LIST_INSERT_HEAD(&db->disks, &blk->u.disk, entry); in ldm_vblk_handle()
871 * ------------+-------+------------------------ in ldm_vblk_handle()
872 * 0x18+ PS disk group GUID in ldm_vblk_handle()
876 strncpy(blk->u.disk_group.name, vstr, in ldm_vblk_handle()
877 sizeof(blk->u.disk_group.name)); in ldm_vblk_handle()
883 error = parse_uuid(name, &blk->u.disk_group.guid); in ldm_vblk_handle()
888 LIST_INSERT_HEAD(&db->groups, &blk->u.disk_group, entry); in ldm_vblk_handle()
894 * ------------+-------+------------------------ in ldm_vblk_handle()
898 be_uuid_dec(p + offset, &blk->u.disk.guid); in ldm_vblk_handle()
899 LIST_INSERT_HEAD(&db->disks, &blk->u.disk, entry); in ldm_vblk_handle()
904 * ------------+-------+------------------------ in ldm_vblk_handle()
909 strncpy(blk->u.disk_group.name, vstr, in ldm_vblk_handle()
910 sizeof(blk->u.disk_group.name)); in ldm_vblk_handle()
911 be_uuid_dec(p + offset, &blk->u.disk.guid); in ldm_vblk_handle()
912 LIST_INSERT_HEAD(&db->groups, &blk->u.disk_group, entry); in ldm_vblk_handle()
918 * ------------+-------+------------------------ in ldm_vblk_handle()
919 * 0x18+ PS volume type in ldm_vblk_handle()
920 * 0x18+ PS unknown in ldm_vblk_handle()
942 blk->u.vol.number = p[offset + 16]; in ldm_vblk_handle()
948 offset = ldm_vnum_get(p, offset + 16, &blk->u.vol.size, size); in ldm_vblk_handle()
957 blk->u.vol.part_type = p[offset + 4]; in ldm_vblk_handle()
960 LIST_FOREACH(volume, &db->volumes, entry) { in ldm_vblk_handle()
961 if (volume->number > blk->u.vol.number) in ldm_vblk_handle()
966 LIST_INSERT_AFTER(last, &blk->u.vol, entry); in ldm_vblk_handle()
968 LIST_INSERT_HEAD(&db->volumes, &blk->u.vol, entry); in ldm_vblk_handle()
971 LDM_DEBUG(1, "unknown VBLK type 0x%02x\n", blk->type); in ldm_vblk_handle()
974 LIST_INSERT_HEAD(&db->vblks, blk, entry); in ldm_vblk_handle()
978 errstr, blk->type); in ldm_vblk_handle()
990 while (!LIST_EMPTY(&db->xvblks)) { in ldm_vmdb_free()
991 xvblk = LIST_FIRST(&db->xvblks); in ldm_vmdb_free()
993 g_free(xvblk->data); in ldm_vmdb_free()
996 while (!LIST_EMPTY(&db->vblks)) { in ldm_vmdb_free()
997 vblk = LIST_FIRST(&db->vblks); in ldm_vmdb_free()
1017 pp = cp->provider; in ldm_vmdb_parse()
1018 size = howmany(db->dh.last_seq * db->dh.size, pp->sectorsize); in ldm_vmdb_parse()
1019 size -= 1; /* one sector takes vmdb header */ in ldm_vmdb_parse()
1020 for (n = 0; n < size; n += maxphys / pp->sectorsize) { in ldm_vmdb_parse()
1021 offset = db->ph.db_offset + db->th.conf_offset + n + 1; in ldm_vmdb_parse()
1022 sectors = (size - n) > (maxphys / pp->sectorsize) ? in ldm_vmdb_parse()
1023 maxphys / pp->sectorsize : size - n; in ldm_vmdb_parse()
1025 buf = g_read_data(cp, offset * pp->sectorsize, in ldm_vmdb_parse()
1026 sectors * pp->sectorsize, &error); in ldm_vmdb_parse()
1029 pp->name); in ldm_vmdb_parse()
1032 for (p = buf; p < buf + sectors * pp->sectorsize; in ldm_vmdb_parse()
1033 p += db->dh.size) { in ldm_vmdb_parse()
1037 pp->name); in ldm_vmdb_parse()
1038 LDM_DUMP(p, db->dh.size); in ldm_vmdb_parse()
1041 vh.seq = be32dec(p + LDM_VBLK_SEQ_OFF); in ldm_vmdb_parse()
1044 if (vh.seq == 0 || vh.group == 0) in ldm_vmdb_parse()
1049 vh.seq > db->dh.last_seq) { in ldm_vmdb_parse()
1051 "in the VBLK header\n", pp->name); in ldm_vmdb_parse()
1052 LDM_DUMP(p, db->dh.size); in ldm_vmdb_parse()
1059 "is corrupted\n", pp->name); in ldm_vmdb_parse()
1060 LDM_DUMP(p, db->dh.size); in ldm_vmdb_parse()
1067 " status is %u\n", pp->name, in ldm_vmdb_parse()
1069 error = ldm_vblk_handle(db, p, db->dh.size); in ldm_vmdb_parse()
1077 while (!LIST_EMPTY(&db->xvblks)) { in ldm_vmdb_parse()
1078 xvblk = LIST_FIRST(&db->xvblks); in ldm_vmdb_parse()
1079 if (xvblk->map == 0xFF) { in ldm_vmdb_parse()
1080 error = ldm_vblk_handle(db, xvblk->data, xvblk->size); in ldm_vmdb_parse()
1085 "xVBLK found\n", pp->name); in ldm_vmdb_parse()
1089 g_free(xvblk->data); in ldm_vmdb_parse()
1093 LIST_FOREACH(volume, &db->volumes, entry) { in ldm_vmdb_parse()
1094 LIST_FOREACH(vblk, &db->vblks, entry) in ldm_vmdb_parse()
1095 if (vblk->type == LDM_VBLK_T_COMPONENT && in ldm_vmdb_parse()
1096 vblk->u.comp.vol_id == volume->id) { in ldm_vmdb_parse()
1097 LIST_INSERT_HEAD(&volume->components, in ldm_vmdb_parse()
1098 &vblk->u.comp, entry); in ldm_vmdb_parse()
1099 volume->count++; in ldm_vmdb_parse()
1101 LIST_FOREACH(comp, &volume->components, entry) in ldm_vmdb_parse()
1102 LIST_FOREACH(vblk, &db->vblks, entry) in ldm_vmdb_parse()
1103 if (vblk->type == LDM_VBLK_T_PARTITION && in ldm_vmdb_parse()
1104 vblk->u.part.comp_id == comp->id) { in ldm_vmdb_parse()
1105 LIST_INSERT_HEAD(&comp->partitions, in ldm_vmdb_parse()
1106 &vblk->u.part, entry); in ldm_vmdb_parse()
1107 comp->count++; in ldm_vmdb_parse()
1148 * ms-ldm-metadata partition, but we can't do this via standard in g_part_ldm_destroy()
1151 if (table->is_gpt) in g_part_ldm_destroy()
1153 pp = LIST_FIRST(&basetable->gpt_gp->consumer)->provider; in g_part_ldm_destroy()
1158 basetable->gpt_smhead = (1 << ldm_ph_off[0]) | 1; in g_part_ldm_destroy()
1164 if (table->db_offset + LDM_DB_SIZE == in g_part_ldm_destroy()
1165 pp->mediasize / pp->sectorsize) in g_part_ldm_destroy()
1166 basetable->gpt_smtail = 1; in g_part_ldm_destroy()
1179 sbuf_printf(sb, " xs LDM xt %u", entry->type); in g_part_ldm_dumpconf()
1183 entry->type); in g_part_ldm_dumpconf()
1209 snprintf(buf, bufsz, "s%d", baseentry->gpe_index); in g_part_ldm_name()
1229 gpt = cp->provider->geom->softc; in ldm_gpt_probe()
1230 LIST_FOREACH(entry, &gpt->gpt_entry, gpe_entry) { in ldm_gpt_probe()
1232 /* Search ms-ldm-metadata partition */ in ldm_gpt_probe()
1233 if (memcmp(&part->ent_type, in ldm_gpt_probe()
1235 entry->gpe_end - entry->gpe_start < LDM_DB_SIZE - 1) in ldm_gpt_probe()
1239 cp2 = g_new_consumer(cp->geom); in ldm_gpt_probe()
1240 error = g_attach(cp2, entry->gpe_pp); in ldm_gpt_probe()
1256 cp->provider->name, cp2->provider->name); in ldm_gpt_probe()
1259 ldm_ph_off[LDM_PH_GPTINDEX] * cp2->provider->sectorsize, in ldm_gpt_probe()
1263 table->is_gpt = 1; in ldm_gpt_probe()
1270 g_access(cp2, -1, 0, 0); in ldm_gpt_probe()
1286 pp = cp->provider; in g_part_ldm_probe()
1287 if (pp->sectorsize != 512) in g_part_ldm_probe()
1293 strcmp(type, "ms-ldm-data") != 0) in g_part_ldm_probe()
1299 if (basetable->gpt_depth != 0) in g_part_ldm_probe()
1303 if (pp->mediasize <= 1024 * 1024) in g_part_ldm_probe()
1307 buf = g_read_data(cp, 0, pp->sectorsize, &error); in g_part_ldm_probe()
1324 pp->name); in g_part_ldm_probe()
1327 ldm_ph_off[LDM_PH_MBRINDEX] * pp->sectorsize, &error); in g_part_ldm_probe()
1351 cp2 = cp; /* ms-ldm-data */ in g_part_ldm_read()
1352 if (table->is_gpt) in g_part_ldm_read()
1353 cp = LIST_FIRST(&cp->geom->consumer); /* ms-ldm-metadata */ in g_part_ldm_read()
1355 error = ldm_privhdr_check(&db, cp, table->is_gpt); in g_part_ldm_read()
1358 basetable->gpt_first = table->is_gpt ? 0: db.ph.start; in g_part_ldm_read()
1359 basetable->gpt_last = basetable->gpt_first + db.ph.size - 1; in g_part_ldm_read()
1360 table->db_offset = db.ph.db_offset; in g_part_ldm_read()
1362 if (table->is_gpt) { in g_part_ldm_read()
1368 * consumer cp is attached to the ms-ldm-metadata partition in g_part_ldm_read()
1387 if (table->is_gpt) { in g_part_ldm_read()
1389 g_access(cp, -1, 0, 0); in g_part_ldm_read()
1399 if (memcmp(&disk->guid, &db.ph.disk_guid, in g_part_ldm_read()
1404 cp->provider->name); in g_part_ldm_read()
1410 LIST_FOREACH(comp, &vol->components, entry) { in g_part_ldm_read()
1412 part = LIST_FIRST(&comp->partitions); in g_part_ldm_read()
1413 if (part->disk_id != disk->id) in g_part_ldm_read()
1417 if (comp->count > 1 || part->offset != 0) { in g_part_ldm_read()
1420 cp->provider->name, (uintmax_t)comp->id, in g_part_ldm_read()
1421 comp->count); in g_part_ldm_read()
1428 if (vol->count > 1 && show_mirrors == 0) { in g_part_ldm_read()
1431 cp->provider->name, (uintmax_t)vol->id, in g_part_ldm_read()
1432 vol->count); in g_part_ldm_read()
1437 basetable->gpt_first + part->start, in g_part_ldm_read()
1438 basetable->gpt_first + part->start + in g_part_ldm_read()
1439 part->size - 1); in g_part_ldm_read()
1441 * Mark skipped partition as ms-ldm-data partition. in g_part_ldm_read()
1447 entry->type = vol->part_type; in g_part_ldm_read()
1449 entry->type = DOSPTYP_LDM; in g_part_ldm_read()
1450 LDM_DEBUG(1, "%s: new volume id: %ju, start: %ju," in g_part_ldm_read()
1451 " end: %ju, type: 0x%02x\n", cp->provider->name, in g_part_ldm_read()
1452 (uintmax_t)part->id,(uintmax_t)part->start + in g_part_ldm_read()
1453 basetable->gpt_first, (uintmax_t)part->start + in g_part_ldm_read()
1454 part->size + basetable->gpt_first - 1, in g_part_ldm_read()
1455 vol->part_type); in g_part_ldm_read()
1471 if (ldm_alias_match[i].typ == entry->type) in g_part_ldm_type()
1474 snprintf(buf, bufsz, "!%d", entry->type); in g_part_ldm_type()