[CRIU] [PATCH] p.haul: workaround bug in tarfile library
Nikita Spiridonov
nspiridonov at odin.com
Mon Nov 16 09:01:55 PST 2015
Workaround tarfile library bug that leads to ownerless garbage
zero blocks in socket when tarfile constructed with socket as
file object to transfer tarballs over network.
Since memory socket used for both images copying to destination
and passing to criu for memory migration this bug affect criu
swrk process which read that zeroes left from tarfile library
and hang.
To workaround current problem receive all remaining data from
memory socket after tarfile object closed and discard it.
In future we can replace tarfile with some better library (current
case not the first workaround needed for tarfile to work correctly)
or implement images tranfer in criu.
Signed-off-by: Nikita Spiridonov <nspiridonov at odin.com>
---
phaul/images.py | 2 ++
phaul/util.py | 16 ++++++++++++++++
2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/phaul/images.py b/phaul/images.py
index a67b569..1b004d6 100644
--- a/phaul/images.py
+++ b/phaul/images.py
@@ -44,6 +44,8 @@ class untar_thread(threading.Thread):
tf = tarfile.open(mode="r|", fileobj=util.fileobj_wrap(self.__sk))
tf.extractall(self.__dir)
tf.close()
+ # Discard all remaining data in socket after tarfile closed
+ util.discard_sk_input(self.__sk)
except:
logging.exception("Exception in untar_thread")
diff --git a/phaul/util.py b/phaul/util.py
index bb9a8ac..00824d5 100644
--- a/phaul/util.py
+++ b/phaul/util.py
@@ -2,6 +2,7 @@ import os
import fcntl
import errno
import logging
+import socket
class fileobj_wrap:
@@ -23,6 +24,21 @@ class fileobj_wrap:
self.__sk.send(str)
+def discard_sk_input(sk):
+ """Read all data from socket and discard it
+
+ Current helper function needed to workaround tarfile library bug that
+ leads to ownerless garbage zero blocks in socket when tarfile constructed
+ with socket as file object to transfer tarballs over network.
+ """
+ try:
+ while True:
+ sk.recv(0x10000, socket.MSG_DONTWAIT)
+ except socket.error as e:
+ if e.errno != errno.EWOULDBLOCK:
+ raise e
+
+
class net_dev:
def __init__(self, name=None, pair=None, link=None):
self.name = name
--
1.7.1
More information about the CRIU
mailing list