[CRIU] [PATCH 04/14] [v2] lib: a few fixes to be compatible with python3

Andrei Vagin avagin at virtuozzo.com
Sat Jun 2 00:02:54 MSK 2018


All these issues was found by running test/crit-recode.py

https://github.com/checkpoint-restore/criu/issues/495

v2: drop FD_CLOEXEC for swrk descriptors
Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
 lib/py/criu.py                  |  2 ++
 lib/py/images/images.py         | 41 +++++++++++++++++++++++------------------
 lib/py/images/pb2dict.py        | 24 +++++++++++-------------
 scripts/build/Dockerfile.centos |  1 +
 4 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/lib/py/criu.py b/lib/py/criu.py
index 85c7c07f8..9465eefa2 100644
--- a/lib/py/criu.py
+++ b/lib/py/criu.py
@@ -85,6 +85,8 @@ class _criu_comm_bin(_criu_comm):
 		css = socket.socketpair(socket.AF_UNIX, socket.SOCK_SEQPACKET)
 		flags = fcntl.fcntl(css[1], fcntl.F_GETFD)
 		fcntl.fcntl(css[1], fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
+		flags = fcntl.fcntl(css[0], fcntl.F_GETFD)
+		fcntl.fcntl(css[0], fcntl.F_SETFD, flags & ~fcntl.FD_CLOEXEC)
 
 		self.daemon = daemon
 
diff --git a/lib/py/images/images.py b/lib/py/images/images.py
index 3ad8550b1..d70ee1a42 100644
--- a/lib/py/images/images.py
+++ b/lib/py/images/images.py
@@ -38,6 +38,7 @@
 # }
 #
 import io
+import base64
 import google
 import struct
 import os
@@ -49,6 +50,10 @@ import array
 from . import magic
 from .pb import *
 
+if "encodebytes" not in dir(base64):
+	base64.encodebytes = base64.encodestring
+	base64.decodebytes = base64.decodestring
+
 #
 # Predefined hardcoded constants
 sizeof_u16 = 2
@@ -185,7 +190,7 @@ class pagemap_handler:
 		pb = pagemap_head()
 		while True:
 			buf = f.read(4)
-			if buf == '':
+			if buf == b'':
 				break
 			size, = struct.unpack('i', buf)
 			pb.ParseFromString(f.read(size))
@@ -242,13 +247,13 @@ class ghost_file_handler:
 				if no_payload:
 					f.seek(gc.len, os.SEEK_CUR)
 				else:
-					entry['extra'] = f.read(gc.len).encode('base64')
+					entry['extra'] = base64.encodebytes(f.read(gc.len))
 				entries.append(entry)
 		else:
 			if no_payload:
 				f.seek(0, os.SEEK_END)
 			else:
-				g_entry['extra'] = f.read().encode('base64')
+				g_entry['extra'] = base64.encodebytes(f.read())
 			entries.append(g_entry)
 
 		return entries
@@ -274,9 +279,9 @@ class ghost_file_handler:
 				size = len(pb_str)
 				f.write(struct.pack('i', size))
 				f.write(pb_str)
-				f.write(item['extra'].decode('base64'))
+				f.write(base64.decodebytes(item['extra']))
 		else:
-			f.write(item['extra'].decode('base64'))
+			f.write(base64.decodebytes(item['extra']))
 
 	def dumps(self, entries):
 		f = io.BytesIO('')
@@ -294,10 +299,10 @@ class pipes_data_extra_handler:
 	def load(self, f, pload):
 		size = pload.bytes
 		data = f.read(size)
-		return data.encode('base64')
+		return base64.encodebytes(data)
 
 	def dump(self, extra, f, pload):
-		data = extra.decode('base64')
+		data = base64.decodebytes(extra)
 		f.write(data)
 
 	def skip(self, f, pload):
@@ -308,10 +313,10 @@ class sk_queues_extra_handler:
 	def load(self, f, pload):
 		size = pload.length
 		data = f.read(size)
-		return data.encode('base64')
+		return base64.encodebytes(data)
 
 	def dump(self, extra, f, pb):
-		data = extra.decode('base64')
+		data = base64.decodebytes(extra)
 		f.write(data)
 
 	def skip(self, f, pload):
@@ -326,14 +331,14 @@ class tcp_stream_extra_handler:
 		inq	= f.read(pb.inq_len)
 		outq	= f.read(pb.outq_len)
 
-		d['inq']	= inq.encode('base64')
-		d['outq']	= outq.encode('base64')
+		d['inq']	= base64.encodebytes(inq)
+		d['outq']	= base64.encodebytes(outq)
 
 		return d
 
 	def dump(self, extra, f, pb):
-		inq	= extra['inq'].decode('base64')
-		outq	= extra['outq'].decode('base64')
+		inq	= base64.decodebytes(extra['inq'])
+		outq	= base64.decodebytes(extra['outq'])
 
 		f.write(inq)
 		f.write(outq)
@@ -388,7 +393,7 @@ class ipc_msg_queue_handler:
 			data = f.read(msg.msize)
 			f.seek(rounded - msg.msize, 1)
 			messages.append(pb2dict.pb2dict(msg))
-			messages.append(data.encode('base64'))
+			base64.encodebytes(messages.append(data))
 		return messages
 
 	def dump(self, extra, f, pb):
@@ -401,7 +406,7 @@ class ipc_msg_queue_handler:
 			f.write(struct.pack('i', size))
 			f.write(msg_str)
 			rounded = round_up(msg.msize, sizeof_u64)
-			data = extra[i + 1].decode('base64')
+			data = base64.decodebytes(extra[i + 1])
 			f.write(data[:msg.msize])
 			f.write('\0' * (rounded - msg.msize))
 
@@ -428,12 +433,12 @@ class ipc_shm_handler:
 		data = f.read(size)
 		rounded = round_up(size, sizeof_u32)
 		f.seek(rounded - size, 1)
-		return data.encode('base64')
+		return base64.encodebytes(data)
 
 	def dump(self, extra, f, pb):
 		entry = pb2dict.pb2dict(pb)
 		size = entry['size']
-		data = extra.decode('base64')
+		data = base64.decodebytes(extra)
 		rounded = round_up(size, sizeof_u32)
 		f.write(data[:size])
 		f.write('\0' * (rounded - size))
@@ -589,6 +594,6 @@ def dumps(img):
 	Same as dump(), but takes only an image and returns
 	a string.
 	"""
-	f = io.BytesIO('')
+	f = io.BytesIO(b'')
 	dump(img, f)
 	return f.getvalue()
diff --git a/lib/py/images/pb2dict.py b/lib/py/images/pb2dict.py
index 441dacf61..391bdd5b3 100644
--- a/lib/py/images/pb2dict.py
+++ b/lib/py/images/pb2dict.py
@@ -1,12 +1,10 @@
 from google.protobuf.descriptor import FieldDescriptor as FD
 import opts_pb2
-from builtins import str
-from past.builtins import long
-from ipaddress import IPv4Address
+from ipaddress import IPv4Address, ip_address
 from ipaddress import IPv6Address
 import socket
 import collections
-import os
+import os, six
 
 # pb2dict and dict2pb are methods to convert pb to/from dict.
 # Inspired by:
@@ -27,14 +25,14 @@ import os
 
 
 _basic_cast = {
-	FD.TYPE_FIXED64		: long,
+	FD.TYPE_FIXED64		: int,
 	FD.TYPE_FIXED32		: int,
-	FD.TYPE_SFIXED64	: long,
+	FD.TYPE_SFIXED64	: int,
 	FD.TYPE_SFIXED32	: int,
 
-	FD.TYPE_INT64		: long,
-	FD.TYPE_UINT64		: long,
-	FD.TYPE_SINT64		: long,
+	FD.TYPE_INT64		: int,
+	FD.TYPE_UINT64		: int,
+	FD.TYPE_SINT64		: int,
 
 	FD.TYPE_INT32		: int,
 	FD.TYPE_UINT32		: int,
@@ -229,7 +227,7 @@ def get_bytes_dec(field):
 		return decode_base64
 
 def is_string(value):
-	return isinstance(value, str)
+	return isinstance(value, six.string_types)
 
 def _pb2dict_cast(field, value, pretty = False, is_hex = False):
 	if not is_hex:
@@ -243,7 +241,7 @@ def _pb2dict_cast(field, value, pretty = False, is_hex = False):
 		return field.enum_type.values_by_number.get(value, None).name
 	elif field.type in _basic_cast:
 		cast = _basic_cast[field.type]
-		if pretty and (cast == int or cast == long):
+		if pretty and (cast == int):
 			if is_hex:
 				# Fields that have (criu).hex = true option set
 				# should be stored in hex string format.
@@ -309,7 +307,7 @@ def _dict2pb_cast(field, value):
 		return field.enum_type.values_by_name.get(value, None).number
 	elif field.type in _basic_cast:
 		cast = _basic_cast[field.type]
-		if (cast == int or cast == long) and is_string(value):
+		if (cast == int) and is_string(value):
 			if _marked_as_dev(field):
 				return encode_dev(field, value)
 
@@ -349,7 +347,7 @@ def dict2pb(d, pb):
 		if field.label == FD.LABEL_REPEATED:
 			pb_val = getattr(pb, field.name, None)
 			if is_string(value[0]) and _marked_as_ip(field):
-				val = ipaddr.IPAddress(value[0])
+				val = ip_address(value[0])
 				if val.version == 4:
 					pb_val.append(socket.htonl(int(val)))
 				elif val.version == 6:
diff --git a/scripts/build/Dockerfile.centos b/scripts/build/Dockerfile.centos
index 75f0ed461..379a84596 100644
--- a/scripts/build/Dockerfile.centos
+++ b/scripts/build/Dockerfile.centos
@@ -25,6 +25,7 @@ RUN yum install -y \
 	python-ipaddress \
 	python2-future \
 	python-yaml \
+	python-six \
 	tar \
 	which
 
-- 
2.14.3



More information about the CRIU mailing list