python3 -c " import struct CHUNK = 128*512 LV_START = 5120000*512 BSIZE = 4096 GDT_ENTRY = 64 BPG = 32768 NUM_GROUPS = 35728 def raw_read(virt_offset, length): result = bytearray(length) pos = virt_offset remaining = length with open('/dev/md0','rb') as f: while remaining > 0: group = pos // (5*CHUNK) in_group = pos % (5*CHUNK) chunk_idx = in_group // CHUNK intra = in_group % CHUNK seg_len = min(CHUNK-intra, remaining) dst_off = pos - virt_offset if chunk_idx != 4: phys = LV_START + group*4*CHUNK + chunk_idx*CHUNK + intra f.seek(phys) data = f.read(seg_len) result[dst_off:dst_off+len(data)] = data pos += seg_len remaining -= seg_len return bytes(result) # Read full backup GDT from group 1 (block 32769) backup_start_virt = (BPG + 1) * BSIZE gdt_size = NUM_GROUPS * GDT_ENTRY print(f'Reading backup GDT: {gdt_size//1024}KB from virtual byte {backup_start_virt}') backup_gdt = raw_read(backup_start_virt, gdt_size) # Verify it looks sane for i in [0,1,2,100,1000,10000]: e = backup_gdt[i*GDT_ENTRY:(i+1)*GDT_ENTRY] bb = struct.unpack_from('