mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 14:25:49 +00:00
zdtm: create a few external descriptros
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> Signed-off-by: Andrei Vagin <avagin@gmail.com>
This commit is contained in:
committed by
Andrei Vagin
parent
a96d229876
commit
89c5fc9b06
@@ -28,7 +28,7 @@ def create_fds():
|
|||||||
global id_str
|
global id_str
|
||||||
id_str = "file[%x:%x]" % (mnt_id, os.fstat(fd1.fileno()).st_ino)
|
id_str = "file[%x:%x]" % (mnt_id, os.fstat(fd1.fileno()).st_ino)
|
||||||
|
|
||||||
return (fd2, fd1)
|
return [(fd2, fd1)]
|
||||||
|
|
||||||
|
|
||||||
def filename(pipef):
|
def filename(pipef):
|
||||||
|
@@ -2,8 +2,11 @@ import os
|
|||||||
|
|
||||||
|
|
||||||
def create_fds():
|
def create_fds():
|
||||||
(fd1, fd2) = os.pipe()
|
pipes = []
|
||||||
return (os.fdopen(fd2, "wb"), os.fdopen(fd1, "rb"))
|
for i in range(10):
|
||||||
|
(fd1, fd2) = os.pipe()
|
||||||
|
pipes.append((os.fdopen(fd2, "wb"), os.fdopen(fd1, "rb")))
|
||||||
|
return pipes
|
||||||
|
|
||||||
|
|
||||||
def filename(pipef):
|
def filename(pipef):
|
||||||
|
@@ -4,7 +4,9 @@ import os
|
|||||||
|
|
||||||
def create_fds():
|
def create_fds():
|
||||||
(sk1, sk2) = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
|
(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):
|
def __sock_ino(sockf):
|
||||||
|
@@ -1,16 +1,30 @@
|
|||||||
|
# vim: noet ts=8 sw=8 sts=8
|
||||||
import fcntl
|
import fcntl
|
||||||
import os
|
import os
|
||||||
import pty
|
import pty
|
||||||
import termios
|
import termios
|
||||||
|
|
||||||
|
|
||||||
|
ctl = False
|
||||||
|
|
||||||
|
|
||||||
def child_prep(fd):
|
def child_prep(fd):
|
||||||
|
global ctl
|
||||||
|
if ctl:
|
||||||
|
return
|
||||||
|
ctl = True
|
||||||
fcntl.ioctl(fd.fileno(), termios.TIOCSCTTY, 1)
|
fcntl.ioctl(fd.fileno(), termios.TIOCSCTTY, 1)
|
||||||
|
|
||||||
|
|
||||||
def create_fds():
|
def create_fds():
|
||||||
(fd1, fd2) = pty.openpty()
|
ttys = []
|
||||||
return (os.fdopen(fd2, "wb"), os.fdopen(fd1, "rb"))
|
for i in range(10):
|
||||||
|
(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):
|
def filename(pipef):
|
||||||
@@ -20,4 +34,4 @@ def filename(pipef):
|
|||||||
|
|
||||||
def dump_opts(sockf):
|
def dump_opts(sockf):
|
||||||
st = os.fstat(sockf.fileno())
|
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)
|
||||||
|
89
test/zdtm.py
89
test/zdtm.py
@@ -580,28 +580,35 @@ class inhfd_test:
|
|||||||
self.__name = os.path.basename(name)
|
self.__name = os.path.basename(name)
|
||||||
print("Load %s" % name)
|
print("Load %s" % name)
|
||||||
self.__fdtyp = imp.load_source(self.__name, name)
|
self.__fdtyp = imp.load_source(self.__name, name)
|
||||||
self.__my_file = None
|
|
||||||
self.__peer_pid = 0
|
self.__peer_pid = 0
|
||||||
self.__peer_file = None
|
self.__files = None
|
||||||
self.__peer_file_name = None
|
self.__peer_file_names = []
|
||||||
self.__dump_opts = None
|
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):
|
def start(self):
|
||||||
self.__message = b"".join([random.choice(string.ascii_letters).encode() for _ in range(16)])
|
self.__files = self.__fdtyp.create_fds()
|
||||||
(self.__my_file, peer_file) = self.__fdtyp.create_fds()
|
|
||||||
|
|
||||||
# Check FDs returned for inter-connection
|
# Check FDs returned for inter-connection
|
||||||
self.__my_file.write(self.__message)
|
i = 0
|
||||||
self.__my_file.flush()
|
for my_file, peer_file in self.__files:
|
||||||
if peer_file.read(16) != self.__message:
|
msg = self.__get_message(i)
|
||||||
raise test_fail_exc("FDs screwup")
|
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()
|
start_pipe = os.pipe()
|
||||||
self.__peer_pid = os.fork()
|
self.__peer_pid = os.fork()
|
||||||
if self.__peer_pid == 0:
|
if self.__peer_pid == 0:
|
||||||
os.setsid()
|
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:
|
try:
|
||||||
os.unlink(self.__name + ".out")
|
os.unlink(self.__name + ".out")
|
||||||
@@ -611,29 +618,45 @@ class inhfd_test:
|
|||||||
os.dup2(fd, 1)
|
os.dup2(fd, 1)
|
||||||
os.dup2(fd, 2)
|
os.dup2(fd, 2)
|
||||||
os.close(0)
|
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[0])
|
||||||
os.close(start_pipe[1])
|
os.close(start_pipe[1])
|
||||||
try:
|
i = 0
|
||||||
data = peer_file.read(16)
|
for _, peer_file in self.__files:
|
||||||
except Exception as e:
|
msg = self.__get_message(i)
|
||||||
print("Unable to read a peer file: %s" % e)
|
my_file.close()
|
||||||
sys.exit(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:
|
if data != msg:
|
||||||
print("%r %r" % (data, self.__message))
|
print("%r %r" % (data, msg))
|
||||||
sys.exit(data == self.__message and 42 or 2)
|
i += 1
|
||||||
|
sys.exit(data == msg and 42 or 2)
|
||||||
|
|
||||||
os.close(start_pipe[1])
|
os.close(start_pipe[1])
|
||||||
os.read(start_pipe[0], 12)
|
os.read(start_pipe[0], 12)
|
||||||
os.close(start_pipe[0])
|
os.close(start_pipe[0])
|
||||||
|
|
||||||
self.__peer_file_name = self.__fdtyp.filename(peer_file)
|
for _, peer_file in self.__files:
|
||||||
self.__dump_opts = self.__fdtyp.dump_opts(peer_file)
|
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):
|
def stop(self):
|
||||||
self.__my_file.write(self.__message)
|
fds = set(os.listdir("/proc/%s/fd" % self.__peer_pid))
|
||||||
self.__my_file.flush()
|
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)
|
pid, status = os.waitpid(self.__peer_pid, 0)
|
||||||
with open(self.__name + ".out") as output:
|
with open(self.__name + ".out") as output:
|
||||||
print(output.read())
|
print(output.read())
|
||||||
@@ -654,18 +677,22 @@ class inhfd_test:
|
|||||||
def gone(self, force = True):
|
def gone(self, force = True):
|
||||||
os.waitpid(self.__peer_pid, 0)
|
os.waitpid(self.__peer_pid, 0)
|
||||||
wait_pid_die(self.__peer_pid, self.__name)
|
wait_pid_die(self.__peer_pid, self.__name)
|
||||||
self.__my_file = None
|
self.__files = None
|
||||||
self.__peer_file = None
|
|
||||||
|
|
||||||
def getdopts(self):
|
def getdopts(self):
|
||||||
return self.__dump_opts
|
return self.__dump_opts
|
||||||
|
|
||||||
def getropts(self):
|
def getropts(self):
|
||||||
(self.__my_file, self.__peer_file) = self.__fdtyp.create_fds()
|
self.__files = self.__fdtyp.create_fds()
|
||||||
fd = self.__peer_file.fileno()
|
ropts = ["--restore-sibling"]
|
||||||
fdflags = fcntl.fcntl(fd, fcntl.F_GETFD) & ~fcntl.FD_CLOEXEC
|
for i in range(len(self.__files)):
|
||||||
fcntl.fcntl(fd, fcntl.F_SETFD, fdflags)
|
my_file, peer_file = self.__files[i]
|
||||||
return ["--restore-sibling", "--inherit-fd", "fd[%d]:%s" % (fd, self.__peer_file_name)]
|
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):
|
def print_output(self):
|
||||||
pass
|
pass
|
||||||
|
Reference in New Issue
Block a user