Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Tikhomirov <ptikhomirov@virtuozzo.com>2020-11-02 15:00:58 +0300
committerAndrei Vagin <avagin@gmail.com>2021-09-03 20:31:00 +0300
commit371d9c83d7f9294f5a235069e3e472c72b58a017 (patch)
treedb62beb6f7c3fc7400a4ec7e44b749ed611cdcf1 /test/others/ns_ext
parenteb9ed1aafa2209a5fd2624096a7b68937e86bcbb (diff)
others/ns_ext: restore a process out of PID namespaces into the host PID namespace
It is quiet a common case to move the process from one pidns to another existing pidns with criu (only restriction is pids should not intersect). Let's check it works. v2: - use pipe-s to synchronize processes - run the test in a pid namespace to avoid pid conflicts in the host pid namespace - grep errors in restore.log - add some more comments v3: use 1000 for ns_last_pid so that test works on systems with low pid_max; remove excess ';'s. Co-Developed-by: Andrei Vagin <avagin@gmail.com> Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Diffstat (limited to 'test/others/ns_ext')
-rw-r--r--test/others/ns_ext/Makefile9
-rw-r--r--test/others/ns_ext/__run_pidns.sh21
-rw-r--r--test/others/ns_ext/_run_pidns.sh33
-rwxr-xr-xtest/others/ns_ext/run_pidns.sh59
4 files changed, 121 insertions, 1 deletions
diff --git a/test/others/ns_ext/Makefile b/test/others/ns_ext/Makefile
index f859b89bc..d15224d52 100644
--- a/test/others/ns_ext/Makefile
+++ b/test/others/ns_ext/Makefile
@@ -1,7 +1,14 @@
-run:
+run: run_pidns run_net run_pid
+
+run_net:
./run.sh net
+
+run_pid:
./run.sh pid
+run_pidns:
+ unshare -fp -m --mount-proc --propagation private ./run_pidns.sh
+
clean:
rm -rf images output pidfile pidfile2 pidfile3
.PHONY: clean run
diff --git a/test/others/ns_ext/__run_pidns.sh b/test/others/ns_ext/__run_pidns.sh
new file mode 100644
index 000000000..50cdb6b76
--- /dev/null
+++ b/test/others/ns_ext/__run_pidns.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+set -e
+
+status_fd=$1
+
+exec 0</dev/null
+exec 2>/dev/null
+exec 1>/dev/null
+
+# Sending our real pid to run_pidns.sh over pipe
+
+exec {fd}</proc/self/status
+pid=$(cat <&$fd | grep '^Pid:' | awk '{print $2}')
+exec {fd}>&-
+echo $pid >&$status_fd
+exec {status_fd}>&-
+
+while :; do
+ sleep 10000
+done
diff --git a/test/others/ns_ext/_run_pidns.sh b/test/others/ns_ext/_run_pidns.sh
new file mode 100644
index 000000000..b0b266ad6
--- /dev/null
+++ b/test/others/ns_ext/_run_pidns.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+set -e
+
+status_fd=$1
+
+# Note that with this block we only guaranty that pid of
+# __run_pidns.sh would be somewhere around 1000, not
+# exactly 1000.
+
+mkdir -p pidns_proc
+mount -t proc proc pidns_proc
+echo 1000 > pidns_proc/sys/kernel/ns_last_pid
+umount -l pidns_proc
+rmdir pidns_proc
+
+# Here we create a pipe to wait for __run_pidns.sh to die,
+# when it dies the pipe_w is closed and read from pipe_r
+# is unblocked.
+
+exec {pipe}<> <(:)
+exec {pipe_r}</proc/self/fd/$pipe
+exec {pipe_w}>/proc/self/fd/$pipe
+exec {pipe}>&-
+
+setsid bash __run_pidns.sh $status_fd &
+exec {pipe_w}>&-
+exec {status_fd}>&-
+
+# Waiting for __run_pidns.sh to be checkpointed
+
+cat <&$pipe_r
+echo "Temporary pidns init is exiting..."
diff --git a/test/others/ns_ext/run_pidns.sh b/test/others/ns_ext/run_pidns.sh
new file mode 100755
index 000000000..b4c7b88a8
--- /dev/null
+++ b/test/others/ns_ext/run_pidns.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+set -e
+
+# This test creates a process in non-host pidns and then dumps it and restores
+# it into host pidns. We use pid >100000 in non-host pidns to make sure it does
+# not intersect with some host pid on restore but it is potentially racy so
+# please run this test only in manualy.
+
+CRIU=../../../criu/criu
+
+# This is a status pipe to report the pid of __run_pidns.sh
+exec {pipe}<> <(:)
+exec {pipe_r}</proc/self/fd/$pipe
+exec {pipe_w}>/proc/self/fd/$pipe
+exec {pipe}>&-
+
+unshare -p sh -c "bash _run_pidns.sh $pipe_w &"
+exec {pipe_w}>&-
+
+PID=$(cat <&$pipe_r)
+echo PID: $PID
+
+PIDNS=$(readlink /proc/$PID/ns/pid | sed 's/://')
+echo PIDNS: $PIDNS
+
+BEFORE=$(grep NSpid /proc/$PID/status)
+echo "before c/r: $BEFORE"
+
+rm -rf images_pidns || :
+mkdir -p images_pidns
+
+echo "$CRIU dump -v4 -o dump.log -t $PID -D images_pidns --external $PIDNS:exti"
+$CRIU dump -v4 -o dump.log -t $PID -D images_pidns --external $PIDNS:exti
+RESULT=$?
+cat images_pidns/dump.log | grep -B 5 Error || echo ok
+[ "$RESULT" != "0" ] && {
+ echo "CRIU dump failed"
+ echo FAIL
+ exit 1
+}
+
+exec {pidns_fd}< /proc/self/ns/pid
+
+echo "$CRIU restore -v4 -o restore.log -D images_pidns --restore-detached --inherit-fd fd[$pidns_fd]:exti"
+$CRIU restore -v4 -o restore.log -D images_pidns --restore-detached --inherit-fd fd[$pidns_fd]:exti --pidfile test.pidfile
+RESULT=$?
+cat images_pidns/restore.log | grep -B 5 Error || echo ok
+[ "$RESULT" != "0" ] && {
+ echo "CRIU restore failed"
+ echo FAIL
+ exit 1
+}
+
+PID=$(cat images_pidns/test.pidfile)
+AFTER=$(grep NSpid /proc/$PID/status)
+echo "after c/r: $AFTER"
+echo PASS
+exit 0