[CRIU] [PATCH] p.haul: allow specify module-specific criu request options
Nikita Spiridonov
nspiridonov at odin.com
Fri Jun 19 03:06:01 PDT 2015
We have to specify multiple --ext-mount-map options in criu dump
and restore requests during Virtuozzo container migration to make
it work. To make it real add possibility that allow specify
module-specific criu request options.
Now every phaul module (e.g. Virtuozzo or LXC) have method
adjust_criu_req; any module-specific request options can be
specified in this method.
Additionally move all requests-related code to separate methods in
phaul_iter_worker and phaul_service classes to simplify migration
logic.
Signed-off-by: Nikita Spiridonov <nspiridonov at odin.com>
---
phaul/p_haul_iters.py | 95 +++++++++++++++++++++++++++--------------------
phaul/p_haul_lxc.py | 4 ++
phaul/p_haul_pid.py | 4 ++
phaul/p_haul_service.py | 92 +++++++++++++++++++++++++++------------------
phaul/p_haul_vz.py | 26 +++++++++++++
5 files changed, 144 insertions(+), 77 deletions(-)
diff --git a/phaul/p_haul_iters.py b/phaul/p_haul_iters.py
index 7a898da..3a2585a 100644
--- a/phaul/p_haul_iters.py
+++ b/phaul/p_haul_iters.py
@@ -47,28 +47,6 @@ class phaul_iter_worker:
print "Setting up remote"
self.th.setup(p_type)
-
- def make_dump_req(self, typ):
- #
- # Prepare generic request for (pre)dump
- #
-
- req = cr_rpc.criu_req()
- req.type = typ
- req.opts.pid = self.pid
- req.opts.ps.fd = self.criu.mem_sk_fileno()
- req.opts.track_mem = True
-
- req.opts.images_dir_fd = self.img.image_dir_fd()
- req.opts.work_dir_fd = self.img.work_dir_fd()
- p_img = self.img.prev_image_dir()
- if p_img:
- req.opts.parent_img = p_img
- if not self.fs.persistent_inodes():
- req.opts.force_irmap = True
-
- return req
-
def set_options(self, opts):
self.th.set_options(opts)
self.criu.verbose(opts["verbose"])
@@ -80,10 +58,7 @@ class phaul_iter_worker:
print "Checking CPU compatibility"
print " `- Dumping CPU info"
- req = cr_rpc.criu_req()
- req.type = cr_rpc.CPUINFO_DUMP
- req.opts.images_dir_fd = self.img.work_dir_fd()
- req.keep_open = True
+ req = self.__make_cpuinfo_dump_req()
resp = self.criu.send_req(req)
if not resp.success:
raise Exception("Can't dump cpuinfo")
@@ -106,7 +81,6 @@ class phaul_iter_worker:
self.fs.start_migration()
print "Starting iterations"
- cc = self.criu
while True:
print "* Iteration %d" % self.iteration
@@ -116,8 +90,8 @@ class phaul_iter_worker:
print "\tIssuing pre-dump command to service"
- req = self.make_dump_req(cr_rpc.PRE_DUMP)
- resp = cc.send_req(req)
+ req = self.__make_predump_req()
+ resp = self.criu.send_req(req)
if not resp.success:
raise Exception("Pre-dump failed")
@@ -168,15 +142,9 @@ class phaul_iter_worker:
self.img.new_image_dir()
print "\tIssuing dump command to service"
- req = self.make_dump_req(cr_rpc.DUMP)
- req.opts.notify_scripts = True
- req.opts.file_locks = True
- req.opts.evasive_devices = True
- req.opts.link_remap = True
- if self.htype.can_migrate_tcp():
- req.opts.tcp_established = True
- resp = cc.send_req(req)
+ req = self.__make_dump_req()
+ resp = self.criu.send_req(req)
while True:
if resp.type != cr_rpc.NOTIFY:
raise Exception("Dump failed")
@@ -195,7 +163,7 @@ class phaul_iter_worker:
self.htype.net_unlock()
print "\t\tNotify (%s)" % resp.notify.script
- resp = cc.ack_notify()
+ resp = self.criu.ack_notify()
print "Dump complete"
self.th.end_iter()
@@ -219,7 +187,7 @@ class phaul_iter_worker:
# DUMP/success message
#
- resp = cc.ack_notify()
+ resp = self.criu.ack_notify()
if not resp.success:
raise Exception("Dump screwed up")
@@ -229,4 +197,51 @@ class phaul_iter_worker:
self._mstat.iteration(stats)
self._mstat.stop(self)
self.img.close()
- cc.close()
+ self.criu.close()
+
+ def __make_req(self, typ):
+ """Prepare generic criu request"""
+ req = cr_rpc.criu_req()
+ req.type = typ
+ self.htype.adjust_criu_req(req)
+ return req
+
+ def __make_common_dump_req(self, typ):
+ """Prepare common criu request for pre-dump or dump"""
+
+ req = self.__make_req(typ)
+ req.opts.pid = self.pid
+ req.opts.ps.fd = self.criu.mem_sk_fileno()
+ req.opts.track_mem = True
+
+ req.opts.images_dir_fd = self.img.image_dir_fd()
+ req.opts.work_dir_fd = self.img.work_dir_fd()
+ p_img = self.img.prev_image_dir()
+ if p_img:
+ req.opts.parent_img = p_img
+ if not self.fs.persistent_inodes():
+ req.opts.force_irmap = True
+
+ return req
+
+ def __make_cpuinfo_dump_req(self):
+ """Prepare cpuinfo dump criu request"""
+ req = self.__make_req(cr_rpc.CPUINFO_DUMP)
+ req.opts.images_dir_fd = self.img.work_dir_fd()
+ req.keep_open = True
+ return req
+
+ def __make_predump_req(self):
+ """Prepare pre-dump criu request"""
+ return self.__make_common_dump_req(cr_rpc.PRE_DUMP)
+
+ def __make_dump_req(self):
+ """Prepare dump criu request"""
+ req = self.__make_common_dump_req(cr_rpc.DUMP)
+ req.opts.notify_scripts = True
+ req.opts.file_locks = True
+ req.opts.evasive_devices = True
+ req.opts.link_remap = True
+ if self.htype.can_migrate_tcp():
+ req.opts.tcp_established = True
+ return req
diff --git a/phaul/p_haul_lxc.py b/phaul/p_haul_lxc.py
index 27df698..13640d2 100644
--- a/phaul/p_haul_lxc.py
+++ b/phaul/p_haul_lxc.py
@@ -76,6 +76,10 @@ class p_haul_type:
def set_options(self, opts):
pass
+ def adjust_criu_req(self, req):
+ """Add module-specific options to criu request"""
+ pass
+
def root_task_pid(self):
pid = -1;
diff --git a/phaul/p_haul_pid.py b/phaul/p_haul_pid.py
index f0051b0..5bd2d5d 100644
--- a/phaul/p_haul_pid.py
+++ b/phaul/p_haul_pid.py
@@ -24,6 +24,10 @@ class p_haul_type:
self._pidfile = opts["dst_rpid"]
self._fs_root = opts["pid_root"]
+ def adjust_criu_req(self, req):
+ """Add module-specific options to criu request"""
+ pass
+
# Report the pid of the root task of what we're
# goung to migrate
def root_task_pid(self):
diff --git a/phaul/p_haul_service.py b/phaul/p_haul_service.py
index d3e19ff..50eab03 100644
--- a/phaul/p_haul_service.py
+++ b/phaul/p_haul_service.py
@@ -53,18 +53,8 @@ class phaul_service:
def start_page_server(self):
print "Starting page server for iter %d" % self.dump_iter
- req = cr_rpc.criu_req()
- req.type = cr_rpc.PAGE_SERVER
- req.keep_open = True
- req.opts.ps.fd = self.criu.mem_sk_fileno()
-
- req.opts.images_dir_fd = self.img.image_dir_fd()
- req.opts.work_dir_fd = self.img.work_dir_fd()
- p_img = self.img.prev_image_dir()
- if p_img:
- req.opts.parent_img = p_img
-
print "\tSending criu rpc req"
+ req = self.__make_page_server_req()
resp = self.criu.send_req(req)
if not resp.success:
raise Exception("Failed to start page server")
@@ -87,10 +77,7 @@ class phaul_service:
def rpc_check_cpuinfo(self):
print "Checking cpuinfo"
- req = cr_rpc.criu_req()
- req.type = cr_rpc.CPUINFO_CHECK
- req.opts.images_dir_fd = self.img.work_dir_fd()
- req.keep_open = True
+ req = self.__make_cpuinfo_check_req()
resp = self.criu.send_req(req)
print " `-", resp.success
return resp.success
@@ -99,27 +86,8 @@ class phaul_service:
print "Restoring from images"
self.htype.put_meta_images(self.img.image_dir())
- req = cr_rpc.criu_req()
- req.type = cr_rpc.RESTORE
- req.opts.images_dir_fd = self.img.image_dir_fd()
- req.opts.work_dir_fd = self.img.work_dir_fd()
- req.opts.notify_scripts = True
-
- if self.htype.can_migrate_tcp():
- req.opts.tcp_established = True
-
- for veth in self.htype.veths():
- v = req.opts.veths.add()
- v.if_in = veth.name
- v.if_out = veth.pair
-
- nroot = self.htype.mount()
- if nroot:
- req.opts.root = nroot
- print "Restore root set to %s" % req.opts.root
-
- cc = self.criu
- resp = cc.send_req(req)
+ req = self.__make_restore_req()
+ resp = self.criu.send_req(req)
while True:
if resp.type == cr_rpc.NOTIFY:
print "\t\tNotify (%s.%d)" % (resp.notify.script, resp.notify.pid)
@@ -137,7 +105,7 @@ class phaul_service:
elif resp.notify.script == "network-lock":
raise Exception("Locking network on restore?")
- resp = cc.ack_notify()
+ resp = self.criu.ack_notify()
continue
if not resp.success:
@@ -152,3 +120,53 @@ class phaul_service:
def rpc_restore_time(self):
stats = criu_api.criu_get_rstats(self.img)
return stats.restore_time
+
+ def __make_req(self, typ):
+ """Prepare generic criu request"""
+ req = cr_rpc.criu_req()
+ req.type = typ
+ self.htype.adjust_criu_req(req)
+ return req
+
+ def __make_page_server_req(self):
+ """Prepare page server criu request"""
+
+ req = self.__make_req(cr_rpc.PAGE_SERVER)
+ req.keep_open = True
+ req.opts.ps.fd = self.criu.mem_sk_fileno()
+ req.opts.images_dir_fd = self.img.image_dir_fd()
+ req.opts.work_dir_fd = self.img.work_dir_fd()
+
+ p_img = self.img.prev_image_dir()
+ if p_img:
+ req.opts.parent_img = p_img
+
+ return req
+
+ def __make_cpuinfo_check_req(self):
+ """Prepare cpuinfo check criu request"""
+ req = self.__make_req(cr_rpc.CPUINFO_CHECK)
+ req.keep_open = True
+ req.opts.images_dir_fd = self.img.work_dir_fd()
+ return req
+
+ def __make_restore_req(self):
+ """Prepare restore criu request"""
+
+ req = self.__make_req(cr_rpc.RESTORE)
+ req.opts.images_dir_fd = self.img.image_dir_fd()
+ req.opts.work_dir_fd = self.img.work_dir_fd()
+ req.opts.notify_scripts = True
+
+ if self.htype.can_migrate_tcp():
+ req.opts.tcp_established = True
+
+ for veth in self.htype.veths():
+ req.opts.veths.add(if_in = veth.name, if_out = veth.pair)
+
+ nroot = self.htype.mount()
+ if nroot:
+ req.opts.root = nroot
+ print "Restore root set to %s" % req.opts.root
+
+ return req
diff --git a/phaul/p_haul_vz.py b/phaul/p_haul_vz.py
index 40dc943..e194194 100644
--- a/phaul/p_haul_vz.py
+++ b/phaul/p_haul_vz.py
@@ -8,6 +8,7 @@ import p_haul_cgroup
import util
import fs_haul_shared
import fs_haul_subtree
+import pycriu.rpc
name = "vz"
vz_dir = "/vz"
@@ -72,6 +73,31 @@ class p_haul_type:
def set_options(self, opts):
pass
+ def adjust_criu_req(self, req):
+ """Add module-specific options to criu request"""
+ if req.type == pycriu.rpc.DUMP or req.type == pycriu.rpc.RESTORE:
+ self.__adjust_criu_ext_mounts(req)
+
+ def __adjust_criu_ext_mounts(self, req):
+ """Setup mappings for external cgroups mounts"""
+
+ ext_mounts = {"/sys/fs/cgroup/cpuset":"/ve-cpuset",
+ "/sys/fs/cgroup/cpu,cpuacct":"/ve-cpu-cpuacct",
+ "/sys/fs/cgroup/memory":"/ve-memory",
+ "/sys/fs/cgroup/devices":"/ve-devices",
+ "/sys/fs/cgroup/freezer":"/ve-freezer",
+ "/sys/fs/cgroup/net_cls":"/ve-net_cls",
+ "/sys/fs/cgroup/blkio":"/ve-blkio",
+ "/sys/fs/cgroup/perf_event":"/ve-perf_event",
+ "/sys/fs/cgroup/hugetlb":"/ve-hugetlb",
+ "/sys/fs/cgroup/systemd":"/ve-systemd"}
+
+ for key, val in ext_mounts.items():
+ if req.type == pycriu.rpc.DUMP:
+ req.opts.ext_mnt.add(key = key, val = val)
+ elif req.type == pycriu.rpc.RESTORE:
+ req.opts.ext_mnt.add(key = val, val = key)
+
def root_task_pid(self):
# Expect first line of tasks file contain root pid of CT
path = "/sys/fs/cgroup/memory/{0}/tasks".format(self._ctid)
--
1.7.1
More information about the CRIU
mailing list