23

I'm attempting to use a loop device inside a container, to mount some image file:

> sudo losetup /dev/loop0 test.img
losetup: /dev/loop0: failed to set up loop device: No such file or directory

/dev/loop0 indeed doesn't exist, and

> sudo mknod /dev/loop0 b 7 0
mknod: ‘/dev/loop0’: Operation not permitted

How can I make this work? Does the container need some cgroup permission that it might not have?

Ivan Velichko
  • 145
  • 2
  • 11
Johannes Ernst
  • 1,037
  • 4
  • 16
  • 26

2 Answers2

23

If you're using systemd-nspawn, start up your container with the --capability=CAP_MKNOD command line switch. This will allow you to create device nodes inside your container. Then create a loop device like this:

# mknod /dev/loop0 b 7 0

Remember that this loop device is shared with the host and is called /dev/loop0 there as well. And that it is now possible to access host devices if you know the major and minor numbers. There could also be other consequences that I haven't thought about. Be warned.

Troels Folke
  • 353
  • 2
  • 5
  • 2
    Can anybody confirm that `--capability=CAP_MKNOD` still works? For me it seems to have no effect, I get `Operation not permitted` even with it, and so do [this user](https://bbs.archlinux.org/viewtopic.php?id=199015) and [this user](http://armbian2.rssing.com/browser.php?indx=63042733&item=411). – nh2 Feb 23 '18 at 22:44
  • 3
    I got it to work now, but in addition to giving `--capability=CAP_MKNOD` I had to set `DeviceAllow=block-loop rwm` in the systemd-nspawn unit to make it work (got that idea from [here](https://github.com/systemd/systemd/blob/3153ded003233b4431ee2fa4cea96cb987c08fd4/units/systemd-nspawn%40.service.in#L36-L40)). – nh2 Feb 24 '18 at 18:43
  • I had to add `--device-cgroup-rule="b 7:* rmw"` to `docker run` to permit full access to loopback devices (but no others, since there's no `--privilege`). Found via https://docs.docker.com/edge/engine/reference/commandline/create/#dealing-with-dynamically-created-devices---device-cgroup-rule and tested on docker 18.06.1-ce (the document claims to only apply to Docker Edge) – RobM Oct 26 '18 at 16:36
  • This doesn't work if one is using user namespace. – LtWorf Mar 18 '20 at 10:53
16

Loop devices are provided by a kernel module. Therefore, you need special privileges to access them. You also need them to be exposed into your container, or you need to manually create the device files.

The quick answer

docker run --privileged=true ...

An alternative

sudo losetup /dev/loop0 test.img
mount /dev/loop0 /mnt
docker run -v /mnt:/mnt ...

This almost works

docker run --device=/dev/loop-control:/dev/loop-control --device=/dev/loop0:/dev/loop0 --cap-add SYS_ADMIN ...

However I get this error:

root@5c033d5f8625:/# sudo mount /dev/loop0 /mnt
mount: block device /dev/loop0 is write-protected, mounting read-only
mount: cannot mount block device /dev/loop0 read-only

See this link for more information.


A note on systemd-nspawn man page:

systemd-nspawn limits access to various kernel interfaces in the container to read-only, such as /sys, /proc/sys or /sys/fs/selinux. Network interfaces and the system clock may not be changed from within the container. Device nodes may not be created. The host system cannot be rebooted and kernel modules may not be loaded from within the container.

hookenz
  • 14,132
  • 22
  • 86
  • 142