Solving “Operation not permitted” Error When Creating Loop Devices in Linux Containers


2 views

When working with Linux containers (particularly Docker/LXC/Podman), you might encounter permission issues when trying to create or use loop devices. The specific error occurs when attempting:

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

sudo mknod /dev/loop0 b 7 0  
mknod: '/dev/loop0': Operation not permitted

Modern container runtimes typically don't expose loop devices by default due to security considerations. The kernel prevents device node creation inside containers unless specifically configured.

1. Running with --privileged

The simplest (but least secure) solution is running your container with full privileges:

docker run --privileged -it your_image

Inside the container, you can now create loop devices:

mknod /dev/loop0 b 7 0
losetup /dev/loop0 test.img
mount /dev/loop0 /mnt

2. Specific Device Access

For better security, grant only necessary permissions:

docker run --device=/dev/loop-control:/dev/loop-control \
           --device=/dev/loop0:/dev/loop0 \
           -it your_image

You'll also need to ensure the host has loop devices available:

sudo modprobe loop
sudo losetup -f  # Verify available loop devices

3. Using Docker's --device-cgroup-rule

For more granular control with Docker:

docker run --device-cgroup-rule='b 7:* rmw' -it your_image

For production environments, consider pre-configuring loop devices on the host and passing them to containers:

# On host
sudo losetup -fP test.img
LOOP_DEV=$(losetup -j test.img | cut -d: -f1)

# Start container with the device
docker run --device=${LOOP_DEV}:${LOOP_DEV} -it your_image

Ensure your kernel supports user namespaces for device management:

grep CONFIG_USER_NS /boot/config-$(uname -r)
grep CONFIG_DEVTMPFS /boot/config-$(uname -r)

If loop devices prove problematic, consider FUSE-based solutions:

sudo apt-get install fuse2fs
fuse2fs test.img /mnt

This avoids the need for loop devices entirely while providing similar functionality.

When troubleshooting:

# Check available loop devices
ls /dev/loop*

# Verify kernel messages
dmesg | grep loop

# Check container capabilities
capsh --print

When working with Linux containers, you might encounter the following scenario when trying to use loop devices:

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

sudo mknod /dev/loop0 b 7 0
mknod: '/dev/loop0': Operation not permitted

This occurs because containers typically don't have access to host devices by default, and creating device nodes inside containers is restricted for security reasons.

Modern container runtimes implement several security measures that prevent direct device access:

  • Device node creation is blocked by default
  • Devices must be explicitly mounted from the host
  • CAP_MKNOD capability is usually dropped

Option 1: Pass Host Loop Devices

The most straightforward solution is to pass host loop devices into the container:

docker run --device /dev/loop0 --device /dev/loop-control -it your_image

For podman (rootless containers require additional steps):

podman run --device /dev/loop0 --device /dev/loop-control -it your_image

Option 2: Use Privileged Mode (Not Recommended)

While not secure for production, you can use privileged mode for testing:

docker run --privileged -it your_image

Option 3: Configure the Container Runtime

For Kubernetes pods, you can add securityContext:

securityContext:
  capabilities:
    add: ["MKNOD"]
  privileged: false

Here's how to properly mount an image file inside a container:

# First ensure loop devices are available
ls /dev/loop*

# If not, on the host:
sudo mknod -m 0660 /dev/loop0 b 7 0
sudo chown root:disk /dev/loop0

# In container:
sudo losetup -f --show test.img
sudo mkdir /mnt/image
sudo mount /dev/loop0 /mnt/image

If you can't modify container permissions, consider:

  • Mounting the image on the host and bind-mounting into container
  • Using a FUSE-based filesystem implementation
  • Using a custom device plugin if running in Kubernetes

When enabling loop devices in containers:

  • Never run containers as root unless absolutely necessary
  • Limit which loop devices are accessible
  • Consider read-only mounts when possible
  • Audit container capabilities regularly