2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-22 18:07:57 +00:00

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: Pavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
Pavel Emelyanov 2017-04-10 14:02:00 +03:00 committed by Andrei Vagin
parent fe974169a5
commit 5e3509ba16
5 changed files with 41 additions and 7 deletions

View File

@ -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;

View File

@ -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 {

View File

@ -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];

View File

@ -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;

View File

@ -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 = {
'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):
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):
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)