[CRIU] [PATCH V2] p.haul: allow specify module-specific criu request options
Pavel Emelyanov
xemul at parallels.com
Wed Jun 24 12:22:15 PDT 2015
On 06/24/2015 08:57 PM, Nikita Spiridonov wrote:
> We have to specify --ext-mount-map auto, --enable-external-sharing
> and --enable-external-masters 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.
Please, split the patch into
[PATCH 1/2] Move all requests-related code to separate mothods
[PATCH 2/2] Allos specify module-specific criu request options
> 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 | 9 ++++
> 5 files changed, 127 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..7f41816 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,14 @@ 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:
> + # Setup options for external mounts resolution
> + req.opts.auto_ext_mnt = True
> + req.opts.ext_sharing = True
> + req.opts.ext_masters = True
> +
> 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)
>
More information about the CRIU
mailing list