[CRIU] [PATCH 3/4] crit: Add support for chunked ghost images

Pavel Emelyanov xemul at virtuozzo.com
Thu Jun 15 19:04:46 MSK 2017


Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 lib/py/images/images.py | 80 ++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 66 insertions(+), 14 deletions(-)

diff --git a/lib/py/images/images.py b/lib/py/images/images.py
index 0f3e8b3..80ed4b7 100644
--- a/lib/py/images/images.py
+++ b/lib/py/images/images.py
@@ -220,6 +220,71 @@ class pagemap_handler:
 	def count(self, f):
 		return entry_handler(None).count(f) - 1
 
+# Special handler for ghost-file.img
+class ghost_file_handler:
+	def load(self, f, pretty = False, no_payload = False):
+		entries = []
+
+		gf = ghost_file_entry()
+		buf = f.read(4)
+		size, = struct.unpack('i', buf)
+		gf.ParseFromString(f.read(size))
+		g_entry = pb2dict.pb2dict(gf, pretty)
+
+		if gf.chunks:
+			entries.append(g_entry)
+			while True:
+				gc = ghost_chunk_entry()
+				buf = f.read(4)
+				if buf == '':
+					break
+				size, = struct.unpack('i', buf)
+				gc.ParseFromString(f.read(size))
+				entry = pb2dict.pb2dict(gc, pretty)
+				if no_payload:
+					f.seek(gc.len, os.SEEK_CUR)
+				else:
+					entry['extra'] = f.read(gc.len).encode('base64')
+				entries.append(entry)
+		else:
+			if no_payload:
+				f.seek(0, os.SEEK_END)
+			else:
+				g_entry['extra'] = f.read().encode('base64')
+			entries.append(g_entry)
+
+		return entries
+
+	def loads(self, s, pretty = False):
+		f = io.BytesIO(s)
+		return self.load(f, pretty)
+
+	def dump(self, entries, f):
+		pb = ghost_file_entry()
+		item = entries.pop(0)
+		pb2dict.dict2pb(item, pb)
+		pb_str = pb.SerializeToString()
+		size = len(pb_str)
+		f.write(struct.pack('i', size))
+		f.write(pb_str)
+
+		if pb.chunks:
+			for item in entries:
+				pb = ghost_chunk_entry()
+				pb2dict.dict2pb(item, pb)
+				pb_str = pb.SerializeToString()
+				size = len(pb_str)
+				f.write(struct.pack('i', size))
+				f.write(pb_str)
+				f.write(item['extra'].decode('base64'))
+		else:
+			f.write(item['extra'].decode('base64'))
+
+	def dumps(self, entries):
+		f = io.BytesIO('')
+		self.dump(entries, f)
+		return f.read()
+
 
 # In following extra handlers we use base64 encoding
 # to store binary data. Even though, the nature
@@ -255,19 +320,6 @@ class sk_queues_extra_handler:
 		f.seek(pload.length, os.SEEK_CUR)
 		return pload.length
 
-class ghost_file_extra_handler:
-	def load(self, f, pb):
-		data = f.read()
-		return data.encode('base64')
-
-	def dump(self, extra, f, pb):
-		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):
@@ -404,7 +456,7 @@ handlers = {
 	'UTSNS'			: entry_handler(utsns_entry),
 	'IPC_VAR'		: entry_handler(ipc_var_entry),
 	'FS'			: entry_handler(fs_entry),
-	'GHOST_FILE'		: entry_handler(ghost_file_entry, ghost_file_extra_handler()),
+	'GHOST_FILE'		: ghost_file_handler(),
 	'MM'			: entry_handler(mm_entry),
 	'CGROUP'		: entry_handler(cgroup_entry),
 	'TCP_STREAM'		: entry_handler(tcp_stream_entry, tcp_stream_extra_handler()),
-- 
2.1.4



More information about the CRIU mailing list