diff --git a/protobuf/fh.proto b/protobuf/fh.proto index eb73d66cf..bda17c943 100644 --- a/protobuf/fh.proto +++ b/protobuf/fh.proto @@ -1,3 +1,5 @@ +import "opts.proto"; + enum fh_entry_sizes { min_entries = 16; } @@ -13,7 +15,7 @@ message fh_entry { } message irmap_cache_entry { - required uint32 dev = 1; + required uint32 dev = 1 [(criu).dev = true, (criu).odev = true]; required uint64 inode = 2; required string path = 3; } diff --git a/protobuf/fsnotify.proto b/protobuf/fsnotify.proto index f0835603b..fbe724cb3 100644 --- a/protobuf/fsnotify.proto +++ b/protobuf/fsnotify.proto @@ -7,7 +7,7 @@ message inotify_wd_entry { required uint64 i_ino = 2; required uint32 mask = 3 [(criu).hex = true]; required uint32 ignored_mask = 4 [(criu).hex = true]; - required uint32 s_dev = 5; + required uint32 s_dev = 5 [(criu).dev = true]; required uint32 wd = 6; required fh_entry f_handle = 7; } @@ -40,7 +40,7 @@ message fanotify_mark_entry { required uint32 mflags = 3 [(criu).hex = true]; required uint32 mask = 4 [(criu).hex = true]; required uint32 ignored_mask = 5 [(criu).hex = true]; - required uint32 s_dev = 6; + required uint32 s_dev = 6 [(criu).dev = true]; optional fanotify_inode_mark_entry ie = 7; optional fanotify_mount_mark_entry me = 8; diff --git a/protobuf/ghost-file.proto b/protobuf/ghost-file.proto index 3bfbbad49..a600a4374 100644 --- a/protobuf/ghost-file.proto +++ b/protobuf/ghost-file.proto @@ -1,9 +1,11 @@ +import "opts.proto"; + message ghost_file_entry { required uint32 uid = 1; required uint32 gid = 2; required uint32 mode = 3; - optional uint32 dev = 4; + optional uint32 dev = 4 [(criu).dev = true]; optional uint64 ino = 5; - optional uint32 rdev = 6; + optional uint32 rdev = 6 [(criu).dev = true, (criu).odev = true]; } diff --git a/protobuf/mnt.proto b/protobuf/mnt.proto index 12582e9d5..390228326 100644 --- a/protobuf/mnt.proto +++ b/protobuf/mnt.proto @@ -24,7 +24,7 @@ enum fstype { message mnt_entry { required uint32 fstype = 1; required uint32 mnt_id = 2; - required uint32 root_dev = 3; + required uint32 root_dev = 3 [(criu).dev = true]; required uint32 parent_mnt_id = 4; required uint32 flags = 5 [(criu).hex = true]; diff --git a/protobuf/opts.proto b/protobuf/opts.proto index 12e4ba497..18ea7b648 100644 --- a/protobuf/opts.proto +++ b/protobuf/opts.proto @@ -4,6 +4,8 @@ message CRIU_Opts { optional bool hex = 1; // Idicate that CRIT should treat this field as hex. optional bool ipadd = 2; // The field is IPv4/v6 address optional string flags = 3; + optional bool dev = 4; // Device major:minor packed + optional bool odev = 5; // ... in old format } extend google.protobuf.FieldOptions { diff --git a/pycriu/images/pb2dict.py b/pycriu/images/pb2dict.py index 4e717f19a..ddd0f9103 100644 --- a/pycriu/images/pb2dict.py +++ b/pycriu/images/pb2dict.py @@ -3,6 +3,7 @@ import opts_pb2 import ipaddr import socket import collections +import os # pb2dict and dict2pb are methods to convert pb to/from dict. # Inspired by: @@ -52,6 +53,12 @@ def _marked_as_ip(field): def _marked_as_flags(field): return field.GetOptions().Extensions[opts_pb2.criu].flags +def _marked_as_dev(field): + return field.GetOptions().Extensions[opts_pb2.criu].dev + +def _marked_as_odev(field): + return field.GetOptions().Extensions[opts_pb2.criu].odev + mmap_prot_map = [ ('PROT_READ', 0x1), ('PROT_WRITE', 0x2), @@ -92,6 +99,21 @@ def unmap_flags(value, flags_map): bd = dict(flags_map) return sum(map(lambda x: int(str(bd.get(x, x)), 0), map(lambda x: x.strip(), value.split('|')))) +kern_minorbits = 20 # This is how kernel encodes dev_t in new format + +def decode_dev(field, value): + if _marked_as_odev(field): + return "%d:%d" % (os.major(value), os.minor(value)) + else: + return "%d:%d" % (value >> kern_minorbits, value & ((1 << kern_minorbits) - 1)) + +def encode_dev(field, value): + dev = map(lambda x: int(x), value.split(':')) + if _marked_as_odev(field): + return os.makedev(dev[0], dev[1]) + else: + return dev[0] << kern_minorbits | dev[1] + def _pb2dict_cast(field, value, pretty = False, is_hex = False): if not is_hex: is_hex = _marked_as_hex(field) @@ -110,6 +132,9 @@ def _pb2dict_cast(field, value, pretty = False, is_hex = False): # should be stored in hex string format. return "0x%x" % value + if _marked_as_dev(field): + return decode_dev(field, value) + flags = _marked_as_flags(field) if flags: try: @@ -164,6 +189,9 @@ def _dict2pb_cast(field, value): elif field.type in _basic_cast: cast = _basic_cast[field.type] if (cast == int or cast == long) and isinstance(value, unicode): + if _marked_as_dev(field): + return encode_dev(field, value) + flags = _marked_as_flags(field) if flags: try: