Commit 4ead1592 authored by Pavel Emelyanov's avatar Pavel Emelyanov

crit: Show no payload for image objects

In some images there can be quite a long "payload" -- some
raw data that is represented by base64 encoding. If we want
to explore huge images reading tons of base64 symbols can
be quite time consuming :) E.g. I a 1.5 gigs image with sysv
shmem was sent to me some time ago for investigation %)

So here is the --nopl argument for show action (decode should
produce encode-able image, so payload there is needed) that
just shows the amount of bytes in payload (if any).
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent f77cb858
......@@ -25,7 +25,7 @@ def decode(opts):
indent = None
try:
img = pycriu.images.load(inf(opts), opts['pretty'])
img = pycriu.images.load(inf(opts), opts['pretty'], opts['nopl'])
except pycriu.images.MagicException as exc:
print >>sys.stderr, "Unknown magic %#x.\n"\
"Maybe you are feeding me an image with "\
......@@ -265,6 +265,7 @@ def main():
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())
......
......@@ -79,7 +79,7 @@ class entry_handler:
self.payload = payload
self.extra_handler = extra_handler
def load(self, f, pretty = False):
def load(self, f, pretty = False, no_payload = False):
"""
Convert criu image entries from binary format to dict(json).
Takes a file-like object and returnes a list with entries in
......@@ -101,7 +101,21 @@ class entry_handler:
# Read extra
if self.extra_handler:
entry['extra'] = self.extra_handler.load(f, pb)
if no_payload:
def human_readable(num):
for unit in ['','K','M','G','T','P','E','Z']:
if num < 1024.0:
if int(num) == num:
return "%d%sB" % (num, unit)
else:
return "%.1f%sB" % (num, unit)
num /= 1024.0
return "%.1fYB" % num
pl_size = self.extra_handler.skip(f, pb)
entry['extra'] = '... <%s>' % human_readable(pl_size)
else:
entry['extra'] = self.extra_handler.load(f, pb)
entries.append(entry)
......@@ -167,7 +181,7 @@ class pagemap_handler:
that it has a header of pagemap_head type followed by entries
of pagemap_entry type.
"""
def load(self, f, pretty = False):
def load(self, f, pretty = False, no_payload = False):
entries = []
pb = pagemap_head()
......@@ -223,6 +237,10 @@ class pipes_data_extra_handler:
data = extra.decode('base64')
f.write(data)
def skip(self, f, pload):
f.seek(pload.bytes, os.SEEK_CUR)
return pload.bytes
class sk_queues_extra_handler:
def load(self, f, pload):
size = pload.length
......@@ -233,6 +251,10 @@ class sk_queues_extra_handler:
data = extra.decode('base64')
f.write(data)
def skip(self, f, pload):
f.seek(pload.length, os.SEEK_CUR)
return pload.length
class ghost_file_extra_handler:
def load(self, f, pb):
data = f.read()
......@@ -242,6 +264,11 @@ class ghost_file_extra_handler:
data = extra.decode('base64')
f.write(data)
def skip(self, f, pb):
p = f.tell()
f.seek(0, os.SEEK_END)
return f.tell() - p
class tcp_stream_extra_handler:
def load(self, f, pb):
d = {}
......@@ -261,6 +288,10 @@ class tcp_stream_extra_handler:
f.write(inq)
f.write(outq)
def skip(self, f, pb):
f.seek(0, os.SEEK_END)
return pb.inq_len + pb.outq_len
class ipc_sem_set_handler:
def load(self, f, pb):
entry = pb2dict.pb2dict(pb)
......@@ -286,6 +317,12 @@ class ipc_sem_set_handler:
f.write(s.tostring())
f.write('\0' * (rounded - size))
def skip(self, f, pb):
entry = pb2dict.pb2dict(pb)
size = sizeof_u16 * entry['nsems']
f.seek(round_up(size, sizeof_u64), os.SEEK_CUR)
return size
class ipc_msg_queue_handler:
def load(self, f, pb):
entry = pb2dict.pb2dict(pb)
......@@ -318,6 +355,22 @@ class ipc_msg_queue_handler:
f.write(data[:msg.msize])
f.write('\0' * (rounded - msg.msize))
def skip(self, f, pb):
entry = pb2dict.pb2dict(pb)
pl_len = 0
for x in range (0, entry['qnum']):
buf = f.read(4)
if buf == '':
break
size, = struct.unpack('i', buf)
msg = ipc_msg()
msg.ParseFromString(f.read(size))
rounded = round_up(msg.msize, sizeof_u64)
f.seek(rounded, os.SEEK_CUR)
pl_len += size + msg.msize
return pl_len
class ipc_shm_handler:
def load(self, f, pb):
entry = pb2dict.pb2dict(pb)
......@@ -335,6 +388,14 @@ class ipc_shm_handler:
f.write(data[:size])
f.write('\0' * (rounded - size))
def skip(self, f, pb):
entry = pb2dict.pb2dict(pb)
size = entry['size']
rounded = round_up(size, sizeof_u32)
f.seek(rounded, os.SEEK_CUR)
return size
handlers = {
'INVENTORY' : entry_handler(inventory_entry),
'CORE' : entry_handler(core_entry),
......@@ -412,7 +473,7 @@ def __rhandler(f):
return m, handler
def load(f, pretty = False):
def load(f, pretty = False, no_payload = False):
"""
Convert criu image from binary format to dict(json).
Takes a file-like object to read criu image from.
......@@ -423,7 +484,7 @@ def load(f, pretty = False):
m, handler = __rhandler(f)
image['magic'] = m
image['entries'] = handler.load(f, pretty)
image['entries'] = handler.load(f, pretty, no_payload)
return image
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment