[3/5] crit: enable python2 or python3 based crit

Submitted by Adrian Reber on May 14, 2018, 1:07 p.m.

Details

Message ID 1526303231-10750-4-git-send-email-adrian@lisas.de
State Accepted
Series "Series without cover letter"
Headers show

Commit Message

Adrian Reber May 14, 2018, 1:07 p.m.
From: Adrian Reber <areber@redhat.com>

With this last commit of the crit with python3 series it is possible to
either use python2 or python3 with CRIU.

Now the basic build system functionality (make and make install) are
python2/python3 aware. zdtm.py and criu-coredump are still python2, but
as they are not part of 'make install' those parts have not yet been
ported from python2 to python3.

Signed-off-by: Adrian Reber <areber@redhat.com>
---
 .gitignore        |   1 +
 Makefile          |  17 ++-
 crit/Makefile     |  13 +++
 crit/crit         | 338 ------------------------------------------------------
 crit/crit-python2 |   6 +
 crit/crit-python3 |   6 +
 lib/py/cli.py     | 337 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 376 insertions(+), 342 deletions(-)
 create mode 100644 crit/Makefile
 delete mode 100755 crit/crit
 create mode 100755 crit/crit-python2
 create mode 100755 crit/crit-python3
 create mode 100755 lib/py/cli.py

Patch hide | download patch | download mbox

diff --git a/.gitignore b/.gitignore
index 0486689..c231104 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@  images/google/protobuf/*.c
 images/google/protobuf/*.h
 .gitid
 criu/criu
+crit/crit
 criu/arch/*/sys-exec-tbl*.c
 # x86 syscalls-table is not generated
 !criu/arch/x86/sys-exec-tbl.c
diff --git a/Makefile b/Makefile
index bdfb55b..eb95ec5 100644
--- a/Makefile
+++ b/Makefile
@@ -127,7 +127,7 @@  HOSTCFLAGS		+= $(WARNINGS) $(DEFINES) -iquote include/
 export CFLAGS USERCLFAGS HOSTCFLAGS
 
 # Default target
-all: criu lib
+all: criu lib crit
 .PHONY: all
 
 #
@@ -228,14 +228,22 @@  criu: $(criu-deps)
 	$(Q) $(MAKE) $(build)=criu all
 .PHONY: criu
 
+crit/Makefile: ;
+crit/%: criu .FORCE
+	$(Q) $(MAKE) $(build)=crit $@
+crit: criu
+	$(Q) $(MAKE) $(build)=crit all
+.PHONY: crit
+
+
 #
-# Libraries next once criu it ready
+# Libraries next once crit it ready
 # (we might generate headers and such
 # when building criu itself).
 lib/Makefile: ;
-lib/%: criu .FORCE
+lib/%: crit .FORCE
 	$(Q) $(MAKE) $(build)=lib $@
-lib: criu
+lib: crit
 	$(Q) $(MAKE) $(build)=lib all
 .PHONY: lib
 
@@ -247,6 +255,7 @@  clean mrproper:
 	$(Q) $(MAKE) $(build)=compel $@
 	$(Q) $(MAKE) $(build)=compel/plugins $@
 	$(Q) $(MAKE) $(build)=lib $@
+	$(Q) $(MAKE) $(build)=crit $@
 .PHONY: clean mrproper
 
 clean-top:
diff --git a/crit/Makefile b/crit/Makefile
new file mode 100644
index 0000000..4de7f0c
--- /dev/null
+++ b/crit/Makefile
@@ -0,0 +1,13 @@ 
+
+all-y	+= crit
+
+crit/crit: crit/crit-$(CRIU_PYTHON)
+	$(Q) cp $^ $@
+crit: crit/crit
+.PHONY: crit
+
+clean-crit:
+	$(Q) $(RM) crit/crit
+.PHONY: clean-crit
+clean: clean-crit
+mrproper: clean
diff --git a/crit/crit b/crit/crit
deleted file mode 100755
index 6adccc9..0000000
--- a/crit/crit
+++ /dev/null
@@ -1,338 +0,0 @@ 
-#!/usr/bin/env python2
-from __future__ import print_function
-import argparse
-import sys
-import json
-import os
-
-import pycriu
-
-def inf(opts):
-	if opts['in']:
-		return open(opts['in'], 'rb')
-	else:
-		return sys.stdin
-
-def outf(opts):
-	if opts['out']:
-		return open(opts['out'], 'w+')
-	else:
-		return sys.stdout
-
-def dinf(opts, name):
-	return open(os.path.join(opts['dir'], name))
-
-def decode(opts):
-	indent = None
-
-	try:
-		img = pycriu.images.load(inf(opts), opts['pretty'], opts['nopl'])
-	except pycriu.images.MagicException as exc:
-		print("Unknown magic %#x.\n"\
-				"Maybe you are feeding me an image with "\
-				"raw data(i.e. pages.img)?" % exc.magic, file=sys.stderr)
-		sys.exit(1)
-
-	if opts['pretty']:
-		indent = 4
-
-	f = outf(opts)
-	json.dump(img, f, indent=indent)
-	if f == sys.stdout:
-		f.write("\n")
-
-def encode(opts):
-	img = json.load(inf(opts))
-	pycriu.images.dump(img, outf(opts))
-
-def info(opts):
-	infs = pycriu.images.info(inf(opts))
-	json.dump(infs, sys.stdout, indent = 4)
-	print()
-
-def get_task_id(p, val):
-	return p[val] if val in p else p['ns_' + val][0]
-#
-# Explorers
-#
-
-class ps_item:
-	def __init__(self, p, core):
-		self.pid = get_task_id(p, 'pid')
-		self.ppid = p['ppid']
-		self.p = p
-		self.core = core
-		self.kids = []
-
-def show_ps(p, opts, depth = 0):
-	print("%7d%7d%7d   %s%s" % (p.pid, get_task_id(p.p, 'pgid'), get_task_id(p.p, 'sid'),
-			' ' * (4 * depth), p.core['tc']['comm']))
-	for kid in p.kids:
-		show_ps(kid, opts, depth + 1)
-
-def explore_ps(opts):
-	pss = { }
-	ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
-	for p in ps_img['entries']:
-		core = pycriu.images.load(dinf(opts, 'core-%d.img' % get_task_id(p, 'pid')))
-		ps = ps_item(p, core['entries'][0])
-		pss[ps.pid] = ps
-
-	# Build tree
-	psr = None
-	for pid in pss:
-		p = pss[pid]
-		if p.ppid == 0:
-			psr = p
-			continue
-
-		pp = pss[p.ppid]
-		pp.kids.append(p)
-
-	print("%7s%7s%7s   %s" % ('PID', 'PGID', 'SID', 'COMM'))
-	show_ps(psr, opts)
-
-files_img = None
-
-def ftype_find_in_files(opts, ft, fid):
-	global files_img
-
-	if files_img is None:
-		try:
-			files_img = pycriu.images.load(dinf(opts, "files.img"))['entries']
-		except:
-			files_img = []
-
-	if len(files_img) == 0:
-		return None
-
-	for f in files_img:
-		if f['id'] == fid:
-			return f
-
-	return None
-
-
-def ftype_find_in_image(opts, ft, fid, img):
-	f = ftype_find_in_files(opts, ft, fid)
-	if f:
-		return f[ft['field']]
-
-	if ft['img'] == None:
-		ft['img'] = pycriu.images.load(dinf(opts, img))['entries']
-	for f in ft['img']:
-		if f['id'] == fid:
-			return f
-	return None
-
-def ftype_reg(opts, ft, fid):
-	rf = ftype_find_in_image(opts, ft, fid, 'reg-files.img')
-	return rf and rf['name'] or 'unknown path'
-
-def ftype_pipe(opts, ft, fid):
-	p = ftype_find_in_image(opts, ft, fid, 'pipes.img')
-	return p and 'pipe[%d]' % p['pipe_id'] or 'pipe[?]'
-
-def ftype_unix(opts, ft, fid):
-	ux = ftype_find_in_image(opts, ft, fid, 'unixsk.img')
-	if not ux:
-		return 'unix[?]'
-
-	n = ux['name'] and ' %s' % ux['name'] or ''
-	return 'unix[%d (%d)%s]' % (ux['ino'], ux['peer'], n)
-
-file_types = {
-	'REG':		{'get': ftype_reg,	'img': None,	'field': 'reg'},
-	'PIPE':		{'get': ftype_pipe,	'img': None,	'field': 'pipe'},
-	'UNIXSK':	{'get': ftype_unix,	'img': None,	'field': 'usk'},
-}
-
-def ftype_gen(opts, ft, fid):
-	return '%s.%d' % (ft['typ'], fid)
-
-files_cache = { }
-
-def get_file_str(opts, fd):
-	key = (fd['type'], fd['id'])
-	f = files_cache.get(key, None)
-	if not f:
-		ft = file_types.get(fd['type'], {'get': ftype_gen, 'typ': fd['type']})
-		f = ft['get'](opts, ft, fd['id'])
-		files_cache[key] = f
-
-	return f
-
-def explore_fds(opts):
-	ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
-	for p in ps_img['entries']:
-		pid = get_task_id(p, 'pid')
-		idi = pycriu.images.load(dinf(opts, 'ids-%s.img' % pid))
-		fdt = idi['entries'][0]['files_id']
-		fdi = pycriu.images.load(dinf(opts, 'fdinfo-%d.img' % fdt))
-
-		print("%d" % pid)
-		for fd in fdi['entries']:
-			print("\t%7d: %s" % (fd['fd'], get_file_str(opts, fd)))
-
-		fdi = pycriu.images.load(dinf(opts, 'fs-%d.img' % pid))['entries'][0]
-		print("\t%7s: %s" % ('cwd', get_file_str(opts, {'type': 'REG', 'id': fdi['cwd_id']})))
-		print("\t%7s: %s" % ('root', get_file_str(opts, {'type': 'REG', 'id': fdi['root_id']})))
-
-
-class vma_id:
-	def __init__(self):
-		self.__ids = {}
-		self.__last = 1
-
-	def get(self, iid):
-		ret = self.__ids.get(iid, None)
-		if not ret:
-			ret = self.__last
-			self.__last += 1
-			self.__ids[iid] = ret
-
-		return ret
-
-def explore_mems(opts):
-	ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
-	vids = vma_id()
-	for p in ps_img['entries']:
-		pid = get_task_id(p, 'pid')
-		mmi = pycriu.images.load(dinf(opts, 'mm-%d.img' % pid))['entries'][0]
-
-		print("%d" % pid)
-		print("\t%-36s    %s" % ('exe', get_file_str(opts, {'type': 'REG', 'id': mmi['exe_file_id']})))
-
-		for vma in mmi['vmas']:
-			st = vma['status']
-			if st & (1 << 10):
-				fn = ' ' + 'ips[%lx]' % vids.get(vma['shmid'])
-			elif st & (1 << 8):
-				fn = ' ' + 'shmem[%lx]' % vids.get(vma['shmid'])
-			elif st & (1 << 11):
-				fn = ' ' + 'packet[%lx]' % vids.get(vma['shmid'])
-			elif st & ((1 << 6) | (1 << 7)):
-				fn = ' ' + get_file_str(opts, {'type': 'REG', 'id': vma['shmid']})
-				if vma['pgoff']:
-					fn += ' + %#lx' % vma['pgoff']
-				if st & (1 << 7):
-					fn += ' (s)'
-			elif st & (1 << 1):
-				fn = ' [stack]'
-			elif st & (1 << 2):
-				fn = ' [vsyscall]'
-			elif st & (1 << 3):
-				fn = ' [vdso]'
-			elif vma['flags'] & 0x0100: # growsdown
-				fn = ' [stack?]'
-			else:
-				fn = ''
-
-			if not st & (1 << 0):
-				fn += ' *'
-
-			prot = vma['prot'] & 0x1 and 'r' or '-'
-			prot += vma['prot'] & 0x2 and 'w' or '-'
-			prot += vma['prot'] & 0x4 and 'x' or '-'
-
-			astr = '%08lx-%08lx' % (vma['start'], vma['end'])
-			print("\t%-36s%s%s" % (astr, prot, fn))
-
-
-def explore_rss(opts):
-	ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
-	for p in ps_img['entries']:
-		pid = get_task_id(p, 'pid')
-		vmas = pycriu.images.load(dinf(opts, 'mm-%d.img' % pid))['entries'][0]['vmas']
-		pms = pycriu.images.load(dinf(opts, 'pagemap-%d.img' % pid))['entries']
-
-		print("%d" % pid)
-		vmi = 0
-		pvmi = -1
-		for pm in pms[1:]:
-			pstr = '\t%lx / %-8d' % (pm['vaddr'], pm['nr_pages'])
-			while vmas[vmi]['end'] <= pm['vaddr']:
-				vmi += 1
-
-			pme = pm['vaddr'] + (pm['nr_pages'] << 12)
-			vstr = ''
-			while vmas[vmi]['start'] < pme:
-				vma = vmas[vmi]
-				if vmi == pvmi:
-					vstr += ' ~'
-				else:
-					vstr += ' %08lx / %-8d' % (vma['start'], (vma['end'] - vma['start'])>>12)
-					if vma['status'] & ((1 << 6) | (1 << 7)):
-						vstr += ' ' + get_file_str(opts, {'type': 'REG', 'id': vma['shmid']})
-					pvmi = vmi
-				vstr += '\n\t%23s' % ''
-				vmi += 1
-
-			vmi -= 1
-
-			print('%-24s%s' % (pstr, vstr))
-
-
-
-explorers = { 'ps': explore_ps, 'fds': explore_fds, 'mems': explore_mems, 'rss': explore_rss }
-
-def explore(opts):
-	explorers[opts['what']](opts)
-
-def main():
-	desc = 'CRiu Image Tool'
-	parser = argparse.ArgumentParser(description=desc,
-			formatter_class=argparse.RawTextHelpFormatter)
-
-	subparsers = parser.add_subparsers(help='Use crit CMD --help for command-specific help')
-
-	# Decode
-	decode_parser = subparsers.add_parser('decode',
-			help = 'convert criu image from binary type to json')
-	decode_parser.add_argument('--pretty',
-			help = 'Multiline with indents and some numerical fields in field-specific format',
-			action = 'store_true')
-	decode_parser.add_argument('-i',
-			    '--in',
-			help = 'criu image in binary format to be decoded (stdin by default)')
-	decode_parser.add_argument('-o',
-			    '--out',
-			help = 'where to put criu image in json format (stdout by default)')
-	decode_parser.set_defaults(func=decode, nopl=False)
-
-	# Encode
-	encode_parser = subparsers.add_parser('encode',
-			help = 'convert criu image from json type to binary')
-	encode_parser.add_argument('-i',
-			    '--in',
-			help = 'criu image in json format to be encoded (stdin by default)')
-	encode_parser.add_argument('-o',
-			    '--out',
-			help = 'where to put criu image in binary format (stdout by default)')
-	encode_parser.set_defaults(func=encode)
-
-	# Info
-	info_parser = subparsers.add_parser('info',
-			help = 'show info about image')
-	info_parser.add_argument("in")
-	info_parser.set_defaults(func=info)
-
-	# Explore
-	x_parser = subparsers.add_parser('x', help = 'explore image dir')
-	x_parser.add_argument('dir')
-	x_parser.add_argument('what', choices = [ 'ps', 'fds', 'mems', 'rss'])
-	x_parser.set_defaults(func=explore)
-
-	# Show
-	show_parser = subparsers.add_parser('show',
-			help = "convert criu image from binary to human-readable json")
-	show_parser.add_argument("in")
-	show_parser.add_argument('--nopl', help = 'do not show entry payload (if exists)', action = 'store_true')
-	show_parser.set_defaults(func=decode, pretty=True, out=None)
-
-	opts = vars(parser.parse_args())
-
-	opts["func"](opts)
-
-if __name__ == '__main__':
-	main()
diff --git a/crit/crit-python2 b/crit/crit-python2
new file mode 100755
index 0000000..b0b7d3c
--- /dev/null
+++ b/crit/crit-python2
@@ -0,0 +1,6 @@ 
+#!/usr/bin/env python2
+
+from pycriu import cli
+
+if __name__ == '__main__':
+	cli.main()
diff --git a/crit/crit-python3 b/crit/crit-python3
new file mode 100755
index 0000000..80467cb
--- /dev/null
+++ b/crit/crit-python3
@@ -0,0 +1,6 @@ 
+#!/usr/bin/env python3
+
+from pycriu import cli
+
+if __name__ == '__main__':
+	cli.main()
diff --git a/lib/py/cli.py b/lib/py/cli.py
new file mode 100755
index 0000000..12597db
--- /dev/null
+++ b/lib/py/cli.py
@@ -0,0 +1,337 @@ 
+from __future__ import print_function
+import argparse
+import sys
+import json
+import os
+
+import pycriu
+
+def inf(opts):
+	if opts['in']:
+		return open(opts['in'], 'rb')
+	else:
+		return sys.stdin
+
+def outf(opts):
+	if opts['out']:
+		return open(opts['out'], 'w+')
+	else:
+		return sys.stdout
+
+def dinf(opts, name):
+	return open(os.path.join(opts['dir'], name))
+
+def decode(opts):
+	indent = None
+
+	try:
+		img = pycriu.images.load(inf(opts), opts['pretty'], opts['nopl'])
+	except pycriu.images.MagicException as exc:
+		print("Unknown magic %#x.\n"\
+				"Maybe you are feeding me an image with "\
+				"raw data(i.e. pages.img)?" % exc.magic, file=sys.stderr)
+		sys.exit(1)
+
+	if opts['pretty']:
+		indent = 4
+
+	f = outf(opts)
+	json.dump(img, f, indent=indent)
+	if f == sys.stdout:
+		f.write("\n")
+
+def encode(opts):
+	img = json.load(inf(opts))
+	pycriu.images.dump(img, outf(opts))
+
+def info(opts):
+	infs = pycriu.images.info(inf(opts))
+	json.dump(infs, sys.stdout, indent = 4)
+	print()
+
+def get_task_id(p, val):
+	return p[val] if val in p else p['ns_' + val][0]
+#
+# Explorers
+#
+
+class ps_item:
+	def __init__(self, p, core):
+		self.pid = get_task_id(p, 'pid')
+		self.ppid = p['ppid']
+		self.p = p
+		self.core = core
+		self.kids = []
+
+def show_ps(p, opts, depth = 0):
+	print("%7d%7d%7d   %s%s" % (p.pid, get_task_id(p.p, 'pgid'), get_task_id(p.p, 'sid'),
+			' ' * (4 * depth), p.core['tc']['comm']))
+	for kid in p.kids:
+		show_ps(kid, opts, depth + 1)
+
+def explore_ps(opts):
+	pss = { }
+	ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
+	for p in ps_img['entries']:
+		core = pycriu.images.load(dinf(opts, 'core-%d.img' % get_task_id(p, 'pid')))
+		ps = ps_item(p, core['entries'][0])
+		pss[ps.pid] = ps
+
+	# Build tree
+	psr = None
+	for pid in pss:
+		p = pss[pid]
+		if p.ppid == 0:
+			psr = p
+			continue
+
+		pp = pss[p.ppid]
+		pp.kids.append(p)
+
+	print("%7s%7s%7s   %s" % ('PID', 'PGID', 'SID', 'COMM'))
+	show_ps(psr, opts)
+
+files_img = None
+
+def ftype_find_in_files(opts, ft, fid):
+	global files_img
+
+	if files_img is None:
+		try:
+			files_img = pycriu.images.load(dinf(opts, "files.img"))['entries']
+		except:
+			files_img = []
+
+	if len(files_img) == 0:
+		return None
+
+	for f in files_img:
+		if f['id'] == fid:
+			return f
+
+	return None
+
+
+def ftype_find_in_image(opts, ft, fid, img):
+	f = ftype_find_in_files(opts, ft, fid)
+	if f:
+		return f[ft['field']]
+
+	if ft['img'] == None:
+		ft['img'] = pycriu.images.load(dinf(opts, img))['entries']
+	for f in ft['img']:
+		if f['id'] == fid:
+			return f
+	return None
+
+def ftype_reg(opts, ft, fid):
+	rf = ftype_find_in_image(opts, ft, fid, 'reg-files.img')
+	return rf and rf['name'] or 'unknown path'
+
+def ftype_pipe(opts, ft, fid):
+	p = ftype_find_in_image(opts, ft, fid, 'pipes.img')
+	return p and 'pipe[%d]' % p['pipe_id'] or 'pipe[?]'
+
+def ftype_unix(opts, ft, fid):
+	ux = ftype_find_in_image(opts, ft, fid, 'unixsk.img')
+	if not ux:
+		return 'unix[?]'
+
+	n = ux['name'] and ' %s' % ux['name'] or ''
+	return 'unix[%d (%d)%s]' % (ux['ino'], ux['peer'], n)
+
+file_types = {
+	'REG':		{'get': ftype_reg,	'img': None,	'field': 'reg'},
+	'PIPE':		{'get': ftype_pipe,	'img': None,	'field': 'pipe'},
+	'UNIXSK':	{'get': ftype_unix,	'img': None,	'field': 'usk'},
+}
+
+def ftype_gen(opts, ft, fid):
+	return '%s.%d' % (ft['typ'], fid)
+
+files_cache = { }
+
+def get_file_str(opts, fd):
+	key = (fd['type'], fd['id'])
+	f = files_cache.get(key, None)
+	if not f:
+		ft = file_types.get(fd['type'], {'get': ftype_gen, 'typ': fd['type']})
+		f = ft['get'](opts, ft, fd['id'])
+		files_cache[key] = f
+
+	return f
+
+def explore_fds(opts):
+	ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
+	for p in ps_img['entries']:
+		pid = get_task_id(p, 'pid')
+		idi = pycriu.images.load(dinf(opts, 'ids-%s.img' % pid))
+		fdt = idi['entries'][0]['files_id']
+		fdi = pycriu.images.load(dinf(opts, 'fdinfo-%d.img' % fdt))
+
+		print("%d" % pid)
+		for fd in fdi['entries']:
+			print("\t%7d: %s" % (fd['fd'], get_file_str(opts, fd)))
+
+		fdi = pycriu.images.load(dinf(opts, 'fs-%d.img' % pid))['entries'][0]
+		print("\t%7s: %s" % ('cwd', get_file_str(opts, {'type': 'REG', 'id': fdi['cwd_id']})))
+		print("\t%7s: %s" % ('root', get_file_str(opts, {'type': 'REG', 'id': fdi['root_id']})))
+
+
+class vma_id:
+	def __init__(self):
+		self.__ids = {}
+		self.__last = 1
+
+	def get(self, iid):
+		ret = self.__ids.get(iid, None)
+		if not ret:
+			ret = self.__last
+			self.__last += 1
+			self.__ids[iid] = ret
+
+		return ret
+
+def explore_mems(opts):
+	ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
+	vids = vma_id()
+	for p in ps_img['entries']:
+		pid = get_task_id(p, 'pid')
+		mmi = pycriu.images.load(dinf(opts, 'mm-%d.img' % pid))['entries'][0]
+
+		print("%d" % pid)
+		print("\t%-36s    %s" % ('exe', get_file_str(opts, {'type': 'REG', 'id': mmi['exe_file_id']})))
+
+		for vma in mmi['vmas']:
+			st = vma['status']
+			if st & (1 << 10):
+				fn = ' ' + 'ips[%lx]' % vids.get(vma['shmid'])
+			elif st & (1 << 8):
+				fn = ' ' + 'shmem[%lx]' % vids.get(vma['shmid'])
+			elif st & (1 << 11):
+				fn = ' ' + 'packet[%lx]' % vids.get(vma['shmid'])
+			elif st & ((1 << 6) | (1 << 7)):
+				fn = ' ' + get_file_str(opts, {'type': 'REG', 'id': vma['shmid']})
+				if vma['pgoff']:
+					fn += ' + %#lx' % vma['pgoff']
+				if st & (1 << 7):
+					fn += ' (s)'
+			elif st & (1 << 1):
+				fn = ' [stack]'
+			elif st & (1 << 2):
+				fn = ' [vsyscall]'
+			elif st & (1 << 3):
+				fn = ' [vdso]'
+			elif vma['flags'] & 0x0100: # growsdown
+				fn = ' [stack?]'
+			else:
+				fn = ''
+
+			if not st & (1 << 0):
+				fn += ' *'
+
+			prot = vma['prot'] & 0x1 and 'r' or '-'
+			prot += vma['prot'] & 0x2 and 'w' or '-'
+			prot += vma['prot'] & 0x4 and 'x' or '-'
+
+			astr = '%08lx-%08lx' % (vma['start'], vma['end'])
+			print("\t%-36s%s%s" % (astr, prot, fn))
+
+
+def explore_rss(opts):
+	ps_img = pycriu.images.load(dinf(opts, 'pstree.img'))
+	for p in ps_img['entries']:
+		pid = get_task_id(p, 'pid')
+		vmas = pycriu.images.load(dinf(opts, 'mm-%d.img' % pid))['entries'][0]['vmas']
+		pms = pycriu.images.load(dinf(opts, 'pagemap-%d.img' % pid))['entries']
+
+		print("%d" % pid)
+		vmi = 0
+		pvmi = -1
+		for pm in pms[1:]:
+			pstr = '\t%lx / %-8d' % (pm['vaddr'], pm['nr_pages'])
+			while vmas[vmi]['end'] <= pm['vaddr']:
+				vmi += 1
+
+			pme = pm['vaddr'] + (pm['nr_pages'] << 12)
+			vstr = ''
+			while vmas[vmi]['start'] < pme:
+				vma = vmas[vmi]
+				if vmi == pvmi:
+					vstr += ' ~'
+				else:
+					vstr += ' %08lx / %-8d' % (vma['start'], (vma['end'] - vma['start'])>>12)
+					if vma['status'] & ((1 << 6) | (1 << 7)):
+						vstr += ' ' + get_file_str(opts, {'type': 'REG', 'id': vma['shmid']})
+					pvmi = vmi
+				vstr += '\n\t%23s' % ''
+				vmi += 1
+
+			vmi -= 1
+
+			print('%-24s%s' % (pstr, vstr))
+
+
+
+explorers = { 'ps': explore_ps, 'fds': explore_fds, 'mems': explore_mems, 'rss': explore_rss }
+
+def explore(opts):
+	explorers[opts['what']](opts)
+
+def main():
+	desc = 'CRiu Image Tool'
+	parser = argparse.ArgumentParser(description=desc,
+			formatter_class=argparse.RawTextHelpFormatter)
+
+	subparsers = parser.add_subparsers(help='Use crit CMD --help for command-specific help')
+
+	# Decode
+	decode_parser = subparsers.add_parser('decode',
+			help = 'convert criu image from binary type to json')
+	decode_parser.add_argument('--pretty',
+			help = 'Multiline with indents and some numerical fields in field-specific format',
+			action = 'store_true')
+	decode_parser.add_argument('-i',
+			    '--in',
+			help = 'criu image in binary format to be decoded (stdin by default)')
+	decode_parser.add_argument('-o',
+			    '--out',
+			help = 'where to put criu image in json format (stdout by default)')
+	decode_parser.set_defaults(func=decode, nopl=False)
+
+	# Encode
+	encode_parser = subparsers.add_parser('encode',
+			help = 'convert criu image from json type to binary')
+	encode_parser.add_argument('-i',
+			    '--in',
+			help = 'criu image in json format to be encoded (stdin by default)')
+	encode_parser.add_argument('-o',
+			    '--out',
+			help = 'where to put criu image in binary format (stdout by default)')
+	encode_parser.set_defaults(func=encode)
+
+	# Info
+	info_parser = subparsers.add_parser('info',
+			help = 'show info about image')
+	info_parser.add_argument("in")
+	info_parser.set_defaults(func=info)
+
+	# Explore
+	x_parser = subparsers.add_parser('x', help = 'explore image dir')
+	x_parser.add_argument('dir')
+	x_parser.add_argument('what', choices = [ 'ps', 'fds', 'mems', 'rss'])
+	x_parser.set_defaults(func=explore)
+
+	# Show
+	show_parser = subparsers.add_parser('show',
+			help = "convert criu image from binary to human-readable json")
+	show_parser.add_argument("in")
+	show_parser.add_argument('--nopl', help = 'do not show entry payload (if exists)', action = 'store_true')
+	show_parser.set_defaults(func=decode, pretty=True, out=None)
+
+	opts = vars(parser.parse_args())
+
+	opts["func"](opts)
+
+if __name__ == '__main__':
+	main()

Comments

Dmitry Safonov May 14, 2018, 3:26 p.m.
2018-05-14 14:07 GMT+01:00 Adrian Reber <adrian@lisas.de>:
> diff --git a/crit/Makefile b/crit/Makefile
> new file mode 100644
> index 0000000..4de7f0c
> --- /dev/null
> +++ b/crit/Makefile
> @@ -0,0 +1,13 @@
> +
> +all-y  += crit
> +
> +crit/crit: crit/crit-$(CRIU_PYTHON)
> +       $(Q) cp $^ $@

Nit: maybe a symbolic link?
Adrian Reber May 15, 2018, 12:48 p.m.
On Mon, May 14, 2018 at 04:26:32PM +0100, Dmitry Safonov wrote:
> 2018-05-14 14:07 GMT+01:00 Adrian Reber <adrian@lisas.de>:
> > diff --git a/crit/Makefile b/crit/Makefile
> > new file mode 100644
> > index 0000000..4de7f0c
> > --- /dev/null
> > +++ b/crit/Makefile
> > @@ -0,0 +1,13 @@
> > +
> > +all-y  += crit
> > +
> > +crit/crit: crit/crit-$(CRIU_PYTHON)
> > +       $(Q) cp $^ $@
> 
> Nit: maybe a symbolic link?

I actually have no preference. So basically whatever Andrei wants ;)

		Adrian