74 lines
2.3 KiB
Bash
74 lines
2.3 KiB
Bash
python3 -c "
|
|
import struct
|
|
|
|
# Read superblock
|
|
with open('/dev/md0','rb') as f:
|
|
f.seek(2621441024) # physical primary sb
|
|
sb = f.read(1024)
|
|
|
|
total_blocks = struct.unpack_from('<I', sb, 4)[0]
|
|
bpg = struct.unpack_from('<I', sb, 40)[0]
|
|
bsize = 4096
|
|
num_groups = (total_blocks + bpg - 1) // bpg
|
|
gdt_blocks = (num_groups * 64 + bsize - 1) // bsize # 64 bytes per GDT entry
|
|
|
|
print(f'Total blocks: {total_blocks}')
|
|
print(f'Blocks/group: {bpg}')
|
|
print(f'Num groups: {num_groups}')
|
|
print(f'GDT size: {num_groups * 64} bytes = {gdt_blocks} blocks')
|
|
print(f'GDT spans blocks 1 to {gdt_blocks}')
|
|
print()
|
|
|
|
# Check which physical chunks cover the GDT
|
|
CHUNK_BYTES = 128 * 512 # 64KB
|
|
LV_PHYS_START = 5120000 * 512
|
|
|
|
def v_to_p_byte(virt_byte):
|
|
group = virt_byte // (5 * CHUNK_BYTES)
|
|
offset_in_group = virt_byte % (5 * CHUNK_BYTES)
|
|
chunk_in_group = offset_in_group // CHUNK_BYTES
|
|
intra = offset_in_group % CHUNK_BYTES
|
|
if chunk_in_group == 4:
|
|
return None # metadata chunk
|
|
phys = (LV_PHYS_START +
|
|
group * 4 * CHUNK_BYTES +
|
|
chunk_in_group * CHUNK_BYTES +
|
|
intra)
|
|
return phys
|
|
|
|
# GDT spans virtual bytes 4096 to 4096+gdt_blocks*4096
|
|
gdt_start_v = 4096 # block 1
|
|
gdt_end_v = 4096 + gdt_blocks * 4096
|
|
|
|
print(f'GDT virtual bytes: {gdt_start_v} to {gdt_end_v}')
|
|
print()
|
|
|
|
# Check each chunk that covers the GDT
|
|
print('Chunks covering GDT:')
|
|
pos = gdt_start_v
|
|
while pos < gdt_end_v:
|
|
chunk_in_group = (pos % (5 * CHUNK_BYTES)) // CHUNK_BYTES
|
|
phys = v_to_p_byte(pos)
|
|
chunk_end = pos + CHUNK_BYTES - (pos % CHUNK_BYTES)
|
|
print(f' Virtual {pos}-{min(chunk_end,gdt_end_v)}: '
|
|
f'chunk_type={chunk_in_group} '
|
|
f'physical={phys} '
|
|
f'{\"METADATA-LOST\" if phys is None else \"\"}')
|
|
pos = chunk_end
|
|
|
|
# Read GDT from nbd and check first few entries
|
|
print()
|
|
print('GDT entries via NBD:')
|
|
with open('/dev/nbd0','rb') as f:
|
|
f.seek(4096)
|
|
gdt_data = f.read(min(gdt_blocks * 4096, 65536))
|
|
|
|
for i in range(min(10, num_groups)):
|
|
entry = gdt_data[i*64:(i+1)*64]
|
|
bb = struct.unpack_from('<I', entry, 0)[0]
|
|
ib = struct.unpack_from('<I', entry, 4)[0]
|
|
it = struct.unpack_from('<I', entry, 8)[0]
|
|
cs = struct.unpack_from('<H', entry, 30)[0]
|
|
print(f' Group {i}: bb={bb} ib={ib} it={it} csum=0x{cs:04x}')
|
|
"
|