[CRIU] [PATCH 2/2] crit: Beautify unix names recode

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


Unix socket name can be a string with any bytes in it. So to
print the name we use base64 encoding. Doing so doesn't allow
to see the socket name when it contains only printable chars.

So here's the custom encoding for bytes fields, that can be
used for custom conversion.

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

---
 images/opts.proto        |  1 +
 images/sk-unix.proto     |  2 +-
 lib/py/images/pb2dict.py | 34 ++++++++++++++++++++++++++++++++--
 3 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/images/opts.proto b/images/opts.proto
index a2cdd75..70c7fd4 100644
--- a/images/opts.proto
+++ b/images/opts.proto
@@ -9,6 +9,7 @@ message CRIU_Opts {
 	optional bool dev = 4; // Device major:minor packed
 	optional bool odev = 5; // ... in old format
 	optional string dict = 6;
+	optional string conv = 7;
 }
 
 extend google.protobuf.FieldOptions {
diff --git a/images/sk-unix.proto b/images/sk-unix.proto
index c9cdc10..2a33fe2 100644
--- a/images/sk-unix.proto
+++ b/images/sk-unix.proto
@@ -37,7 +37,7 @@ message unix_sk_entry {
 	 * Abstract name may contain \0 at any point,
 	 * so we need to carry it as byte sequence...
 	 */
-	required bytes			name		= 11;
+	required bytes			name		= 11 [(criu).conv = "unix_name"];
 
 	optional sk_shutdown		shutdown	= 12;
 
diff --git a/lib/py/images/pb2dict.py b/lib/py/images/pb2dict.py
index 89aa423..bf05278 100644
--- a/lib/py/images/pb2dict.py
+++ b/lib/py/images/pb2dict.py
@@ -60,6 +60,9 @@ def _marked_as_odev(field):
 def _marked_as_dict(field):
 	return field.GetOptions().Extensions[opts_pb2.criu].dict
 
+def _custom_conv(field):
+	return field.GetOptions().Extensions[opts_pb2.criu].conv
+
 mmap_prot_map = [
 	('PROT_READ',	0x1),
 	('PROT_WRITE',	0x2),
@@ -164,6 +167,33 @@ def encode_dev(field, value):
 	else:
 		return dev[0] << kern_minorbits | dev[1]
 
+def encode_base64(value):
+	return value.encode('base64')
+def decode_base64(value):
+	return value.decode('base64')
+
+def encode_unix(value):
+	return value.encode('quopri')
+def decode_unix(value):
+	return value.decode('quopri')
+
+encode = { 'unix_name': encode_unix }
+decode = { 'unix_name': decode_unix }
+
+def get_bytes_enc(field):
+	c = _custom_conv(field)
+	if c:
+		return encode[c]
+	else:
+		return encode_base64
+
+def get_bytes_dec(field):
+	c = _custom_conv(field)
+	if c:
+		return decode[c]
+	else:
+		return decode_base64
+
 def is_string(value):
 	return isinstance(value, unicode) or isinstance(value, str)
 
@@ -174,7 +204,7 @@ def _pb2dict_cast(field, value, pretty = False, is_hex = False):
 	if field.type == FD.TYPE_MESSAGE:
 		return pb2dict(value, pretty, is_hex)
 	elif field.type == FD.TYPE_BYTES:
-		return value.encode('base64')
+		return get_bytes_enc(field)(value)
 	elif field.type == FD.TYPE_ENUM:
 		return field.enum_type.values_by_number.get(value, None).name
 	elif field.type in _basic_cast:
@@ -240,7 +270,7 @@ def _dict2pb_cast(field, value):
 	# and non-repeated messages need special treatment
 	# in this case, and are hadled separately.
 	if field.type == FD.TYPE_BYTES:
-		return value.decode('base64')
+		return get_bytes_dec(field)(value)
 	elif field.type == FD.TYPE_ENUM:
 		return field.enum_type.values_by_name.get(value, None).number
 	elif field.type in _basic_cast:
-- 
2.5.5



More information about the CRIU mailing list