[CRIU] [PATCH 3/4] p.haul: change --fdfs argument semantics to handle multiple disks
Nikita Spiridonov
nspiridonov at odin.com
Thu Dec 10 02:12:04 PST 2015
change --fdfs argument semantics to handle multiple disks. Now for
Virtuozzo module --fdfs option accept list of active ploop deltas
with corresponding sockets in format
%delta_path1%:%socket_fd1%[,...].
Not sure if we have to rename --fdfs options to something like
--fschannel or preserve old name for uniformity
(--fdrpc/--fdmem/--fdfs). Preserve old name for now.
Signed-off-by: Nikita Spiridonov <nspiridonov at odin.com>
---
p.haul | 6 +++---
phaul/args_parser.py | 5 +++--
phaul/connection.py | 18 +++++++++---------
phaul/iters.py | 2 +-
phaul/p_haul_docker.py | 4 ++--
phaul/p_haul_lxc.py | 4 ++--
phaul/p_haul_pid.py | 4 ++--
phaul/p_haul_vz.py | 43 +++++++++++++++++++++++++++++++++++++++----
phaul/service.py | 9 ++++-----
9 files changed, 65 insertions(+), 30 deletions(-)
diff --git a/p.haul b/p.haul
index b56fb5c..b6fb234 100755
--- a/p.haul
+++ b/p.haul
@@ -7,7 +7,7 @@ import phaul.iters
import phaul.connection
# Usage idea
-# p.haul <type> <id> --fdrpc <fd> --fdmem <fd> --fdfs <fd>
+# p.haul <type> <id> --fdrpc <fd> --fdmem <fd>
#
# p.haul work over existing connections specified via command line arguments
# as file descriptors. Three arguments required - --fdrpc for rpc calls,
@@ -16,8 +16,8 @@ import phaul.connection
# connections with target host and call p.haul or p.haul-service.
#
# E.g.
-# p.haul vz 100 --fdrpc 3 --fdmem 4 --fdfs 5
-# p.haul lxc myct --fdrpc 3 --fdmem 4 --fdfs 5
+# p.haul vz 100 --fdrpc 3 --fdmem 4 --fdfs root.hdd/root.hds:5
+# p.haul lxc myct --fdrpc 3 --fdmem 4
#
diff --git a/phaul/args_parser.py b/phaul/args_parser.py
index 8e519b4..a98b64f 100644
--- a/phaul/args_parser.py
+++ b/phaul/args_parser.py
@@ -22,7 +22,7 @@ def parse_client_args():
parser.add_argument("--to", help="IP where to haul")
parser.add_argument("--fdrpc", type=int, required=True, help="File descriptor of rpc socket")
parser.add_argument("--fdmem", type=int, required=True, help="File descriptor of memory socket")
- parser.add_argument("--fdfs", type=int, required=True, help="File descriptor of fs socket")
+ parser.add_argument("--fdfs", help="Module specific definition of fs channel")
parser.add_argument("-v", default=criu_api.def_verb, type=int, dest="verbose", help="Verbosity level")
parser.add_argument("--keep-images", default=False, action='store_true', help="Keep images after migration")
parser.add_argument("--dst-rpid", default=None, help="Write pidfile on restore")
@@ -52,7 +52,8 @@ def parse_service_args():
parser.add_argument("--fdrpc", type=int, required=True, help="File descriptor of rpc socket")
parser.add_argument("--fdmem", type=int, required=True, help="File descriptor of memory socket")
- parser.add_argument("--fdfs", type=int, required=True, help="File descriptor of fs socket")
+ parser.add_argument("--fdfs", help="Module specific definition of fs channel")
+
parser.add_argument("--log-file", help="Write logging messages to specified file")
return parser.parse_args()
diff --git a/phaul/connection.py b/phaul/connection.py
index 33da9fd..7838bc3 100644
--- a/phaul/connection.py
+++ b/phaul/connection.py
@@ -13,18 +13,17 @@ class connection:
Class encapsulate connections reqired for p.haul work, including rpc socket
(socket for RPC calls), memory socket (socket for c/r images migration) and
- fs socket (socket for disk migration).
+ module specific definition of fs channel needed for disk migration.
"""
- def __init__(self, rpc_sk, mem_sk, fs_sk):
+ def __init__(self, rpc_sk, mem_sk, fdfs):
self.rpc_sk = rpc_sk
self.mem_sk = mem_sk
- self.fs_sk = fs_sk
+ self.fdfs = fdfs
def close(self):
self.rpc_sk.close()
self.mem_sk.close()
- self.fs_sk.close()
def establish(fdrpc, fdmem, fdfs):
@@ -34,13 +33,14 @@ def establish(fdrpc, fdmem, fdfs):
with domain AF_INET and type SOCK_STREAM.
"""
- logging.info("Use existing connections, fdrpc=%d fdmem=%d fdfs=%d", fdrpc,
+ logging.info("Use existing connections, fdrpc=%d fdmem=%d fdfs=%s", fdrpc,
fdmem, fdfs)
+ # Create rpc socket
rpc_sk = socket.fromfd(fdrpc, socket.AF_INET, socket.SOCK_STREAM)
- mem_sk = socket.fromfd(fdmem, socket.AF_INET, socket.SOCK_STREAM)
- fs_sk = socket.fromfd(fdfs, socket.AF_INET, socket.SOCK_STREAM)
-
util.set_cloexec(rpc_sk)
- return connection(rpc_sk, mem_sk, fs_sk)
+ # Create memory socket
+ mem_sk = socket.fromfd(fdmem, socket.AF_INET, socket.SOCK_STREAM)
+
+ return connection(rpc_sk, mem_sk, fdfs)
diff --git a/phaul/iters.py b/phaul/iters.py
index 8728e7e..89a7841 100644
--- a/phaul/iters.py
+++ b/phaul/iters.py
@@ -40,7 +40,7 @@ class phaul_iter_worker:
if not self.htype:
raise Exception("No htype driver found")
- self.fs = self.htype.get_fs(self.connection.fs_sk)
+ self.fs = self.htype.get_fs(self.connection.fdfs)
if not self.fs:
raise Exception("No FS driver found")
diff --git a/phaul/p_haul_docker.py b/phaul/p_haul_docker.py
index 81e7533..e957103 100644
--- a/phaul/p_haul_docker.py
+++ b/phaul/p_haul_docker.py
@@ -66,11 +66,11 @@ class p_haul_type:
def umount(self):
pass
- def get_fs(self, fs_sk=None):
+ def get_fs(self, fdfs=None):
# use rsync for rootfs and configuration directories
return fs_haul_subtree.p_haul_fs([self._ct_rootfs, self._ct_config_dir])
- def get_fs_receiver(self, fs_sk=None):
+ def get_fs_receiver(self, fdfs=None):
return None
def get_full_ctid(self):
diff --git a/phaul/p_haul_lxc.py b/phaul/p_haul_lxc.py
index 5e1fe7b..4b3d789 100644
--- a/phaul/p_haul_lxc.py
+++ b/phaul/p_haul_lxc.py
@@ -133,10 +133,10 @@ class p_haul_type:
self._fs_mounted = True
return nroot
- def get_fs(self, fs_sk=None):
+ def get_fs(self, fdfs=None):
return fs_haul_shared.p_haul_fs()
- def get_fs_receiver(self, fs_sk=None):
+ def get_fs_receiver(self, fdfs=None):
return None
def restored(self, pid):
diff --git a/phaul/p_haul_pid.py b/phaul/p_haul_pid.py
index a53d594..75dfd26 100644
--- a/phaul/p_haul_pid.py
+++ b/phaul/p_haul_pid.py
@@ -46,10 +46,10 @@ class p_haul_type:
pass
# Get driver for FS migration
- def get_fs(self, fs_sk=None):
+ def get_fs(self, fdfs=None):
return fs_haul_shared.p_haul_fs()
- def get_fs_receiver(self, fs_sk=None):
+ def get_fs_receiver(self, fdfs=None):
return None
# Get list of files which should be copied to
diff --git a/phaul/p_haul_vz.py b/phaul/p_haul_vz.py
index db13f2d..85c8857 100644
--- a/phaul/p_haul_vz.py
+++ b/phaul/p_haul_vz.py
@@ -188,14 +188,49 @@ class p_haul_type:
logging.info(proc_output)
self._fs_mounted = False
- def get_fs(self, fs_sk=None):
- deltas = [(os.path.join(self._ct_priv, "root.hdd", "root.hds"), fs_sk)]
+ def get_fs(self, fdfs=None):
+ deltas = self.__parse_fdfs_arg(fdfs)
return fs_haul_ploop.p_haul_fs(deltas)
- def get_fs_receiver(self, fs_sk=None):
- deltas = [(os.path.join(self._ct_priv, "root.hdd", "root.hds"), fs_sk)]
+ def get_fs_receiver(self, fdfs=None):
+ deltas = self.__parse_fdfs_arg(fdfs)
return fs_haul_ploop.p_haul_fs_receiver(deltas)
+ def __parse_fdfs_arg(self, fdfs):
+ """
+ Parse string containing list of ploop deltas with socket fds
+
+ String contain list of active ploop deltas with corresponding socket
+ file descriptors in format %delta_path1%:%socket_fd1%[,...]. Parse it
+ and return list of tuples.
+ """
+
+ FDFS_DELTAS_SEPARATOR = ","
+ FDFS_PAIR_SEPARATOR = ":"
+
+ if not fdfs:
+ return []
+
+ deltas = []
+ for delta in fdfs.split(FDFS_DELTAS_SEPARATOR):
+ path, dummy, fd = delta.rpartition(FDFS_PAIR_SEPARATOR)
+ deltas.append((self.__get_ploop_delta_abspath(path), int(fd)))
+
+ return deltas
+
+ def __get_ploop_delta_abspath(self, delta_path):
+ """
+ Transform delta path to absolute form
+
+ If delta path starts with a slash it is already in absolute form,
+ otherwise it is relative to containers private.
+ """
+
+ if delta_path.startswith("/"):
+ return delta_path
+ else:
+ return os.path.join(self._ct_priv, delta_path)
+
def restored(self, pid):
pass
diff --git a/phaul/service.py b/phaul/service.py
index 577278e..5a3a380 100644
--- a/phaul/service.py
+++ b/phaul/service.py
@@ -11,9 +11,8 @@ import htype
class phaul_service:
def __init__(self, connection):
+ self.connection = connection
self.criu_connection = None
- self._mem_sk = connection.mem_sk
- self._fs_sk = connection.fs_sk
self.img = None
self.htype = None
self.__fs_receiver = None
@@ -45,11 +44,11 @@ class phaul_service:
logging.info("Setting up service side %s", htype_id)
self.img = images.phaul_images("rst")
- self.criu_connection = criu_api.criu_conn(self._mem_sk)
+ self.criu_connection = criu_api.criu_conn(self.connection.mem_sk)
self.htype = htype.get_dst(htype_id)
# Create and start fs receiver if current p.haul module provide it
- self.__fs_receiver = self.htype.get_fs_receiver(self._fs_sk)
+ self.__fs_receiver = self.htype.get_fs_receiver(self.connection.fdfs)
if self.__fs_receiver:
self.__fs_receiver.start_receive()
@@ -79,7 +78,7 @@ class phaul_service:
pass
def rpc_start_accept_images(self, dir_id):
- self.img.start_accept_images(dir_id, self._mem_sk)
+ self.img.start_accept_images(dir_id, self.connection.mem_sk)
def rpc_stop_accept_images(self):
self.img.stop_accept_images()
--
1.7.1
More information about the CRIU
mailing list