[3/5] zdtm: create a few external descriptros

Submitted by Andrey Vagin on Sept. 20, 2018, 10:22 p.m.

Details

Message ID 20180920221817.29697-4-avagin@virtuozzo.com
State Accepted
Series "files: save inherited file descriptors in fdstore"
Headers show

Commit Message

Andrey Vagin Sept. 20, 2018, 10:22 p.m.
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@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(-)

Patch hide | download patch | download mbox

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