Add Linux-compatible /proc/self/smaps emulation
Fixes #258
Summary
Running redis-server under elfuse currently fails during Redis's ARM64 copy-on-write safety check because Redis reads /proc/self/smaps, which elfuse does not provide with Linux-compatible contents. Redis treats the failed check as unsafe and exits to protect background saves.
This PR adds synthetic smaps support so Redis can inspect guest VMAs and complete startup under elfuse.
Implementation
- Generate
/proc/self/smapsand/proc/<pid>/smapsfrom the tracked guest VMA snapshot. - Emit Linux-shaped VMA headers and the standard smaps fields, including
VmFlags. - Preserve fork-aware COW information with a coarse
Shared_Dirtycompatibility signal for writable private anonymous mappings in fork children. - Share VMA collection and formatting logic with
/proc/self/maps. - Replace the fixed maps-entry/output limits with checked growable array and string-builder utilities.
- Add parser and regression coverage for smaps layout, field completeness, fork behavior, and larger VMA snapshots.
- Document the synthetic smaps semantics and intentional limitations; exact host page residency and
smaps_rollupremain out of scope.
Testing
make test-dynamic-array-host test-string-builder-host— passed.git diff --check— passed.- Guest
test-proc-smapcompilation was attempted, but the local environment does not haveaarch64-linux-gnu-gcc.
Compatibility notes
The synthetic values are derived from elfuse's tracked guest VMAs and fork state. Fields requiring host kernel page accounting are emitted as stable compatibility values and should not be interpreted as precise memory profiling data.
Summary by cubic
Adds Linux-compatible /proc/self/smaps and /proc/<pid>/smaps so redis-server passes its ARM64 COW safety check and starts under elfuse. Also standardizes FD-limit handling and adds descriptor-exhaustion regressions to make check.
-
New Features
- Emit Linux-shaped smaps (headers, standard fields,
VmFlags) for self and PIDs; reuse/proc/self/mapsVMA collection; append then sort+merge once; cap by guest limits. - Track per-VMA fork state and stable
vma_id; keepShared_Dirty/Pss_Dirtyconsistent and exclude post-fork mappings; propagate via fork IPC and memory ops. - Add
dynamic-arrayandstring-builderutilities with host tests; add a smaps parser and fork/mremap regressions. - Introduce
elfuse-limits.hfor shared FD limits (FD_TABLE_SIZE,HOST_FD_RESERVE,HOST_NOFILE_MIN); test runners derive limits viatests/test-config.sh;tests/manifest.txtsupportshost_nofile=elfuse-minimum.
- Emit Linux-shaped smaps (headers, standard fields,
-
Bug Fixes
- Harden fork-aware smaps and
mremap: preserve VMA lineage across fork/restore; make region splits/moves transactional; flush shared files before removes; avoid flushing writable aliases for read-onlyMAP_SHARED; coverPROT_NONE. - Harden
mmap/mremapfailure paths: reserve FDs before teardown; keepEMFILEfailures side-effect free; preserve smaps accounting and errno; preserve failedmmapreservation addresses; add descriptor- and table-exhaustion regressions; run the EMFILE regression inmake check. - Use unique
/dev/shmfixture names to avoid collisions in concurrent test runs.
- Harden fork-aware smaps and