[CRIU] [PATCH 2/2] p.haul: LinuX Containers hauler module (v2)
Andrey Vagin
avagin at openvz.org
Wed Mar 19 11:55:56 PDT 2014
Known issues:
* It works only in one direction, because the lxc control
process isn't executed after migration.
v2: add support of veth devices
[root at 40 p.haul]# ./p.haul lxc centos-lxc-4 192.168.122.36
Loading config file from /var/lib/lxc/centos-lxc-4/config
Connecting to target host
Initilized shared FS hauler
Connecting to CRIU service
Preliminary FS migration
Starting iterations
* Iteration 0
Making directory /var/local/p.haul-fs/rDf7q4/img/1
Issuing pre-dump command to service
Pre-dump succeeded
Dumped 2508 pages, 0 skipped
Checking iteration progress:
> Proceed to next iteration
* Iteration 1
Making directory /var/local/p.haul-fs/rDf7q4/img/2
Issuing pre-dump command to service
Pre-dump succeeded
Dumped 39 pages, 2469 skipped
Checking iteration progress:
> Small dump
Final dump and restore
Making directory /var/local/p.haul-fs/rDf7q4/img/3
Issuing dump command to service
Notify (network-lock)
Dump complete
Final FS and images sync
Sending images to target
Pack
Add htype images
Save CG for 6212 into /var/local/p.haul-fs/rDf7q4/img/3/lxccg.img
Copy
Unpack
Asking target host to restore
Final dump -- 25 pages, 2483 skipped
Removing images
Migration succeeded
total time is ~3.08 sec
frozen time is ~2.71 sec ( ['0.08', '0.11', '2.52'] )
restore time is ~1.83 sec
img sync time is ~0.31 sec
lxc
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
p_haul_lxc.py | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
p_haul_type.py | 4 +-
2 files changed, 171 insertions(+), 1 deletion(-)
create mode 100644 p_haul_lxc.py
diff --git a/p_haul_lxc.py b/p_haul_lxc.py
new file mode 100644
index 0000000..3c2867b
--- /dev/null
+++ b/p_haul_lxc.py
@@ -0,0 +1,168 @@
+#
+# LinuX Containers hauler module
+#
+
+import os
+import shutil
+import p_haul_cgroup
+import p_haul_netifapi as netif
+import p_haul_fsapi as fsapi
+import p_haul_netapi as netapi
+import fs_haul_shared
+import fs_haul_subtree
+from subprocess import Popen, PIPE
+
+name = "lxc"
+lxc_dir = "/var/lib/lxc/"
+lxc_rootfs_dir = "/usr/lib64/lxc/rootfs"
+cg_image_name = "lxccg.img"
+
+class p_haul_type:
+ def __init__(self, name):
+ self._ctname = name
+ #
+ # This list would contain (v_in, v_out, v_br) tuples where
+ # v_in is the name of veth device in CT
+ # v_out is its peer on the host
+ # v_bridge is the bridge to which thie veth is attached
+ #
+ self._veths = []
+ self._cfg = {}
+
+ def __load_ct_config(self):
+ print "Loading config file from %s" % self.__ct_config()
+
+ self._cfg = {}
+ self._veths = []
+
+ veth = None
+
+ ifd = open(self.__ct_config())
+ for line in ifd:
+ if not ("=" in line):
+ continue
+ k, v = map(lambda a: a.strip(), line.split("=", 1))
+ self._cfg[k] = v
+
+ if k == "lxc.network.type":
+ if v != "veth":
+ raise Exception("Unsupported network device type: %s", v)
+ if veth:
+ self._veths.append(veth)
+ veth = netapi.net_dev()
+ elif k == "lxc.network.link":
+ veth.link = v
+ elif k == "lxc.network.name":
+ veth.name = v
+ elif k == "lxc.network.veth.pair":
+ veth.pair = v
+ if veth:
+ self._veths.append(veth)
+ ifd.close()
+
+ def __apply_cg_config(self):
+ print "Applying CT configs"
+ # FIXME -- implement
+ pass
+
+ def id(self):
+ return (name, self._ctname)
+
+ def init_src(self):
+ self._fs_mounted = True
+ self._bridged = True
+ self.__load_ct_config()
+
+ def init_dst(self):
+ self._fs_mounted = False
+ self._bridged = False
+ self.__load_ct_config()
+
+ def root_task_pid(self):
+ pid = -1;
+
+ pd = Popen(["lxc-info", "-n", self._ctname], stdout = PIPE)
+ for l in pd.stdout:
+ if l.startswith("PID:"):
+ pid = int(l.split(":")[1])
+ status = pd.wait()
+ if status:
+ raise Exception("lxc info -n %s failed: %d" %
+ (self._ctname, status))
+ if pid == -1:
+ raise Exception("CT isn't running")
+ return pid
+
+ def __ct_rootfs(self):
+ return self._cfg['lxc.rootfs']
+
+ def __ct_root(self):
+ return os.path.join(lxc_rootfs_dir, self._ctname)
+
+ def __ct_config(self):
+ return os.path.join(lxc_dir, self._ctname, "config")
+
+ #
+ # Meta-images for LXC -- container config and info about CGroups
+ #
+ def get_meta_images(self, dir):
+ cg_img = os.path.join(dir, cg_image_name)
+ p_haul_cgroup.dump_hier(self.root_task_pid(), cg_img)
+ cfg_name = self.__ct_config()
+ return [ (cfg_name, "config"),
+ (cg_img, cg_image_name) ]
+
+ def put_meta_images(self, dir):
+ print "Putting config file into %s" % lxc_dir
+
+ shutil.copy(os.path.join(dir, "config"), self.__ct_config())
+
+ # Keep this name, we'll need one in prepare_ct()
+ self.cg_img = os.path.join(dir, cg_image_name)
+
+ #
+ # Create cgroup hierarchy and put root task into it
+ # Hierarchy is unlimited, we will apply config limitations
+ # in ->restored->__apply_cg_config later
+ #
+ def prepare_ct(self, pid):
+ p_haul_cgroup.restore_hier(pid, self.cg_img)
+
+ def mount(self):
+ nroot = self.__ct_root()
+ print "Mounting CT root to %s" % nroot
+ if not os.access(nroot, os.F_OK):
+ os.makedirs(nroot)
+ os.system("mount --bind %s %s" % (self.__ct_rootfs(), nroot))
+ self._fs_mounted = True
+ return nroot
+
+ def get_fs(self):
+ return fs_haul_shared.p_haul_fs()
+
+ def restored(self, pid):
+ self.__apply_cg_config()
+
+ def net_lock(self):
+ for veth in self._veths:
+ netif.ifdown(veth.pair)
+
+ def net_unlock(self):
+ for veth in self._veths:
+ netif.ifup(veth.pair)
+ if veth.link and not self._bridged:
+ netif.bridge_add(veth.pair, veth.link)
+
+ def can_migrate_tcp(self):
+ return True
+
+ def umount(self):
+ pass
+
+ def veths(self):
+ #
+ # Caller wants to see list of tuples with [0] being name
+ # in CT and [1] being name on host. Just return existing
+ # tuples, the [2] with bridge name wouldn't hurt
+ #
+ return self._veths
diff --git a/p_haul_type.py b/p_haul_type.py
index 6ed6c76..6ac093d 100644
--- a/p_haul_type.py
+++ b/p_haul_type.py
@@ -6,10 +6,12 @@
import p_haul_ovz
import p_haul_pid
+import p_haul_lxc
haul_types = {
p_haul_ovz.name: p_haul_ovz,
- p_haul_pid.name: p_haul_pid
+ p_haul_pid.name: p_haul_pid,
+ p_haul_lxc.name: p_haul_lxc,
}
def __get(id):
--
1.8.5.3
More information about the CRIU
mailing list