[lxc-devel] [PATCH 1/2] python: Add add_device() function

Stéphane Graber stgraber at ubuntu.com
Fri Nov 23 19:41:56 UTC 2012


On 11/23/2012 10:39 AM, Serge Hallyn wrote:
> Quoting Stéphane Graber (stgraber at ubuntu.com):
>> 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
> 
> The cgroup tweaking should be done using generic code.  Maybe it's
> time to add those to the c api...

Totally agreed, I was actually going to nag you again this cycle about
getting a set_cgroup_item() and get_cgroup_item() function in the API so
I can remove all that ugly code from the python wrapper :)

>> +        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)
> 
> This brings up an interesting question of persistence.  The device node
> will be persistent if using static /dev, not with autodev.  The cgroup
> settings are not saved here that I can see.
> 
> Do we want persistence to be an option?  If so we could optionally save
> the cgroup settings and add a new config file entry for device entries
> to add in the case of autodev.  HOWEVER, there will also be cases where
> the device being added can change its major:minor between container
> startups.  In which case we have deeper problems (and need to bind to
> a uuid or lspci/lsusb device descriptor or something).

Yeah, persistence is an option I'm planning to add along with removing
entries at run time (both from the cgroup and the fs).

One problem though is that using set_config_item + save_config will wipe
any formating and comment in the configuration, I'm guessing not all
users will like that :)

>> +        return True
>> +
>>      def append_config_item(self, key, value):
>>          """
>>              Append 'value' to 'key', assuming 'key' is a list.
>> -- 
>> 1.8.0
>>
>>
>> ------------------------------------------------------------------------------
>> Monitor your physical, virtual and cloud infrastructure from a single
>> web console. Get in-depth insight into apps, servers, databases, vmware,
>> SAP, cloud infrastructure, etc. Download 30-day Free Trial.
>> Pricing starts from $795 for 25 servers or applications!
>> http://p.sf.net/sfu/zoho_dev2dev_nov
>> _______________________________________________
>> Lxc-devel mailing list
>> Lxc-devel at lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/lxc-devel


-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 899 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20121123/c12304d6/attachment.pgp>


More information about the lxc-devel mailing list