diff --git a/scripts/ci/run-ci-tests.sh b/scripts/ci/run-ci-tests.sh index 5b9f6d92920..dc82432efde 100755 --- a/scripts/ci/run-ci-tests.sh +++ b/scripts/ci/run-ci-tests.sh @@ -259,6 +259,7 @@ if [ -n "$TRAVIS" ] || [ -n "$CIRCLECI" ]; then # GitHub Actions (and Cirrus CI) does not provide a real TTY and CRIU will fail with: # Error (criu/tty.c:1014): tty: Don't have tty to inherit session from, aborting make -C test/others/shell-job/ run + make -C test/others/criu-ns/ run fi make -C test/others/skip-file-rwx-check/ run make -C test/others/rpc/ run diff --git a/test/others/criu-ns/Makefile b/test/others/criu-ns/Makefile new file mode 100644 index 00000000000..d81733ef4d9 --- /dev/null +++ b/test/others/criu-ns/Makefile @@ -0,0 +1,2 @@ +run: + ../../zdtm_ct run.py diff --git a/test/others/criu-ns/run.py b/test/others/criu-ns/run.py new file mode 100755 index 00000000000..f7715dcd032 --- /dev/null +++ b/test/others/criu-ns/run.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python + +import os +import pty +import shutil +import subprocess +import sys +import time + +CR_NS = "../../../scripts/criu-ns" +pid = 0 + + +def check_dumpdir(): + if os.path.isdir("dumpdir"): + shutil.rmtree("dumpdir") + os.mkdir("dumpdir", 0o755) + + +def create_pty(): + fd_m, fd_s = pty.openpty() + return (os.fdopen(fd_m, "wb"), os.fdopen(fd_s, "wb")) + + +def create_dumpee(shell_job=False): + global pid + open("running", "w").close() + fd_m, fd_s = create_pty() + pid = os.fork() + if pid == 0: + if not shell_job: + os.setsid() + os.dup2(fd_s.fileno(), 0) + os.dup2(fd_s.fileno(), 1) + os.dup2(fd_s.fileno(), 2) + else: + fd_m.close() + fd_s.close() + while True: + if not os.access("running", os.F_OK): + sys.exit(0) + time.sleep(1) + sys.exit(1) + + +def test_dump_and_restore_with_shell_job(): + global pid + check_dumpdir() + create_dumpee(shell_job=True) + + cmd = [CR_NS, "dump", "-D", "dumpdir", "-v4", "-o", "dump.log", + "--shell-job", "-t", str(pid)] + ret = subprocess.Popen(cmd).wait() + if ret != 0: + sys.exit(ret) + + os.unlink("running") + fd_m, fd_s = create_pty() + pid = os.fork() + if pid == 0: + cmd = [CR_NS, "restore", "-D", "dumpdir", "-v4", "-o", + "restore.log", "--shell-job"] + ret = subprocess.Popen(cmd).wait() + if ret != 0: + sys.exit(ret) + os._exit(0) + + os.waitpid(pid, 0) + + +def test_dump_and_restore_without_shell_job(restore_detached=False): + global pid + check_dumpdir() + create_dumpee() + + cmd = [CR_NS, "dump", "-D", "dumpdir", "-v4", "-o", "dump.log", + "-t", str(pid)] + ret = subprocess.Popen(cmd).wait() + if ret != 0: + sys.exit(ret) + + os.unlink("running") + fd_m, fd_s = create_pty() + pid = os.fork() + if pid == 0: + os.setsid() + + if restore_detached: + cmd = [CR_NS, "restore", "-D", "dumpdir", "-v4", "-o", + "restore.log", "--restore-detached"] + else: + cmd = [CR_NS, "restore", "-D", "dumpdir", "-v4", "-o", + "restore.log"] + + ret = subprocess.Popen(cmd).wait() + if ret != 0: + sys.exit(ret) + os._exit(0) + + os.waitpid(pid, 0) + + +if __name__ == "__main__": + test_dump_and_restore_with_shell_job() + test_dump_and_restore_without_shell_job() + test_dump_and_restore_without_shell_job(restore_detached=True)