[3/3] zdtm.py: Add minimal support for CRIU RPC testing

Submitted by Pavel Emelianov on Aug. 24, 2016, 1:22 p.m.

Details

Message ID 57BD9F8E.9030009@virtuozzo.com
State Superseded
Headers show

Commit Message

Pavel Emelianov Aug. 24, 2016, 1:22 p.m.
As RPC server the swrk mode is used which, in turn, is easily used
by nice lib/py/criu.py thingie from Ruslan.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 test/criu.py |  1 +
 test/rpc.py  |  1 +
 test/zdtm.py | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 75 insertions(+), 3 deletions(-)
 create mode 120000 test/criu.py
 create mode 120000 test/rpc.py

Patch hide | download patch | download mbox

diff --git a/test/criu.py b/test/criu.py
new file mode 120000
index 0000000..6626084
--- /dev/null
+++ b/test/criu.py
@@ -0,0 +1 @@ 
+../lib/py/criu.py
\ No newline at end of file
diff --git a/test/rpc.py b/test/rpc.py
new file mode 120000
index 0000000..62fc609
--- /dev/null
+++ b/test/rpc.py
@@ -0,0 +1 @@ 
+../lib/py/rpc.py
\ No newline at end of file
diff --git a/test/zdtm.py b/test/zdtm.py
index 762551f..8fe9d9f 100755
--- a/test/zdtm.py
+++ b/test/zdtm.py
@@ -19,6 +19,8 @@  import fcntl
 import errno
 import datetime
 import yaml
+import socket
+import criu as crpc
 
 os.chdir(os.path.dirname(os.path.abspath(__file__)))
 
@@ -650,6 +652,72 @@  class criu_cli:
 			return cr
 		return cr.wait()
 
+class criu_rpc:
+	@staticmethod
+	def __set_opts(criu, args, ctx):
+		while len(args) != 0:
+			arg = args.pop(0)
+			if arg == '-v4':
+				criu.opts.log_level = 4
+				continue
+			if arg == '-o':
+				criu.opts.log_file = args.pop(0)
+				continue
+			if arg == '-D':
+				criu.opts.images_dir_fd = os.open(args.pop(0), os.O_DIRECTORY)
+				ctx['imgd'] = criu.opts.images_dir_fd
+				continue
+			if arg == '-t':
+				criu.opts.pid = int(args.pop(0))
+				continue
+			if arg == '--pidfile':
+				ctx['pidf'] = args.pop(0)
+				continue
+			if arg == '--timeout':
+				criu.opts.timeout = int(args.pop(0))
+				continue
+			if arg == '--restore-detached':
+				# Set by service by default
+				ctx['rd'] = True
+				continue
+			if arg == '--root':
+				criu.opts.root = args.pop(0)
+				continue
+
+			raise test_fail_exc('RPC for %s required' % arg)
+
+	@staticmethod
+	def run(action, args, fault = None, strace = [], preexec = None):
+		if fault:
+			raise test_fail_exc('RPC and FAULT not supported')
+		if strace:
+			raise test_fail_exc('RPC and SAT not supported')
+		if preexec:
+			raise test_fail_exc('RPC and PREEXEC not supported')
+
+		ctx = {} # Object used to keep info untill action is done
+		criu = crpc.criu()
+		criu.use_binary(criu_bin)
+		criu_rpc.__set_opts(criu, args, ctx)
+
+		if action == 'dump':
+			criu.dump()
+		elif action == 'restore':
+			if not ctx.has_key('rd'):
+				raise test_fail_exc('RPC Non-detached restore is impossible')
+
+			res = criu.restore()
+			pidf = ctx.get('pidf')
+			if pidf:
+				open(pidf, 'w').write('%d\n' % res.pid)
+		else:
+			raise test_fail_exc('RPC for %s required' % action)
+
+		imgd = ctx.get('imgd')
+		if imgd:
+			os.close(imgd)
+		return 0
+
 class criu:
 	def __init__(self, opts):
 		self.__test = None
@@ -666,6 +734,7 @@  class criu:
 		self.__sat = (opts['sat'] and True or False)
 		self.__dedup = (opts['dedup'] and True or False)
 		self.__user = (opts['user'] and True or False)
+		self.__criu = (opts['rpc'] and criu_rpc or criu_cli)
 
 	def logs(self):
 		return self.__dump_path
@@ -726,7 +795,7 @@  class criu:
 
 		__ddir = self.__ddir()
 
-		ret = criu_cli.run(action, s_args, self.__fault, strace, preexec)
+		ret = self.__criu.run(action, s_args, self.__fault, strace, preexec)
 		if action == "lazy-pages":
 			return ret
 		grep_errors(os.path.join(__ddir, log))
@@ -743,7 +812,7 @@  class criu:
 					os.rename(os.path.join(__ddir, log), os.path.join(__ddir, log + ".fail"))
 				# try again without faults
 				print "Run criu " + action
-				ret = criu_cli.run(action, s_args, False, strace, preexec)
+				ret = self.__criu.run(action, s_args, False, strace, preexec)
 				grep_errors(os.path.join(__ddir, log))
 				if ret == 0:
 					return
@@ -1177,7 +1246,7 @@  class launcher:
 		self.__show_progress()
 
 		nd = ('nocr', 'norst', 'pre', 'iters', 'page_server', 'sibling', 'unshare',
-				'fault', 'keep_img', 'report', 'snaps', 'sat', 'script',
+				'fault', 'keep_img', 'report', 'snaps', 'sat', 'script', 'rpc',
 				'join_ns', 'dedup', 'sbs', 'freezecg', 'user', 'dry_run', 'lazy_pages')
 		arg = repr((name, desc, flavor, {d: self.__opts[d] for d in nd}))
 
@@ -1625,6 +1694,7 @@  rp.add_argument("--sbs", help = "Do step-by-step execution, asking user for keyp
 rp.add_argument("--unshare", help = "Restore tests into unshared context", action = 'store_true')
 rp.add_argument("--freezecg", help = "Use freeze cgroup (path:state)")
 rp.add_argument("--user", help = "Run CRIU as regular user", action = 'store_true')
+rp.add_argument("--rpc", help = "Run CRIU via RPC rather than CLI", action = 'store_true')
 
 rp.add_argument("--page-server", help = "Use page server dump", action = 'store_true')
 rp.add_argument("-p", "--parallel", help = "Run test in parallel")