[CRIU] [PATCH 3/5] vz: transform ovz module into vz module
nspiridonov
nspiridonov at odin.com
Tue Apr 28 08:35:13 PDT 2015
From: jne100 <jne100 at gmail.com>
Rename OpenVZ module to Virtuozzo module, change method of root
pid acquisition. As far as /var/lib/vzctl/vepid/ctid missing for
Virtuozzo containers obtain root pid using cgroups.
Signed-off-by: Nikita Spiridonov <nspiridonov at odin.com>
---
p_haul_ovz.py | 188 -------------------------------------------------------
p_haul_type.py | 4 +-
p_haul_vz.py | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 191 insertions(+), 190 deletions(-)
delete mode 100644 p_haul_ovz.py
create mode 100644 p_haul_vz.py
diff --git a/p_haul_ovz.py b/p_haul_ovz.py
deleted file mode 100644
index f33e033..0000000
--- a/p_haul_ovz.py
+++ /dev/null
@@ -1,188 +0,0 @@
-#
-# OpenVZ containers hauler module
-#
-
-import os
-import shlex
-import p_haul_cgroup
-import util
-import fs_haul_shared
-import fs_haul_subtree
-
-name = "ovz"
-vzpid_dir = "/var/lib/vzctl/vepid/"
-vz_dir = "/vz"
-vzpriv_dir = "%s/private" % vz_dir
-vzroot_dir = "%s/root" % vz_dir
-vz_conf_dir = "/etc/vz/conf/"
-vz_pidfiles = "/var/lib/vzctl/vepid/"
-cg_image_name = "ovzcg.img"
-
-class p_haul_type:
- def __init__(self, ctid):
- self._ctid = ctid
- #
- # 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, path):
- print "Loading config file from %s" % path
-
- with open(os.path.join(path, self.__ct_config())) as ifd:
- self._cfg = ifd.read()
-
- #
- # Parse and keep veth pairs, later we will
- # equip restore request with this data and
- # will use it while (un)locking the network
- #
- config = parse_vz_config(self._cfg)
- if "NETIF" in config:
- v_in, v_out, v_bridge = None, None, None
- for parm in config["NETIF"].split(","):
- pa = parm.split("=")
- if pa[0] == "ifname":
- v_in = pa[1]
- elif pa[0] == "host_ifname":
- v_out = pa[1]
- elif pa[0] == "bridge":
- v_bridge = pa[1]
- if v_in and v_out:
- print "\tCollect %s -> %s (%s) veth" % (v_in, v_out, v_bridge)
- self._veths.append(util.net_dev(v_in, v_out, v_bridge))
-
- def __apply_cg_config(self):
- print "Applying CT configs"
- # FIXME -- implement
- pass
-
- def init_src(self):
- self._fs_mounted = True
- self._bridged = True
- self.__load_ct_config(vz_conf_dir)
-
- def init_dst(self):
- self._fs_mounted = False
- self._bridged = False
-
- def set_options(self, opts):
- pass
-
- def root_task_pid(self):
- pf = open(os.path.join(vzpid_dir, self._ctid))
- pid = pf.read()
- return int(pid)
-
- def __ct_priv(self):
- return "%s/%s" % (vzpriv_dir, self._ctid)
-
- def __ct_root(self):
- return "%s/%s" % (vzroot_dir, self._ctid)
-
- def __ct_config(self):
- return "%s.conf" % self._ctid
-
- #
- # Meta-images for OVZ -- container config and info about CGroups
- #
- def get_meta_images(self, path):
- cg_img = os.path.join(path, cg_image_name)
- p_haul_cgroup.dump_hier(self.root_task_pid(), cg_img)
- cfg_name = self.__ct_config()
- return [ (os.path.join(vz_conf_dir, cfg_name), cfg_name), \
- (cg_img, cg_image_name) ]
-
- def put_meta_images(self, path):
- print "Putting config file into %s" % vz_conf_dir
-
- self.__load_ct_config(path)
- with open(os.path.join(vz_conf_dir, self.__ct_config()), "w") as ofd:
- ofd.write(self._cfg)
-
- # Keep this name, we'll need one in prepare_ct()
- self.cg_img = os.path.join(path, 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 __umount_root(self):
- print "Umounting CT root"
- os.system("umount %s" % self.__ct_root())
- self._fs_mounted = False
-
- 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_priv(), nroot))
- self._fs_mounted = True
- return nroot
-
- def umount(self):
- if self._fs_mounted:
- self.__umount_root()
-
- def get_fs(self):
- rootfs = util.path_to_fs(self.__ct_priv())
- if not rootfs:
- print "CT is on unknown FS"
- return None
-
- print "CT is on %s" % rootfs
-
- if rootfs == "nfs":
- return fs_haul_shared.p_haul_fs()
- if rootfs == "ext3" or rootfs == "ext4":
- return fs_haul_subtree.p_haul_fs(self.__ct_priv())
-
- print "Unknown CT FS"
- return None
-
- def restored(self, pid):
- print "Writing pidfile"
- pidfile = open(os.path.join(vz_pidfiles, self._ctid), 'w')
- pidfile.write("%d" % pid)
- pidfile.close()
-
- self.__apply_cg_config()
-
- def net_lock(self):
- for veth in self._veths:
- util.ifdown(veth.pair)
-
- def net_unlock(self):
- for veth in self._veths:
- util.ifup(veth.pair)
- if veth.link and not self._bridged:
- util.bridge_add(veth.pair, veth.link)
-
- def can_migrate_tcp(self):
- return True
-
- 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
-
-def parse_vz_config(body):
- """ Parse shell-like virtuozzo config file"""
-
- config_values = dict()
- for token in shlex.split(body, comments=True):
- name, sep, value = token.partition("=")
- config_values[name] = value
- return config_values
diff --git a/p_haul_type.py b/p_haul_type.py
index 6ac093d..adf654e 100644
--- a/p_haul_type.py
+++ b/p_haul_type.py
@@ -4,12 +4,12 @@
# See p_haul_pid for comments of how a class should look like.
#
-import p_haul_ovz
+import p_haul_vz
import p_haul_pid
import p_haul_lxc
haul_types = {
- p_haul_ovz.name: p_haul_ovz,
+ p_haul_vz.name: p_haul_vz,
p_haul_pid.name: p_haul_pid,
p_haul_lxc.name: p_haul_lxc,
}
diff --git a/p_haul_vz.py b/p_haul_vz.py
new file mode 100644
index 0000000..40dc943
--- /dev/null
+++ b/p_haul_vz.py
@@ -0,0 +1,189 @@
+#
+# Virtuozzo containers hauler module
+#
+
+import os
+import shlex
+import p_haul_cgroup
+import util
+import fs_haul_shared
+import fs_haul_subtree
+
+name = "vz"
+vz_dir = "/vz"
+vzpriv_dir = "%s/private" % vz_dir
+vzroot_dir = "%s/root" % vz_dir
+vz_conf_dir = "/etc/vz/conf/"
+vz_pidfiles = "/var/lib/vzctl/vepid/"
+cg_image_name = "ovzcg.img"
+
+class p_haul_type:
+ def __init__(self, ctid):
+ self._ctid = ctid
+ #
+ # 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, path):
+ print "Loading config file from %s" % path
+
+ with open(os.path.join(path, self.__ct_config())) as ifd:
+ self._cfg = ifd.read()
+
+ #
+ # Parse and keep veth pairs, later we will
+ # equip restore request with this data and
+ # will use it while (un)locking the network
+ #
+ config = parse_vz_config(self._cfg)
+ if "NETIF" in config:
+ v_in, v_out, v_bridge = None, None, None
+ for parm in config["NETIF"].split(","):
+ pa = parm.split("=")
+ if pa[0] == "ifname":
+ v_in = pa[1]
+ elif pa[0] == "host_ifname":
+ v_out = pa[1]
+ elif pa[0] == "bridge":
+ v_bridge = pa[1]
+ if v_in and v_out:
+ print "\tCollect %s -> %s (%s) veth" % (v_in, v_out, v_bridge)
+ self._veths.append(util.net_dev(v_in, v_out, v_bridge))
+
+ def __apply_cg_config(self):
+ print "Applying CT configs"
+ # FIXME -- implement
+ pass
+
+ def init_src(self):
+ self._fs_mounted = True
+ self._bridged = True
+ self.__load_ct_config(vz_conf_dir)
+
+ def init_dst(self):
+ self._fs_mounted = False
+ self._bridged = False
+
+ def set_options(self, opts):
+ pass
+
+ 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)
+ with open(path) as tasks:
+ pid = tasks.readline()
+ return int(pid)
+
+ def __ct_priv(self):
+ return "%s/%s" % (vzpriv_dir, self._ctid)
+
+ def __ct_root(self):
+ return "%s/%s" % (vzroot_dir, self._ctid)
+
+ def __ct_config(self):
+ return "%s.conf" % self._ctid
+
+ #
+ # Meta-images for OVZ -- container config and info about CGroups
+ #
+ def get_meta_images(self, path):
+ cg_img = os.path.join(path, cg_image_name)
+ p_haul_cgroup.dump_hier(self.root_task_pid(), cg_img)
+ cfg_name = self.__ct_config()
+ return [ (os.path.join(vz_conf_dir, cfg_name), cfg_name), \
+ (cg_img, cg_image_name) ]
+
+ def put_meta_images(self, path):
+ print "Putting config file into %s" % vz_conf_dir
+
+ self.__load_ct_config(path)
+ with open(os.path.join(vz_conf_dir, self.__ct_config()), "w") as ofd:
+ ofd.write(self._cfg)
+
+ # Keep this name, we'll need one in prepare_ct()
+ self.cg_img = os.path.join(path, 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 __umount_root(self):
+ print "Umounting CT root"
+ os.system("umount %s" % self.__ct_root())
+ self._fs_mounted = False
+
+ 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_priv(), nroot))
+ self._fs_mounted = True
+ return nroot
+
+ def umount(self):
+ if self._fs_mounted:
+ self.__umount_root()
+
+ def get_fs(self):
+ rootfs = util.path_to_fs(self.__ct_priv())
+ if not rootfs:
+ print "CT is on unknown FS"
+ return None
+
+ print "CT is on %s" % rootfs
+
+ if rootfs == "nfs":
+ return fs_haul_shared.p_haul_fs()
+ if rootfs == "ext3" or rootfs == "ext4":
+ return fs_haul_subtree.p_haul_fs(self.__ct_priv())
+
+ print "Unknown CT FS"
+ return None
+
+ def restored(self, pid):
+ print "Writing pidfile"
+ pidfile = open(os.path.join(vz_pidfiles, self._ctid), 'w')
+ pidfile.write("%d" % pid)
+ pidfile.close()
+
+ self.__apply_cg_config()
+
+ def net_lock(self):
+ for veth in self._veths:
+ util.ifdown(veth.pair)
+
+ def net_unlock(self):
+ for veth in self._veths:
+ util.ifup(veth.pair)
+ if veth.link and not self._bridged:
+ util.bridge_add(veth.pair, veth.link)
+
+ def can_migrate_tcp(self):
+ return True
+
+ 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
+
+def parse_vz_config(body):
+ """ Parse shell-like virtuozzo config file"""
+
+ config_values = dict()
+ for token in shlex.split(body, comments=True):
+ name, sep, value = token.partition("=")
+ config_values[name] = value
+ return config_values
--
1.7.1
More information about the CRIU
mailing list