[CRIU] [PATCH 1/2] crit: Decode some numbers into strings

Pavel Emelyanov xemul at virtuozzo.com
Mon Apr 10 04:02:00 PDT 2017


There are several places in image files, where we store
integers, but these numbers actually mean some string.
E.g. socket families, states and types and tasks states.

So here's the (criu).dict option for such fields that
helps to convert the numbers into strings and back.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>

---
 images/core.proto        |  2 +-
 images/opts.proto        |  1 +
 images/sk-inet.proto     |  8 ++++----
 images/sk-unix.proto     |  4 ++--
 lib/py/images/pb2dict.py | 33 +++++++++++++++++++++++++++++++++
 5 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/images/core.proto b/images/core.proto
index 14f13f8..9c2254d 100644
--- a/images/core.proto
+++ b/images/core.proto
@@ -23,7 +23,7 @@ enum seccomp_mode {
 };
 
 message task_core_entry {
-	required uint32			task_state	= 1;
+	required uint32			task_state	= 1 [(criu).dict = "gen"];
 	required uint32			exit_code	= 2;
 
 	required uint32			personality	= 3;
diff --git a/images/opts.proto b/images/opts.proto
index 380d54a..a2cdd75 100644
--- a/images/opts.proto
+++ b/images/opts.proto
@@ -8,6 +8,7 @@ message CRIU_Opts {
 	optional string flags = 3;
 	optional bool dev = 4; // Device major:minor packed
 	optional bool odev = 5; // ... in old format
+	optional string dict = 6;
 }
 
 extend google.protobuf.FieldOptions {
diff --git a/images/sk-inet.proto b/images/sk-inet.proto
index b03d1fc..cb8245c 100644
--- a/images/sk-inet.proto
+++ b/images/sk-inet.proto
@@ -22,10 +22,10 @@ message inet_sk_entry {
 	 */
 	required uint32			id		=  1;
 	required uint32			ino		=  2;
-	required uint32			family		=  3;
-	required uint32			type		=  4;
-	required uint32			proto		=  5;
-	required uint32			state		=  6;
+	required uint32			family		=  3 [(criu).dict = "sk"];
+	required uint32			type		=  4 [(criu).dict = "sk"];
+	required uint32			proto		=  5 [(criu).dict = "sk"];
+	required uint32			state		=  6 [(criu).dict = "sk"];
 	required uint32			src_port	=  7;
 	required uint32			dst_port	=  8;
 	required uint32			flags		=  9 [(criu).hex = true];
diff --git a/images/sk-unix.proto b/images/sk-unix.proto
index d695070..c9cdc10 100644
--- a/images/sk-unix.proto
+++ b/images/sk-unix.proto
@@ -24,8 +24,8 @@ message unix_sk_entry {
 	 */
 	required uint32			id		=  1;
 	required uint32			ino		=  2;
-	required uint32			type		=  3;
-	required uint32			state		=  4;
+	required uint32			type		=  3 [(criu).dict = "sk"];
+	required uint32			state		=  4 [(criu).dict = "sk"];
 	required uint32			flags		=  5 [(criu).hex = true];
 	required uint32			uflags		=  6 [(criu).hex = true];
 	required uint32			backlog		=  7;
diff --git a/lib/py/images/pb2dict.py b/lib/py/images/pb2dict.py
index 769b63b..89aa423 100644
--- a/lib/py/images/pb2dict.py
+++ b/lib/py/images/pb2dict.py
@@ -57,6 +57,9 @@ def _marked_as_dev(field):
 def _marked_as_odev(field):
 	return field.GetOptions().Extensions[opts_pb2.criu].odev
 
+def _marked_as_dict(field):
+	return field.GetOptions().Extensions[opts_pb2.criu].dict
+
 mmap_prot_map = [
 	('PROT_READ',	0x1),
 	('PROT_WRITE',	0x2),
@@ -113,6 +116,25 @@ flags_maps = {
 	'pmap.flags' : pmap_flags_map,
 }
 
+gen_maps = {
+	'task_state' : { 1: 'Alive', 3: 'Zombie', 6: 'Stopped' },
+}
+
+sk_maps = {
+	'family'    : { 2: 'INET' },
+	'type'      : { 1: 'STREAM', 2: 'DGRAM' },
+	'state'     : { 1: 'ESTABLISHED', 7: 'CLOSE', 10: 'LISTEN' },
+	'proto'     : { 6: 'TCP' },
+}
+
+gen_rmaps = { k: {v2:k2 for k2,v2 in v.items()} for k,v in gen_maps.items() }
+sk_rmaps = { k: {v2:k2 for k2,v2 in v.items()} for k,v in sk_maps.items() }
+
+dict_maps = {
+	'gen' : ( gen_maps, gen_rmaps ),
+	'sk'  : ( sk_maps, sk_rmaps ),
+}
+
 def map_flags(value, flags_map):
 	bs = map(lambda x: x[0], filter(lambda x: value & x[1], flags_map))
 	value &= ~sum(map(lambda x: x[1], flags_map))
@@ -175,6 +197,10 @@ def _pb2dict_cast(field, value, pretty = False, is_hex = False):
 				else:
 					return map_flags(value, flags_map)
 
+			dct = _marked_as_dict(field)
+			if dct:
+				return dict_maps[dct][0][field.name].get(value, cast(value))
+
 		return cast(value)
 	else:
 		raise Exception("Field(%s) has unsupported type %d" % (field.name, field.type))
@@ -232,6 +258,13 @@ def _dict2pb_cast(field, value):
 				else:
 					return unmap_flags(value, flags_map)
 
+			dct = _marked_as_dict(field)
+			if dct:
+				ret = dict_maps[dct][1][field.name].get(value, None)
+				if ret == None:
+					ret = cast(value, 0)
+				return ret
+
 			# Some int or long fields might be stored as hex
 			# strings. See _pb2dict_cast.
 			return cast(value, 0)
-- 
2.5.5


More information about the CRIU mailing list