[lxc-devel] [PATCH 1/2] python: Add add_device() function
Stéphane Graber
stgraber at ubuntu.com
Thu Nov 22 23:08:11 UTC 2012
This introduces a new add_devices() call to the python API.
Parameters:
- path => Mandatory, path to a character or block device on the host
- destpath => Optional, alternative path inside the container
The function will allow the node in the container's devices cgroup and
then create the entry in the container.
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
src/python-lxc/lxc/__init__.py | 61 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/src/python-lxc/lxc/__init__.py b/src/python-lxc/lxc/__init__.py
index 4da3d41..c572e10 100644
--- a/src/python-lxc/lxc/__init__.py
+++ b/src/python-lxc/lxc/__init__.py
@@ -25,6 +25,7 @@ import _lxc
import glob
import os
import subprocess
+import stat
import tempfile
import time
import warnings
@@ -149,6 +150,66 @@ class Container(_lxc.Container):
_lxc.Container.__init__(self, name)
self.network = ContainerNetworkList(self)
+ def add_device(self, path, destpath=None):
+ """
+ Add device to running container.
+ """
+
+ if not destpath:
+ destpath = path
+
+ if not os.path.exists(path):
+ return False
+
+ # Lookup the source
+ path_stat = os.stat(path)
+ mode = stat.S_IMODE(path_stat.st_mode)
+
+ # Lookup the cgroup
+ cgroup_path = None
+ with open("/proc/%s/cgroup" % self.init_pid, "r") as fd:
+ for line in fd:
+ if ":devices:" in line:
+ cgroup_path = line.split(":")[-1].strip()
+ break
+ else:
+ return False
+
+ # Lookup the cgroup mount point
+ cgroup = None
+ with open("/proc/mounts", "r") as fd:
+ for line in fd:
+ mount = line.split()
+ if (mount[2] == "cgroup" and "devices" in mount[3]
+ and os.path.exists("%s/%s" % (mount[1], cgroup_path))):
+ cgroup = "%s/%s" % (mount[1], cgroup_path)
+ break
+
+ if not os.path.exists(cgroup):
+ return False
+
+ # Allow the target
+ with open("%s/devices.allow" % cgroup, "a") as fd:
+ if stat.S_ISBLK(path_stat.st_mode):
+ fd.write("b %s:%s rwm" % (int(path_stat.st_rdev / 256),
+ int(path_stat.st_rdev % 256)))
+ elif stat.S_ISCHR(path_stat.st_mode):
+ fd.write("c %s:%s rwm" % (int(path_stat.st_rdev / 256),
+ int(path_stat.st_rdev % 256)))
+
+ # Create the target
+ rootfs = "/proc/%s/root/" % self.init_pid
+ container_path = "%s/%s" % (rootfs, destpath)
+
+ if os.path.exists(container_path):
+ os.remove(container_path)
+
+ os.mknod(container_path, path_stat.st_mode, path_stat.st_rdev)
+ os.chmod(container_path, mode)
+ os.chown(container_path, 0, 0)
+
+ return True
+
def append_config_item(self, key, value):
"""
Append 'value' to 'key', assuming 'key' is a list.
--
1.8.0
More information about the lxc-devel
mailing list