[CRIU] [PATCH] p.haul: allow specify module-specific criu request options
Tycho Andersen
tycho.andersen at canonical.com
Fri Jun 19 07:15:22 PDT 2015
On Fri, Jun 19, 2015 at 02:06:01PM +0400, Nikita Spiridonov wrote:
> 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.
Is this something we can use `--ext-mount-map auto` for? In
lxc-checkpoint, we're using that so we don't have to specify all these
by hand (including any extra bind mounts the user may have asked for).
Tycho
> 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
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list