Commit 5e3509ba authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Andrei Vagin

crit: Decode some numbers into strings

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: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent fe974169
...@@ -23,7 +23,7 @@ enum seccomp_mode { ...@@ -23,7 +23,7 @@ enum seccomp_mode {
}; };
message task_core_entry { message task_core_entry {
required uint32 task_state = 1; required uint32 task_state = 1 [(criu).dict = "gen"];
required uint32 exit_code = 2; required uint32 exit_code = 2;
required uint32 personality = 3; required uint32 personality = 3;
......
...@@ -8,6 +8,7 @@ message CRIU_Opts { ...@@ -8,6 +8,7 @@ message CRIU_Opts {
optional string flags = 3; optional string flags = 3;
optional bool dev = 4; // Device major:minor packed optional bool dev = 4; // Device major:minor packed
optional bool odev = 5; // ... in old format optional bool odev = 5; // ... in old format
optional string dict = 6;
} }
extend google.protobuf.FieldOptions { extend google.protobuf.FieldOptions {
......
...@@ -19,10 +19,10 @@ message inet_sk_entry { ...@@ -19,10 +19,10 @@ message inet_sk_entry {
*/ */
required uint32 id = 1; required uint32 id = 1;
required uint32 ino = 2; required uint32 ino = 2;
required uint32 family = 3; required uint32 family = 3 [(criu).dict = "sk"];
required uint32 type = 4; required uint32 type = 4 [(criu).dict = "sk"];
required uint32 proto = 5; required uint32 proto = 5 [(criu).dict = "sk"];
required uint32 state = 6; required uint32 state = 6 [(criu).dict = "sk"];
required uint32 src_port = 7; required uint32 src_port = 7;
required uint32 dst_port = 8; required uint32 dst_port = 8;
required uint32 flags = 9 [(criu).hex = true]; required uint32 flags = 9 [(criu).hex = true];
......
...@@ -24,8 +24,8 @@ message unix_sk_entry { ...@@ -24,8 +24,8 @@ message unix_sk_entry {
*/ */
required uint32 id = 1; required uint32 id = 1;
required uint32 ino = 2; required uint32 ino = 2;
required uint32 type = 3; required uint32 type = 3 [(criu).dict = "sk"];
required uint32 state = 4; required uint32 state = 4 [(criu).dict = "sk"];
required uint32 flags = 5 [(criu).hex = true]; required uint32 flags = 5 [(criu).hex = true];
required uint32 uflags = 6 [(criu).hex = true]; required uint32 uflags = 6 [(criu).hex = true];
required uint32 backlog = 7; required uint32 backlog = 7;
......
...@@ -57,6 +57,9 @@ def _marked_as_dev(field): ...@@ -57,6 +57,9 @@ def _marked_as_dev(field):
def _marked_as_odev(field): def _marked_as_odev(field):
return field.GetOptions().Extensions[opts_pb2.criu].odev return field.GetOptions().Extensions[opts_pb2.criu].odev
def _marked_as_dict(field):
return field.GetOptions().Extensions[opts_pb2.criu].dict
mmap_prot_map = [ mmap_prot_map = [
('PROT_READ', 0x1), ('PROT_READ', 0x1),
('PROT_WRITE', 0x2), ('PROT_WRITE', 0x2),
...@@ -106,6 +109,25 @@ flags_maps = { ...@@ -106,6 +109,25 @@ flags_maps = {
'rfile.flags' : rfile_flags_map, 'rfile.flags' : rfile_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): def map_flags(value, flags_map):
bs = map(lambda x: x[0], filter(lambda x: value & x[1], 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)) value &= ~sum(map(lambda x: x[1], flags_map))
...@@ -168,6 +190,10 @@ def _pb2dict_cast(field, value, pretty = False, is_hex = False): ...@@ -168,6 +190,10 @@ def _pb2dict_cast(field, value, pretty = False, is_hex = False):
else: else:
return map_flags(value, flags_map) 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) return cast(value)
else: else:
raise Exception("Field(%s) has unsupported type %d" % (field.name, field.type)) raise Exception("Field(%s) has unsupported type %d" % (field.name, field.type))
...@@ -225,6 +251,13 @@ def _dict2pb_cast(field, value): ...@@ -225,6 +251,13 @@ def _dict2pb_cast(field, value):
else: else:
return unmap_flags(value, flags_map) 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 # Some int or long fields might be stored as hex
# strings. See _pb2dict_cast. # strings. See _pb2dict_cast.
return cast(value, 0) return cast(value, 0)
......
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