@@ -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
@@ -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:
new file mode 100644
@@ -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
deleted file mode 100755
@@ -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()
new file mode 100755
@@ -0,0 +1,6 @@
+#!/usr/bin/env python2
+
+from pycriu import cli
+
+if __name__ == '__main__':
+ cli.main()
new file mode 100755
@@ -0,0 +1,6 @@
+#!/usr/bin/env python3
+
+from pycriu import cli
+
+if __name__ == '__main__':
+ cli.main()
new file mode 100755
@@ -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()