[CRIU] [PATCH 3/5] zdtm: create a few external descriptros
Andrey Vagin
avagin at virtuozzo.com
Fri Sep 21 01:22:35 MSK 2018
Currently, we create only one external resource to check how it is
handled by criu. It is better to create more than one.
Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
test/inhfd/fifo.py | 2 +-
test/inhfd/pipe.py | 7 ++--
test/inhfd/socket.py | 4 ++-
test/inhfd/tty.py | 20 ++++++++++--
test/zdtm.py | 91 ++++++++++++++++++++++++++++++++++------------------
5 files changed, 85 insertions(+), 39 deletions(-)
diff --git a/test/inhfd/fifo.py b/test/inhfd/fifo.py
index bd4017ec4..64e5f8f13 100755
--- a/test/inhfd/fifo.py
+++ b/test/inhfd/fifo.py
@@ -28,7 +28,7 @@ def create_fds():
global id_str
id_str = "file[%x:%x]" % (mnt_id, os.fstat(fd1.fileno()).st_ino)
- return (fd2, fd1)
+ return [(fd2, fd1)]
def filename(pipef):
diff --git a/test/inhfd/pipe.py b/test/inhfd/pipe.py
index 4635a6cc1..318dc862d 100755
--- a/test/inhfd/pipe.py
+++ b/test/inhfd/pipe.py
@@ -2,8 +2,11 @@ import os
def create_fds():
- (fd1, fd2) = os.pipe()
- return (os.fdopen(fd2, "wb"), os.fdopen(fd1, "rb"))
+ pipes = []
+ for i in range(10):
+ (fd1, fd2) = os.pipe()
+ pipes.append((os.fdopen(fd2, "wb"), os.fdopen(fd1, "rb")))
+ return pipes
def filename(pipef):
diff --git a/test/inhfd/socket.py b/test/inhfd/socket.py
index d7e434046..feba0e0c6 100755
--- a/test/inhfd/socket.py
+++ b/test/inhfd/socket.py
@@ -4,7 +4,9 @@ import os
def create_fds():
(sk1, sk2) = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
- return (sk1.makefile("wb"), sk2.makefile("rb"))
+ (sk3, sk4) = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
+ return [(sk1.makefile("wb"), sk2.makefile("rb")),
+ (sk3.makefile("wb"), sk4.makefile("rb"))]
def __sock_ino(sockf):
diff --git a/test/inhfd/tty.py b/test/inhfd/tty.py
index 519b6bcbc..e59c6716b 100755
--- a/test/inhfd/tty.py
+++ b/test/inhfd/tty.py
@@ -1,16 +1,30 @@
+# vim: noet ts=8 sw=8 sts=8
import fcntl
import os
import pty
import termios
+ctl = False
+
+
def child_prep(fd):
+ global ctl
+ if ctl:
+ return
+ ctl = True
fcntl.ioctl(fd.fileno(), termios.TIOCSCTTY, 1)
def create_fds():
- (fd1, fd2) = pty.openpty()
- return (os.fdopen(fd2, "wb"), os.fdopen(fd1, "rb"))
+ ttys = []
+ for i in range(100):
+ (fd1, fd2) = pty.openpty()
+ newattr = termios.tcgetattr(fd1)
+ newattr[3] &= ~termios.ICANON & ~termios.ECHO
+ termios.tcsetattr(fd1, termios.TCSADRAIN, newattr)
+ ttys.append((os.fdopen(fd1, "wb"), os.fdopen(fd2, "rb")))
+ return ttys
def filename(pipef):
@@ -20,4 +34,4 @@ def filename(pipef):
def dump_opts(sockf):
st = os.fstat(sockf.fileno())
- return ["--external", 'tty[%x:%x]' % (st.st_rdev, st.st_dev)]
+ return "--external", 'tty[%x:%x]' % (st.st_rdev, st.st_dev)
diff --git a/test/zdtm.py b/test/zdtm.py
index c27787529..4ce54bf3c 100755
--- a/test/zdtm.py
+++ b/test/zdtm.py
@@ -579,28 +579,35 @@ class inhfd_test:
self.__name = os.path.basename(name)
print("Load %s" % name)
self.__fdtyp = imp.load_source(self.__name, name)
- self.__my_file = None
self.__peer_pid = 0
- self.__peer_file = None
- self.__peer_file_name = None
- self.__dump_opts = None
+ self.__files = None
+ self.__peer_file_names = []
+ self.__dump_opts = []
+
+ def __get_message(self, i):
+ return b"".join([random.choice(string.ascii_letters).encode() for _ in range(10)]) + b"%06d" % i
def start(self):
- self.__message = b"".join([random.choice(string.ascii_letters).encode() for _ in range(16)])
- (self.__my_file, peer_file) = self.__fdtyp.create_fds()
+ self.__files = self.__fdtyp.create_fds()
# Check FDs returned for inter-connection
- self.__my_file.write(self.__message)
- self.__my_file.flush()
- if peer_file.read(16) != self.__message:
- raise test_fail_exc("FDs screwup")
+ i = 0
+ for my_file, peer_file in self.__files:
+ msg = self.__get_message(i)
+ my_file.write(msg)
+ my_file.flush()
+ data = peer_file.read(len(msg))
+ if data != msg:
+ raise test_fail_exc("FDs screwup: %r %r" % (msg, data))
+ i += 1
start_pipe = os.pipe()
self.__peer_pid = os.fork()
if self.__peer_pid == 0:
os.setsid()
- getattr(self.__fdtyp, "child_prep", lambda fd: None)(peer_file)
+ for _, peer_file in self.__files:
+ getattr(self.__fdtyp, "child_prep", lambda fd: None)(peer_file)
try:
os.unlink(self.__name + ".out")
@@ -610,29 +617,45 @@ class inhfd_test:
os.dup2(fd, 1)
os.dup2(fd, 2)
os.close(0)
- self.__my_file.close()
+ for my_file, _ in self.__files:
+ my_file.close()
os.close(start_pipe[0])
os.close(start_pipe[1])
- try:
- data = peer_file.read(16)
- except Exception as e:
- print("Unable to read a peer file: %s" % e)
- sys.exit(1)
-
- if data != self.__message:
- print("%r %r" % (data, self.__message))
- sys.exit(data == self.__message and 42 or 2)
+ i = 0
+ for _, peer_file in self.__files:
+ msg = self.__get_message(i)
+ my_file.close()
+ try:
+ data = peer_file.read(16)
+ except Exception as e:
+ print("Unable to read a peer file: %s" % e)
+ sys.exit(1)
+
+ if data != msg:
+ print("%r %r" % (data, msg))
+ i += 1
+ sys.exit(data == msg and 42 or 2)
os.close(start_pipe[1])
os.read(start_pipe[0], 12)
os.close(start_pipe[0])
- self.__peer_file_name = self.__fdtyp.filename(peer_file)
- self.__dump_opts = self.__fdtyp.dump_opts(peer_file)
+ for _, peer_file in self.__files:
+ self.__peer_file_names.append(self.__fdtyp.filename(peer_file))
+ self.__dump_opts += self.__fdtyp.dump_opts(peer_file)
+
+ self.__fds = set(os.listdir("/proc/%s/fd" % self.__peer_pid))
def stop(self):
- self.__my_file.write(self.__message)
- self.__my_file.flush()
+ fds = set(os.listdir("/proc/%s/fd" % self.__peer_pid))
+ if fds != self.__fds:
+ raise test_fail_exc("File descriptors mismatch: %s %s" % (fds, self.__fds))
+ i = 0
+ for my_file, _ in self.__files:
+ msg = self.__get_message(i)
+ my_file.write(msg)
+ my_file.flush()
+ i += 1
pid, status = os.waitpid(self.__peer_pid, 0)
print(open(self.__name + ".out").read())
self.__peer_pid = 0
@@ -652,18 +675,22 @@ class inhfd_test:
def gone(self, force = True):
os.waitpid(self.__peer_pid, 0)
wait_pid_die(self.__peer_pid, self.__name)
- self.__my_file = None
- self.__peer_file = None
+ self.__files = None
def getdopts(self):
return self.__dump_opts
def getropts(self):
- (self.__my_file, self.__peer_file) = self.__fdtyp.create_fds()
- fd = self.__peer_file.fileno()
- fdflags = fcntl.fcntl(fd, fcntl.F_GETFD) & ~fcntl.FD_CLOEXEC
- fcntl.fcntl(fd, fcntl.F_SETFD, fdflags)
- return ["--restore-sibling", "--inherit-fd", "fd[%d]:%s" % (fd, self.__peer_file_name)]
+ self.__files = self.__fdtyp.create_fds()
+ ropts = ["--restore-sibling"]
+ for i in range(len(self.__files)):
+ my_file, peer_file = self.__files[i]
+ fd = peer_file.fileno()
+ fdflags = fcntl.fcntl(fd, fcntl.F_GETFD) & ~fcntl.FD_CLOEXEC
+ fcntl.fcntl(fd, fcntl.F_SETFD, fdflags)
+ peer_file_name = self.__peer_file_names[i]
+ ropts.extend(["--inherit-fd", "fd[%d]:%s" % (fd, peer_file_name)])
+ return ropts
def print_output(self):
pass
--
2.14.4
More information about the CRIU
mailing list