Skip to content

Commit ec26065

Browse files
committed
lazy-migration: add test case
The lazy-pages test case is not as straight forward as the other test cases. This is related to the fact that restoring requires a different name if restored on the same host. During 'runc checkpoint' the container is not destroyed before all memory pages have been transferred to the destination and thus the same container name cannot be used. As real world usage will rather migrate a container from one system to another than lazy migrate a container on the same host this is only problematic for this test case. Another reason is that it requires starting 'runc checkpoint' and 'criu lazy-pages' in the background as those process need to be running to start the final restore 'runc restore'. CRIU upstream is currently discussing to automatically start 'criu lazy-pages' which would simplify the lazy-pages test case a bit. The handling and checking of the background processes make the test case not the most elegant as at one point a 'sleep 2' is required to make sure that 'runc checkpoint' had time to do its thing before looking at log files. Before running the actual test criu is called in feature checking mode to make sure lazy migration is in the test case criu enabled. If not, the test is skipped. Signed-off-by: Adrian Reber <[email protected]>
1 parent 60ae709 commit ec26065

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

tests/integration/checkpoint.bats

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,111 @@ function teardown() {
122122
[ "$status" -eq 0 ]
123123
[[ "${output}" == *"ponG Ping"* ]]
124124
}
125+
126+
@test "checkpoint --lazy-pages and restore" {
127+
# XXX: currently criu require root containers.
128+
requires criu root
129+
130+
# check if lazy-pages is supported
131+
run ${CRIU} check --feature lazy_pages
132+
if [ "$status" -eq 1 ]; then
133+
# this criu does not support lazy migration; skip the test
134+
skip "this criu does not support lazy migration"
135+
fi
136+
137+
sed -i 's;"terminal": true;"terminal": false;' config.json
138+
sed -i 's;"readonly": true;"readonly": false;' config.json
139+
sed -i 's/"sh"/"sh","-c","for i in `seq 10`; do read xxx || continue; echo ponG $xxx; done"/' config.json
140+
141+
# The following code creates pipes for stdin and stdout.
142+
# CRIU can't handle fifo-s, so we need all these tricks.
143+
fifo=`mktemp -u /tmp/runc-fifo-XXXXXX`
144+
mkfifo $fifo
145+
146+
# For lazy migration we need to know when CRIU is ready to serve
147+
# the memory pages via TCP.
148+
lazy_pipe=`mktemp -u /tmp/lazy-pipe-XXXXXX`
149+
mkfifo $lazy_pipe
150+
151+
# TCP port for lazy migration
152+
port=27277
153+
154+
# stdout
155+
cat $fifo | cat $fifo &
156+
pid=$!
157+
exec 50</proc/$pid/fd/0
158+
exec 51>/proc/$pid/fd/0
159+
160+
# stdin
161+
cat $fifo | cat $fifo &
162+
pid=$!
163+
exec 60</proc/$pid/fd/0
164+
exec 61>/proc/$pid/fd/0
165+
166+
echo -n > $fifo
167+
unlink $fifo
168+
169+
# run busybox
170+
__runc run -d test_busybox <&60 >&51 2>&51
171+
[ $? -eq 0 ]
172+
173+
testcontainer test_busybox running
174+
175+
# checkpoint the running container
176+
mkdir image-dir
177+
mkdir work-dir
178+
# Double fork taken from helpers.bats
179+
# We need to start 'runc checkpoint --lazy-pages' in the background,
180+
# so we double fork in the shell.
181+
(runc --criu "$CRIU" checkpoint --lazy-pages --page-server 0.0.0.0:${port} --status-fd ${lazy_pipe} --work-path ./work-dir --image-path ./image-dir test_busybox & ) &
182+
# Sleeping here. This is ugly, but not sure how else to handle it.
183+
# The return code of the in the background running runc is needed, if
184+
# there is some basic error. If the lazy migration is ready can
185+
# be handled by $lazy_pipe. Which probably will always be ready
186+
# after sleeping two seconds.
187+
sleep 2
188+
# Check if inventory.img was written
189+
[ -e image-dir/inventory.img ]
190+
# If the inventory.img exists criu checkpointed some things, let's see
191+
# if there were other errors in the log file.
192+
run grep -B 5 Error ./work-dir/dump.log -q
193+
[ "$status" -eq 1 ]
194+
195+
# This will block until CRIU is ready to serve memory pages
196+
cat $lazy_pipe
197+
[ "$status" -eq 1 ]
198+
199+
unlink $lazy_pipe
200+
201+
# Double fork taken from helpers.bats
202+
# We need to start 'criu lazy-pages' in the background,
203+
# so we double fork in the shell.
204+
# Start CRIU in lazy-daemon mode
205+
$(${CRIU} lazy-pages --page-server --address 127.0.0.1 --port ${port} -D image-dir &) &
206+
207+
# Restore lazily from checkpoint.
208+
# The restored container needs a different name as the checkpointed
209+
# container is not yet destroyed. It is only destroyed at that point
210+
# in time when the last page is lazily transferred to the destination.
211+
# Killing the CRIU on the checkpoint side will let the container
212+
# continue to run if the migration failed at some point.
213+
__runc --criu "$CRIU" restore -d --work-path ./image-dir --image-path ./image-dir --lazy-pages test_busybox_restore <&60 >&51 2>&51
214+
ret=$?
215+
[ $ret -eq 0 ]
216+
run grep -B 5 Error ./work-dir/dump.log -q
217+
[ "$status" -eq 1 ]
218+
219+
# busybox should be back up and running
220+
testcontainer test_busybox_restore running
221+
222+
runc exec --cwd /bin test_busybox_restore echo ok
223+
[ "$status" -eq 0 ]
224+
[[ ${output} == "ok" ]]
225+
226+
echo Ping >&61
227+
exec 61>&-
228+
exec 51>&-
229+
run cat <&50
230+
[ "$status" -eq 0 ]
231+
[[ "${output}" == *"ponG Ping"* ]]
232+
}

0 commit comments

Comments
 (0)