Allow loop mounting files inside LXC containers?

16,114

The issue you were running into is with apparmor. 'dmesg' would probably have shown you something like:

[ 4822.366235] type=1400 audit(1384973058.254:52): apparmor="DENIED" operation="mount" 
info="failed type match" error=-13 parent=1272 profile="lxc-container-default" 
name="/mnt/" pid=1273 comm="mount" fstype="ext4" srcname="/dev/loop0/" flags="ro"

You can allow your lxc container to do mounts of ext2, ext3, or ext4 filesystems in one of 2 ways. The simplist is to just add the following to the lxc config (/var/lib/lxc/$NAME/config):

lxc.aa_profile = unconfined
lxc.cgroup.devices.allow = b 7:* rwm
lxc.cgroup.devices.allow = c 10:237 rwm

A much more restrictive solution that still grants the necessary permissions is to do the following:

$ sudo tee /etc/apparmor.d/lxc/lxc-custom-mounts <<EOF
# copied and modified from /etc/apparmor.d/lxc/lxc-default
profile lxc-container-extx-mounts flags=(attach_disconnected,mediate_deleted) {
  #include <abstractions/lxc/container-base>
  mount fstype=ext4 -> /**,
  mount fstype=ext3 -> /**,
  mount fstype=ext2 -> /**,
}
EOF

# reload the lxc-containers profile
$ sudo apparmor_parser --replace /etc/apparmor.d/lxc-containers

$ sudo lxc-create -t ubuntu-cloud -n source-saucy-amd64 -- --release=saucy --arch=amd64

$ name="test1"
$ cfg=/var/lib/lxc/$name/config;
$ sudo lxc-clone -o source-saucy-amd64 -n "$name"

## modify the config to use the profile created above
$ sudo grep "#allow-loop" "$cfg" || sudo tee -a "$cfg" <<EOF
#allow-loop
lxc.aa_profile = lxc-container-extx-mounts
lxc.cgroup.devices.allow = b 7:* rwm
lxc.cgroup.devices.allow = c 10:237 rwm
EOF

You can then verify it works in the container with something as easy as:

$ truncate --size 100M my.img
$ mkfs.ext4 -F my.img
$ sudo mount -o loop,ro my.img /mnt
$ ls /mnt
lost+found
$ sudo umount /mnt

I've just opened bug 1257389 to address this. Hopefully sometime soon maas-import-ephemerals will work inside a container.

Share:
16,114

Related videos on Youtube

Dan Hibbert
Author by

Dan Hibbert

Updated on September 18, 2022

Comments

  • Dan Hibbert
    Dan Hibbert over 1 year

    I'm trying to set up a MaaS server inside an LXC container.

    When I import the PXE files, it needs to be able to mount loop devices.

    I have set the following options in the container config file to allow loop mounting, but I'm missing something.

    lxc.cgroup.devices.allow = b 7:* rwm
    lxc.cgroup.devices.allow = c 10:237 rwm
    

    I get the following error because the script cannot loop mount a file:

    mount: cannot mount block device /dev/loop0 read-only
    Wed, 13 Nov 2013 07:26:41 +0000: failed to mount /var/lib/maas/ephemeral/precise/ephemeral/i386/20131010/disk.img
    Traceback (most recent call last):
      File "/usr/sbin/maas-import-ephemerals", line 26, in <module>
        main(args)
      File "/usr/lib/python2.7/dist-packages/provisioningserver/import_images/ephemerals_script.py", line 428, in main
        target.sync(source, args.path)
      File "/usr/lib/python2.7/dist-packages/simplestreams/mirrors/__init__.py", line 85, in sync
        return self.sync_index(reader, path, data, content)
      File "/usr/lib/python2.7/dist-packages/simplestreams/mirrors/__init__.py", line 237, in sync_index
        self.sync(reader, path=epath)
      File "/usr/lib/python2.7/dist-packages/simplestreams/mirrors/__init__.py", line 83, in sync
        return self.sync_products(reader, path, data, content)
      File "/usr/lib/python2.7/dist-packages/simplestreams/mirrors/__init__.py", line 315, in sync_products
        self.insert_item(item, src, target, pgree, ipath_cs)
      File "/usr/lib/python2.7/dist-packages/provisioningserver/import_images/ephemerals_script.py", line 251, in insert_item
        self.extract_item(path, flat)
      File "/usr/lib/python2.7/dist-packages/provisioningserver/import_images/ephemerals_script.py", line 295, in extract_item
        tarball, target_dir, temp_location=self._simplestreams_path())
      File "/usr/lib/python2.7/dist-packages/provisioningserver/import_images/ephemerals_script.py", line 124, in extract_image_tarball
        call_uec2roottar(image, os.path.join(target_dir, 'dist-root.tar.gz'))
      File "/usr/lib/python2.7/dist-packages/provisioningserver/import_images/ephemerals_script.py", line 97, in call_uec2roottar
        subprocess.check_call(["uec2roottar"] + list(args))
      File "/usr/lib/python2.7/subprocess.py", line 540, in check_call
        raise CalledProcessError(retcode, cmd)
    subprocess.CalledProcessError: Command '[u'uec2roottar', u'/var/lib/maas/ephemeral/precise/ephemeral/i386/20131010/disk.img', u'/var/lib/maas/ephemeral/precise/ephemeral/i386/20131010/dist-root.tar.gz']' returned non-zero exit status 1
    root@maaslxc2:~# mount /dev/loop0 /mnt
    mount: block device /dev/loop0 is write-protected, mounting read-only
    mount: cannot mount block device /dev/loop0 read-only
    

    So, what do I need to change in the container's configuration to allow it to mount loop devices? It appears that this is not just a MaaS problem, but a restriction that would cause trouble for anything (not just MaaS) that needs to loop mount a file in a LXC container.