[CRIU] [PATCH] zdtm.py: Test how freeze cgroup works

Pavel Emelyanov xemul at parallels.com
Wed Dec 16 06:45:49 PST 2015


Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 test/jenkins/criu-fcg.sh | 13 +++++++
 test/zdtm.py             | 98 +++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 101 insertions(+), 10 deletions(-)
 create mode 100755 test/jenkins/criu-fcg.sh

diff --git a/test/jenkins/criu-fcg.sh b/test/jenkins/criu-fcg.sh
new file mode 100755
index 0000000..72cefdb
--- /dev/null
+++ b/test/jenkins/criu-fcg.sh
@@ -0,0 +1,13 @@
+# Test how freeze cgroup works
+set -e
+source `dirname $0`/criu-lib.sh
+prep
+mount_tmpfs_to_dump
+
+./test/zdtm.py run -t zdtm/live/transition/thread-bomb -f h --report report --freezecg zdtm:f || fail
+./test/zdtm.py run -t zdtm/live/transition/thread-bomb -f h --report report --freezecg zdtm:f --pre 3 || fail
+./test/zdtm.py run -t zdtm/live/transition/thread-bomb -f h --report report --freezecg zdtm:f --norst || fail
+
+./test/zdtm.py run -t zdtm/live/transition/thread-bomb -f h --report report --freezecg zdtm:t || fail
+./test/zdtm.py run -t zdtm/live/transition/thread-bomb -f h --report report --freezecg zdtm:t --pre 3 || fail
+./test/zdtm.py run -t zdtm/live/transition/thread-bomb -f h --report report --freezecg zdtm:t --norst || fail
diff --git a/test/zdtm.py b/test/zdtm.py
index d58c621..61be010 100755
--- a/test/zdtm.py
+++ b/test/zdtm.py
@@ -274,12 +274,14 @@ class test_fail_expected_exc:
 #
 
 class zdtm_test:
-	def __init__(self, name, desc, flavor):
+	def __init__(self, name, desc, flavor, freezer):
 		self.__name = name
 		self.__desc = desc
+		self.__freezer = None
 		self.__make_action('cleanout')
 		self.__pid = 0
 		self.__flavor = flavor
+		self.__freezer = freezer
 		self._bins = [ name ]
 		self._env = {}
 		self._deps = desc.get('deps', [])
@@ -295,9 +297,13 @@ class zdtm_test:
 		if env:
 			env = dict(os.environ, **env)
 
-		s = subprocess.Popen(s_args, env = env, cwd = root)
+		s = subprocess.Popen(s_args, env = env, cwd = root,
+				preexec_fn = self.__freezer and self.__freezer.attach or None)
 		s.wait()
 
+		if self.__freezer:
+			self.__freezer.freeze()
+
 	def __pidfile(self):
 		if self.__flavor.ns:
 			return self.__name + '.init.pid'
@@ -319,7 +325,9 @@ class zdtm_test:
 		print "Start test"
 
 		env = self._env
-		env['ZDTM_THREAD_BOMB'] = "5"
+		if not self.__freezer.kernel:
+			env['ZDTM_THREAD_BOMB'] = "5"
+
 		if not test_flag(self.__desc, 'suid'):
 			env['ZDTM_UID'] = "18943"
 			env['ZDTM_GID'] = "58467"
@@ -352,6 +360,7 @@ class zdtm_test:
 		self.__flavor.fini()
 
 	def stop(self):
+		self.__freezer.thaw()
 		self.getpid() # Read the pid from pidfile back
 		self.kill(signal.SIGTERM)
 
@@ -377,10 +386,10 @@ class zdtm_test:
 		return opts
 
 	def getdopts(self):
-		return self.__getcropts()
+		return self.__getcropts() + self.__freezer.getdopts()
 
 	def getropts(self):
-		return self.__getcropts()
+		return self.__getcropts() + self.__freezer.getropts()
 
 	def gone(self, force = True):
 		if not self.auto_reap:
@@ -415,7 +424,7 @@ class zdtm_test:
 
 
 class inhfd_test:
-	def __init__(self, name, desc, flavor):
+	def __init__(self, name, desc, flavor, freezer):
 		self.__name = os.path.basename(name)
 		print "Load %s" % name
 		self.__fdtyp = imp.load_source(self.__name, name)
@@ -504,8 +513,8 @@ class inhfd_test:
 
 
 class groups_test(zdtm_test):
-	def __init__(self, name, desc, flavor):
-		zdtm_test.__init__(self, 'zdtm/lib/groups', desc, flavor)
+	def __init__(self, name, desc, flavor, freezer):
+		zdtm_test.__init__(self, 'zdtm/lib/groups', desc, flavor, freezer)
 		if flavor.ns:
 			self.__real_name = name
 			self.__subs = map(lambda x: x.strip(), open(name).readlines())
@@ -790,6 +799,67 @@ def check_visible_state(test, state):
 
 		raise test_fail_exc("maps compare")
 
+
+class noop_freezer:
+	def __init__(self):
+		self.kernel = False
+
+	def attach(self):
+		pass
+
+	def freeze(self):
+		pass
+
+	def thaw(self):
+		pass
+
+	def getdopts(self):
+		return []
+
+	def getropts(self):
+		return []
+
+
+class cg_freezer:
+	def __init__(self, path, state):
+		self.__path = '/sys/fs/cgroup/freezer/' + path
+		self.__state = state
+		self.kernel = True
+
+	def attach(self):
+		if not os.access(self.__path, os.F_OK):
+			os.makedirs(self.__path)
+		with open(self.__path + '/tasks', 'w') as f:
+			f.write('0')
+
+	def __set_state(self, state):
+		with open(self.__path + '/freezer.state', 'w') as f:
+			f.write(state)
+
+	def freeze(self):
+		if self.__state.startswith('f'):
+			self.__set_state('FROZEN')
+
+	def thaw(self):
+		if self.__state.startswith('f'):
+			self.__set_state('THAWED')
+
+	def getdopts(self):
+		return [ '--freeze-cgroup', self.__path, '--manage-cgroups' ]
+
+	def getropts(self):
+		return [ '--manage-cgroups' ]
+
+
+def get_freezer(desc):
+	if not desc:
+		return noop_freezer()
+
+	fd = desc.split(':')
+	fr = cg_freezer(path = fd[0], state = fd[1])
+	return fr
+
+
 def do_run_test(tname, tdesc, flavs, opts):
 	tcname = tname.split('/')[0]
 	tclass = test_classes.get(tcname, None)
@@ -802,11 +872,13 @@ def do_run_test(tname, tdesc, flavs, opts):
 	if opts['sbs']:
 		init_sbs()
 
+	fcg = get_freezer(opts['freezecg'])
+
 	for f in flavs:
 		print
 		print_sep("Run %s in %s" % (tname, f))
 		flav = flavors[f](opts)
-		t = tclass(tname, tdesc, flav)
+		t = tclass(tname, tdesc, flav, fcg)
 		cr_api = criu_cli(opts)
 
 		try:
@@ -866,7 +938,8 @@ class launcher:
 		self.__show_progress()
 
 		nd = ('nocr', 'norst', 'pre', 'iters', 'page_server', 'sibling', \
-				'fault', 'keep_img', 'report', 'snaps', 'sat', 'dedup', 'sbs')
+				'fault', 'keep_img', 'report', 'snaps', 'sat', \
+				'dedup', 'sbs', 'freezecg')
 		arg = repr((name, desc, flavor, { d: self.__opts[d] for d in nd }))
 
 		if self.__max > 1 and self.__total > 1:
@@ -1002,6 +1075,10 @@ def run_tests(opts):
 	if opts['report']:
 		init_report(opts['report'])
 
+	if opts['parallel'] and opts['freezecg']:
+		print "Parallel launch with freezer not supported"
+		opts['parallel'] = None
+
 	l = launcher(opts, len(torun))
 	try:
 		for t in torun:
@@ -1219,6 +1296,7 @@ rp.add_argument("--iters", help = "Do CR cycle several times before check (n[:pa
 rp.add_argument("--fault", help = "Test fault injection")
 rp.add_argument("--sat", help = "Generate criu strace-s for sat tool (restore is fake, images are kept)", action = 'store_true')
 rp.add_argument("--sbs", help = "Do step-by-step execution, asking user for keypress to continue", action = 'store_true')
+rp.add_argument("--freezecg", help = "Use freeze cgroup (path:state)")
 
 rp.add_argument("--page-server", help = "Use page server dump", action = 'store_true')
 rp.add_argument("-p", "--parallel", help = "Run test in parallel")
-- 
1.9.3



More information about the CRIU mailing list