18

I am using a docker container (based on the official centos:6.4 image) to build an ISO which I then need to mount and verify. I am unable to mount the ISO using:

sudo mount -o loop /path/to/iso /mnt

Gives:

mount: Could not find any loop device. Maybe this kernel does not know
   about the loop device? (If so, recompile or `modprobe loop'.)

It looks like the kernel has been compiled without loop device support. Is it possible to build docker images which support loop devices? I couldn't find any information on this, however, looking at this thread it seems that this may be an ongoing topic.

I wonder if there is a way to circumvent this limitation?

pxul
  • 497
  • 1
  • 3
  • 13
  • I doubt it's the kernel. It looks more like your docker container has no loop devices in. Have you tried using `losetup`? – abligh Feb 26 '14 at 09:08
  • Hi, thanks for your reply. Can you give me a bit more information about your suggestion? The examples on the `losetup` manpage suggest that the loop entries in /dev exist, which in this case they do not (contents of `/dev`: `console full kmsg mapper null ptmx pts random shm stderr stdin stdout tty tty1 urandom zero`). It looked like using `dmsetup` might be an option, but again, there isn't much information on how this would be done. – pxul Feb 26 '14 at 10:20
  • What does `losetup -f` give you? – abligh Feb 26 '14 at 10:42
  • Same as I get from the mount command: `losetup: Could not find any loop device. Maybe this kernel does not know about the loop device? (If so, recompile or modprobe loop.)` – pxul Feb 26 '14 at 10:44
  • What does it do outside the container? It might simply be that the container is prohibiting it. Same kernel in the container as outside, remember. – abligh Feb 26 '14 at 10:57
  • Right, yes, I must be honest, I've only been playing with docker for a couple of days so I'm still finding my feet a little. Mounting images outside of the container is fine (I'm running Fedora 20, with the docker-io package - version 0.7.6). I have tried mounting an ISO using a privileged container of the "base" (Ubuntu) image and this works fine, so as you say, it must be a limitation of the image. I'll take a look around and see if there is any info on creating images with loop support (like the Ubuntu base image). Thanks for your help. – pxul Feb 26 '14 at 11:08
  • Suggest you check what is mounted on `/dev` looks likes what is mounted on `/dev` when your image is run not in a container. – abligh Feb 26 '14 at 11:45

2 Answers2

29

To mount an ISO inside a container, you need two things:

  • access to loop devices,
  • permission to mount filesystems.

By default, Docker locks down both things; that's why you get that error message.

The easiest solution is to start the container in privileged mode:

docker run --privileged ...

A more fine-grained solution is to dive down into the devices cgroup and container capabilities to give the required permissions.

Note that you cannot execute privileged operations as part of a Dockerfile; i.e. if you need to mount that ISO in a Dockerfile, you won't be able to do it.

However, I recommend that you have a look at Xorriso and specifically the osirrox tool , which lets you extract files from ISO images just like you would extract a tar file, without requiring any kind of special access, e.g.:

osirrox -indev /path/to/iso -extract / /full-iso-contents
ctd
  • 1,693
  • 12
  • 27
jpetazzo
  • 14,874
  • 3
  • 43
  • 45
  • Came for the loopback, left with `osirrox`. Thanks! – Stephan Henningsen Aug 27 '18 at 20:34
  • Using `osirrox` like that produces no error should `-indev` iso file not exist. Would appear to be by design? `-dev`: *If there is no ISO image then create a blank one.*, and `-indev`: *Set input drive and load an ISO image if present.* and *The same rules and restrictions apply as with -dev.* – Andreas Jan 25 '22 at 15:32
14

I have a feeling this is not a good way to solve my issue, but this is what I have done for the time being, until a more sane idea presents itself.

My container starts into bash, from this shell I am able to add loop devices using:

# mknod /dev/loop0 -m0660 b 7 0
# mknod /dev/loop1 -m0660 b 7 1
...
# mknod /dev/loop9 -m0660 b 7 9

and now, I have loop devices available, so I am able to mount an ISO. However, I noticed that the first available loop device for me was /dev/loop2:

bash-4.1# losetup -f
/dev/loop2

this implies that loop0 and loop1 are already in use, this is confirmed by:

bash-4.1# losetup -a
/dev/loop0: [fd00]:1978974 (/dev/loop0)
/dev/loop1: [fd00]:1978975 (/dev/loop1)
/dev/loop2: [fd00]:2369514 (/path/to/my/iso)

and, this is why I think this solution is bad, from outside the container:

12:36:02 $ losetup -a
/dev/loop0: []: (/var/lib/docker/devicemapper/devicemapper/data)
/dev/loop1: []: (/var/lib/docker/devicemapper/devicemapper/metadata)
/dev/loop2: []: (/path/to/my/iso)

So it looks like the first 2 loop devices I created in the container mapped to loop0 and loop1 outside of the container, which is why they were not available for use. I guess there must be a way of setting up these devices with devicemapper (which is being used by docker, by the looks) but I've not been able to turn up much info on this.

For the time being, this solution will be okay for me - I'll just have to be careful to remember to umount the image when I'm finished with it.

I'm aware that this is far from a sane solution, so if anyone else can come up with a better plan I'm all ears.

pxul
  • 497
  • 1
  • 3
  • 13
  • 1
    I just implemented such this way today. Couldn't find any other good solution. Main problem is the sharing loop devices with the host machine. We should take care of this behavior. – Ferhat S. R. Sep 27 '18 at 12:01
  • Awesomesauce!!! I have been troubleshooting a `failed to setup loop device for /images/foo.img` for over an hour when I came across your solution. Manually created some loop devices as you outlined, and *BOOM!* Works like a champ! – Ogre Psalm33 May 01 '20 at 21:37
  • Why not using a docker-compose to mount the iso _outside_ the container, and share the mount _inside_ via a bind mount? In both solutions, the files may be read from the host. – Gaétan RYCKEBOER Feb 26 '22 at 10:04