@@ -101,8 +101,211 @@ function run_test2 {
101101 ${CRIT} x ./ rss || exit 1
102102}
103103
104+ ZDTM_DIR=" ${BASE_DIR} /test/zdtm/static"
105+
106+ function dump_test_process {
107+ # Dump compress_pages02 (covers 8 mapping types: anonymous,
108+ # zero-filled, shared anonymous, file-backed private/shared,
109+ # memfd, read-only, PROT_NONE guard) into the given directory.
110+ # Prints the PID on success.
111+ local dir=$1 ; shift
112+ local pid
113+
114+ make -C " $ZDTM_DIR " compress_pages02 > /dev/null 2>&1
115+
116+ # Clean stale marker files and run from the test directory
117+ # so zdtm pidfile rename works (same filesystem).
118+ rm -f " $dir " /test.out* " $dir " /test.pid " $dir " /test.file
119+
120+ (cd " $dir " && " $ZDTM_DIR /compress_pages02" \
121+ --pidfile=test.pid \
122+ --outfile=test.out \
123+ --filename=test.file)
124+
125+ # Wait for pidfile
126+ local i=0
127+ while [ $i -lt 50 ]; do
128+ if [ -f " $dir /test.pid" ]; then
129+ break
130+ fi
131+ sleep 0.1
132+ i=$(( i + 1 ))
133+ done
134+
135+ pid=$( cat " $dir /test.pid" 2> /dev/null)
136+ if [ -z " $pid " ] || ! kill -0 " $pid " 2> /dev/null; then
137+ echo " FAIL: test process didn't start"
138+ cat " $dir /test.out" 2> /dev/null
139+ exit 1
140+ fi
141+
142+ if ! $CRIU dump -v4 -o dump.log -D " $dir " -t " $pid " --shell-job " $@ " ; then
143+ echo " FAIL: dump into $dir "
144+ cat " $dir /dump.log"
145+ kill -9 " $pid " 2> /dev/null
146+ exit 1
147+ fi
148+ echo " $pid "
149+ }
150+
151+ function restore_and_verify {
152+ # Restore from directory, send SIGTERM so compress_pages02
153+ # verifies its own memory, then check the test output for PASS.
154+ local dir=$1
155+ local pid
156+
157+ if ! $CRIU restore -v4 -o restore.log -D " $dir " --shell-job -d; then
158+ echo " FAIL: restore from $dir "
159+ cat " $dir /restore.log"
160+ exit 1
161+ fi
162+
163+ # Get the root PID from the pstree image
164+ pid=$( $CRIT decode -i " $dir /pstree.img" 2> /dev/null |
165+ grep -o ' "pid": [0-9]*' | head -1 | grep -o ' [0-9]*' )
166+
167+ if [ -z " $pid " ] || ! kill -0 " $pid " 2> /dev/null; then
168+ echo " FAIL: restored process not running from $dir (pid=$pid )"
169+ exit 1
170+ fi
171+
172+ # Send SIGTERM so compress_pages02 verifies all memory
173+ # regions (zero, pattern, shared, file, memfd, readonly,
174+ # guard) then writes PASS/FAIL to its output file.
175+ kill -TERM " $pid " 2> /dev/null
176+ wait " $pid " 2> /dev/null
177+ sleep 0.5
178+
179+ if ! grep -q PASS " $dir /test.out" 2> /dev/null; then
180+ echo " FAIL: memory verification failed after restore from $dir "
181+ cat " $dir /test.out" 2> /dev/null
182+ exit 1
183+ fi
184+ }
185+
186+ function pages_checksum {
187+ # Print md5sum of all pages-*.img files in a directory.
188+ # This captures the raw page content for comparison.
189+ cat " $1 " /pages-* .img | md5sum | awk ' {print $1}'
190+ }
191+
192+ function run_test_compress {
193+ echo " === compress/decompress tests ==="
194+
195+ # -------------------------------------------------------
196+ # Test 1: dump -c -> decompress -> restore
197+ # -------------------------------------------------------
198+ echo " -- Test 1: compressed dump -> decompress -> restore"
199+ dump_test_process comp/ -c > /dev/null
200+
201+ $CRIT decompress comp/ || exit 1
202+
203+ # Verify backup files exist
204+ ls comp/pages-* .img.bak > /dev/null 2>&1 || { echo " FAIL: no pages backup" ; exit 1; }
205+ ls comp/pagemap-* .img.bak > /dev/null 2>&1 || { echo " FAIL: no pagemap backup" ; exit 1; }
206+ ls comp/inventory.img.bak > /dev/null 2>&1 || { echo " FAIL: no inventory backup" ; exit 1; }
207+
208+ restore_and_verify comp/
209+ echo " PASS"
210+
211+ # -------------------------------------------------------
212+ # Test 2: dump uncompressed -> compress -> restore
213+ # -------------------------------------------------------
214+ echo " -- Test 2: uncompressed dump -> compress -> restore"
215+ dump_test_process uncomp/ > /dev/null
216+
217+ $CRIT compress uncomp/ --in-place || exit 1
218+
219+ # Verify no backup files with --in-place
220+ if ls uncomp/* .bak > /dev/null 2>&1 ; then
221+ echo " FAIL: backup files created with --in-place"
222+ exit 1
223+ fi
224+
225+ restore_and_verify uncomp/
226+ echo " PASS"
227+
228+ # -------------------------------------------------------
229+ # Test 3: compress already compressed, decompress already decompressed
230+ # -------------------------------------------------------
231+ echo " -- Test 3: compress already compressed, decompress already decompressed"
232+ $CRIT compress uncomp/ --in-place 2>&1 | grep -q " already compressed" || {
233+ echo " FAIL: compress should report already compressed"
234+ exit 1
235+ }
236+ $CRIT decompress comp/ 2>&1 | grep -q " already decompressed" || {
237+ echo " FAIL: decompress should report already decompressed"
238+ exit 1
239+ }
240+ echo " PASS"
241+
242+ # -------------------------------------------------------
243+ # Test 4: compress -> decompress -> compress produces same pages
244+ # -------------------------------------------------------
245+ echo " -- Test 4: compress -> decompress -> compress stability"
246+ rm -rf cdc/
247+ mkdir -p cdc/
248+ dump_test_process cdc/ > /dev/null
249+
250+ $CRIT compress cdc/ --in-place || exit 1
251+ local sum1
252+ sum1=$( pages_checksum cdc/)
253+
254+ $CRIT decompress cdc/ --in-place || exit 1
255+ $CRIT compress cdc/ --in-place || exit 1
256+ local sum2
257+ sum2=$( pages_checksum cdc/)
258+
259+ if [ " $sum1 " != " $sum2 " ]; then
260+ echo " FAIL: compress->decompress->compress changed pages data"
261+ echo " first: $sum1 "
262+ echo " second: $sum2 "
263+ exit 1
264+ fi
265+
266+ restore_and_verify cdc/
267+ echo " PASS"
268+
269+ # -------------------------------------------------------
270+ # Test 5: decompress -> compress -> decompress produces same pages
271+ # -------------------------------------------------------
272+ echo " -- Test 5: decompress -> compress -> decompress stability"
273+ rm -rf dcd/
274+ mkdir -p dcd/
275+ dump_test_process dcd/ -c > /dev/null
276+
277+ $CRIT decompress dcd/ --in-place || exit 1
278+ local sum3
279+ sum3=$( pages_checksum dcd/)
280+
281+ $CRIT compress dcd/ --in-place || exit 1
282+ $CRIT decompress dcd/ --in-place || exit 1
283+ local sum4
284+ sum4=$( pages_checksum dcd/)
285+
286+ if [ " $sum3 " != " $sum4 " ]; then
287+ echo " FAIL: decompress->compress->decompress changed pages data"
288+ echo " first: $sum3 "
289+ echo " second: $sum4 "
290+ exit 1
291+ fi
292+
293+ restore_and_verify dcd/
294+ echo " PASS"
295+
296+ echo " === compress/decompress: ALL PASS ==="
297+ }
298+
104299${CRIT} --version
105300
106301gen_imgs
107302run_test1
108303run_test2
304+
305+ # Skip compress/decompress tests if lz4 or CRIU compression is unavailable
306+ if python3 -c " import lz4.block" 2> /dev/null && $CRIU check --feature compress 2> /dev/null; then
307+ mkdir -p comp/ uncomp/
308+ run_test_compress
309+ else
310+ echo " === Skipping compress/decompress tests (lz4 or CRIU compression not available) ==="
311+ fi
0 commit comments