test/others: Cover all-raw compression entries

Compression can fall back to raw storage for every block in an entry.
The writer then omits compression metadata so restore can use ordinary
I/O, but that fast path also depends on a page-aligned payload.

Add per-page and region tests with an incompressible mapping. Inspect
the pagemap for an aligned 56-page entry without compression metadata,
while requiring another genuine LZ4 block to prove compression was
active. Restore through direct image I/O, require native AIO when
O_DIRECT is available, and verify the workload contents.

Run the test in CI when page compression is available.

Assisted-by: Codex:GPT-5
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
This commit is contained in:
Radostin Stoyanov 2026-07-11 12:16:05 +01:00
parent f5fc0ddb56
commit deeb0f8a82
5 changed files with 189 additions and 0 deletions

View file

@ -367,6 +367,13 @@ run_non_shardable_tests() {
echo "Skipping compression/incremental test"
fi
# Raw compression fallback image format.
if criu/criu check --feature compress; then
make -C test/others/compression/raw run
else
echo "Skipping compression/raw test"
fi
./test/zdtm.py run -t zdtm/transition/pid_reuse --pre 2 # start time based pid reuse detection
./test/zdtm.py run -t zdtm/transition/pidfd_store_sk --rpc --pre 2 # pidfd based pid reuse detection

View file

@ -0,0 +1 @@
dump-raw-*/

View file

@ -0,0 +1,3 @@
run:
./run.sh
.PHONY: run

View file

@ -0,0 +1,86 @@
#!/usr/bin/env python3
import argparse
import os
import sys
import pycriu.images
PE_PRESENT = 4
PE_PAYLOAD_ALIGNED = 8
def check_raw_entry(directory, pid):
path = os.path.join(directory, "pagemap-%s.img" % pid)
with open(path, "rb") as image:
entries = pycriu.images.load(image)["entries"][1:]
page_size = os.sysconf("SC_PAGE_SIZE")
payload_offset = 0
found = False
found_lz4 = False
for entry in entries:
flags = int(entry.get("flags", 0))
if not flags & PE_PRESENT:
continue
if flags & PE_PAYLOAD_ALIGNED:
payload_offset = (payload_offset + page_size - 1) & -page_size
is_raw_target = (
int(entry.get("nr_pages", 0)) == 56
and "compressed_size" not in entry
and "total_compressed_size" not in entry
and "region_pages" not in entry
)
if is_raw_target:
if not flags & PE_PAYLOAD_ALIGNED:
print("FAIL: all-raw entry lacks PE_PAYLOAD_ALIGNED in %s" % path)
return 1
if payload_offset % page_size:
print(
"FAIL: all-raw entry starts at unaligned offset %d"
% payload_offset
)
return 1
found = True
compressed_sizes = entry.get("compressed_size")
if compressed_sizes:
block_pages = int(entry.get("region_pages", 0)) or 1
remaining = int(entry.get("nr_pages", 0))
for size in compressed_sizes:
pages = min(block_pages, remaining)
if 0 < int(size) < pages * page_size:
found_lz4 = True
remaining -= pages
payload_offset += sum(int(size) for size in compressed_sizes)
else:
payload_offset += int(entry.get("nr_pages", 0)) * page_size
if not found:
print(
"FAIL: no aligned 56-page all-raw entry without compression metadata "
"in %s" % path
)
return 1
if not found_lz4:
print("FAIL: compression test produced no LZ4-compressed block in %s" % path)
return 1
return 0
def main():
parser = argparse.ArgumentParser(
description="Validate raw-fallback pagemap metadata"
)
parser.add_argument("directory")
parser.add_argument("pid")
args = parser.parse_args()
return check_raw_entry(args.directory, args.pid)
if __name__ == "__main__":
sys.exit(main())

View file

@ -0,0 +1,92 @@
#!/bin/bash
# Verify that entries made entirely of compression raw fallbacks use the
# ordinary uncompressed pagemap representation and still restore correctly.
set -euo pipefail
# shellcheck source=test/others/env.sh
source ../../env.sh
CRIU_CMD=("${CRIU}" --no-default-config)
ZDTM_DIR="../../../zdtm/static"
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
RAW_ENTRY_CHECK="${SCRIPT_DIR}/check_raw_entry.py"
PID=""
function fail {
echo "FAIL: $*"
exit 1
}
function cleanup {
if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null; then
kill -TERM "$PID" 2>/dev/null || true
for _ in $(seq 1 50); do
kill -0 "$PID" 2>/dev/null || break
sleep 0.1
done
if kill -0 "$PID" 2>/dev/null; then
kill -KILL "$PID" 2>/dev/null || true
fi
fi
rm -rf dump-raw-*
}
trap cleanup EXIT
function start_test {
(
cd "$ZDTM_DIR" || exit 1
make compress_pages00.cleanout
make compress_pages00
make compress_pages00.pid || exit 1
)
PID=$(cat "$ZDTM_DIR/compress_pages00.pid")
kill -0 "$PID" || fail "Test didn't start"
}
function stop_test {
(
cd "$ZDTM_DIR" || exit 1
make compress_pages00.stop
grep PASS compress_pages00.out || exit 1
) || fail "$1: memory content verification failed"
PID=""
}
function assert_raw_entry {
local directory="$1"
PYTHONPATH="${BASE_DIR}/lib${PYTHONPATH:+:${PYTHONPATH}}" \
python3 "$RAW_ENTRY_CHECK" "$directory" "$PID"
}
function run_mode {
local name="$1"
shift
local imgdir="dump-raw-$name"
rm -rf "$imgdir"
mkdir "$imgdir"
start_test
"${CRIU_CMD[@]}" dump -D "$imgdir" -o dump.log -t "$PID" -v4 "$@" \
|| fail "$name: dump failed"
assert_raw_entry "$imgdir" || fail "$name: raw-entry metadata check failed"
"${CRIU_CMD[@]}" restore -D "$imgdir" -o restore.log -v4 -d \
--image-io-mode direct \
|| fail "$name: restore failed"
if grep -q "O_DIRECT enabled on pages fd" "$imgdir/restore.log"; then
grep -q "Restoring delayed VMA I/O with native AIO" \
"$imgdir/restore.log" || \
fail "$name: aligned raw ranges did not use direct AIO"
fi
stop_test "$name"
}
run_mode page --compress
run_mode region --compress-region=64K
echo "Test PASSED"