55 lines
1.5 KiB
Python
55 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Patch superblock to disable metadata_csum feature flag,
|
|
and zero GDT checksum fields for groups 0-12.
|
|
All writes go to dm-0 (overlay), nbd0 untouched.
|
|
"""
|
|
import struct
|
|
|
|
DEV = '/dev/dm-0'
|
|
BLOCK = 4096
|
|
BACKUP_SB_BLOCK = 32768
|
|
|
|
# Feature flag constants
|
|
INCOMPAT_64BIT = 0x80
|
|
RO_COMPAT_METADATA_CSUM = 0x400
|
|
|
|
with open(DEV, 'r+b') as f:
|
|
# Read primary superblock (already patched to block 0)
|
|
f.seek(1024)
|
|
sb = bytearray(f.read(1024))
|
|
|
|
# Check current feature flags
|
|
ro_compat = struct.unpack_from('<I', sb, 100)[0]
|
|
print(f"ro_compat_features: {ro_compat:#010x}")
|
|
print(f"metadata_csum set: {bool(ro_compat & RO_COMPAT_METADATA_CSUM)}")
|
|
|
|
# Clear metadata_csum
|
|
ro_compat &= ~RO_COMPAT_METADATA_CSUM
|
|
struct.pack_into('<I', sb, 100, ro_compat)
|
|
|
|
# Zero superblock checksum
|
|
struct.pack_into('<I', sb, 1020, 0)
|
|
|
|
# Write patched superblock back
|
|
f.seek(1024)
|
|
f.write(sb)
|
|
print("Patched superblock: metadata_csum cleared")
|
|
|
|
# Now zero bg_checksum in GDT entries for groups 0-12
|
|
# bg_checksum is at offset 30 in each 64-byte descriptor
|
|
f.seek(BLOCK) # GDT starts at block 1
|
|
gdt = bytearray(f.read(13 * 64)) # groups 0-12 only
|
|
|
|
for grp in range(13):
|
|
off = grp * 64
|
|
old_csum = struct.unpack_from('<H', gdt, off + 30)[0]
|
|
struct.pack_into('<H', gdt, off + 30, 0)
|
|
print(f" group {grp:2d}: cleared checksum {old_csum:#06x}")
|
|
|
|
f.seek(BLOCK)
|
|
f.write(gdt)
|
|
print("Patched GDT checksums for groups 0-12")
|
|
|
|
print("Done - try debugfs again")
|