2019-07-29 22:07:10 +01:00
|
|
|
#!/usr/bin/python
|
2014-12-11 22:55:16 +02:00
|
|
|
# Test criu errno
|
|
|
|
|
2018-09-23 15:31:51 +01:00
|
|
|
import socket, os, errno
|
2014-12-11 22:55:16 +02:00
|
|
|
import rpc_pb2 as rpc
|
2015-01-22 18:59:00 +03:00
|
|
|
import argparse
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser(description="Test errno reported by CRIU RPC")
|
2019-09-07 15:46:22 +03:00
|
|
|
parser.add_argument('socket', type=str, help="CRIU service socket")
|
|
|
|
parser.add_argument('dir',
|
|
|
|
type=str,
|
|
|
|
help="Directory where CRIU images should be placed")
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2015-01-22 18:59:00 +03:00
|
|
|
args = vars(parser.parse_args())
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
|
2014-12-11 22:55:16 +02:00
|
|
|
# Prepare dir for images
|
|
|
|
class test:
|
2019-09-07 15:46:22 +03:00
|
|
|
def __init__(self):
|
|
|
|
self.imgs_fd = os.open(args['dir'], os.O_DIRECTORY)
|
|
|
|
self.s = -1
|
|
|
|
self._MAX_MSG_SIZE = 1024
|
|
|
|
|
|
|
|
def connect(self):
|
|
|
|
self.s = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
|
|
|
|
self.s.connect(args['socket'])
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
def get_base_req(self):
|
|
|
|
req = rpc.criu_req()
|
|
|
|
req.opts.log_level = 4
|
|
|
|
req.opts.images_dir_fd = self.imgs_fd
|
|
|
|
return req
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
def send_req(self, req):
|
|
|
|
self.connect()
|
|
|
|
self.s.send(req.SerializeToString())
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
def recv_resp(self):
|
|
|
|
resp = rpc.criu_resp()
|
|
|
|
resp.ParseFromString(self.s.recv(self._MAX_MSG_SIZE))
|
|
|
|
return resp
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
def check_resp(self, resp, typ, err):
|
|
|
|
if resp.type != typ:
|
2022-03-30 18:45:16 -07:00
|
|
|
raise Exception('Unexpected response type ' + str(resp.type))
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
if resp.success:
|
|
|
|
raise Exception('Unexpected success = True')
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
if err and resp.cr_errno != err:
|
|
|
|
raise Exception('Unexpected cr_errno ' + str(resp.cr_errno))
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
def no_process(self):
|
|
|
|
print('Try to dump unexisting process')
|
|
|
|
# Get pid of non-existing process.
|
|
|
|
# Suppose max_pid is not taken by any process.
|
|
|
|
with open("/proc/sys/kernel/pid_max", "r") as f:
|
|
|
|
pid = int(f.readline())
|
|
|
|
try:
|
|
|
|
os.kill(pid, 0)
|
|
|
|
except OSError:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
raise Exception('max pid is taken')
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
# Ask criu to dump non-existing process.
|
|
|
|
req = self.get_base_req()
|
|
|
|
req.type = rpc.DUMP
|
|
|
|
req.opts.pid = pid
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
self.send_req(req)
|
|
|
|
resp = self.recv_resp()
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
self.check_resp(resp, rpc.DUMP, errno.ESRCH)
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
print('Success')
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
def process_exists(self):
|
|
|
|
print(
|
|
|
|
'Try to restore process which pid is already taken by other process'
|
|
|
|
)
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
# Perform self-dump
|
|
|
|
req = self.get_base_req()
|
|
|
|
req.type = rpc.DUMP
|
|
|
|
req.opts.leave_running = True
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
self.send_req(req)
|
|
|
|
resp = self.recv_resp()
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
if resp.success != True:
|
|
|
|
raise Exception('Self-dump failed')
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
# Ask to restore process from images of ourselves
|
|
|
|
req = self.get_base_req()
|
|
|
|
req.type = rpc.RESTORE
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
self.send_req(req)
|
|
|
|
resp = self.recv_resp()
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
self.check_resp(resp, rpc.RESTORE, errno.EEXIST)
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
print('Success')
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
def bad_options(self):
|
|
|
|
print('Try to send criu invalid opts')
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
# Subdirs are not allowed in log_file
|
|
|
|
req = self.get_base_req()
|
|
|
|
req.type = rpc.DUMP
|
|
|
|
req.opts.log_file = "../file.log"
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
self.send_req(req)
|
|
|
|
resp = self.recv_resp()
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
self.check_resp(resp, rpc.DUMP, errno.EBADRQC)
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
print('Success')
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
def bad_request(self):
|
|
|
|
print('Try to send criu invalid request type')
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
req = self.get_base_req()
|
|
|
|
req.type = rpc.NOTIFY
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
self.send_req(req)
|
|
|
|
resp = self.recv_resp()
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
self.check_resp(resp, rpc.EMPTY, None)
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
print('Success')
|
2014-12-11 22:55:16 +02:00
|
|
|
|
2019-09-07 15:46:22 +03:00
|
|
|
def run(self):
|
|
|
|
self.no_process()
|
|
|
|
self.process_exists()
|
|
|
|
self.bad_options()
|
|
|
|
self.bad_request()
|
2014-12-11 22:55:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
t = test()
|
|
|
|
t.run()
|