52 lines
1.6 KiB
Bash
52 lines
1.6 KiB
Bash
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('<I',e,0)[0]
|
|
ib = struct.unpack_from('<I',e,4)[0]
|
|
it = struct.unpack_from('<I',e,8)[0]
|
|
cs = struct.unpack_from('<H',e,30)[0]
|
|
print(f' Backup group {i}: bb={bb} ib={ib} it={it} csum=0x{cs:04x}')
|
|
|
|
# Save it
|
|
with open('/tmp/backup_gdt.bin','wb') as f:
|
|
f.write(backup_gdt)
|
|
print(f'Saved {len(backup_gdt)} bytes to /tmp/backup_gdt.bin')
|
|
"
|