Exposing /dev/loop devices in privileged mode


#1

Hi! I’m trying to run a task where I need a loopback device to manipulate raw disk images. In docker, the privileged mode allows me to use mknod to create loop devices in the container and use them - then I can use something like losetup -f to retrieve an available loop device.
Looks like privileged mode in concourse does not expose /dev/loopX devices. I tried creating them manually using mknod, but I’m getting Operation not permitted when attempting to mount them. Is there a way to tell concourse/garden to expose or allow to use mknod-created /dev/loopX devices when the task is executed in privileged mode? (I’m using 3.10 with btrfs backend).


Hardware in the loop testing
#2

I found the answer by looking at what concourse is doing in their own CI :slight_smile:

Based on https://github.com/concourse/concourse/blob/8cd12d526a81bf3e1a926334ed66166a1cbb95df/bin/ci/testflight,

you need to enable device control in the devices cgroup associated with the container:

function permit_device_control() {
  local devices_mount_info=$(cat /proc/self/cgroup | grep devices)

  if [ -z "$devices_mount_info" ]; then
    # cgroups not set up; must not be in a container
    return
  fi

  local devices_subsytems=$(echo $devices_mount_info | cut -d: -f2)
  local devices_subdir=$(echo $devices_mount_info | cut -d: -f3)

  if [ "$devices_subdir" = "/" ]; then
    # we're in the root devices cgroup; must not be in a container
    return
  fi

  cgroup_dir=/tmp/devices-cgroup

  if [ ! -e ${cgroup_dir} ]; then
    # mount our container's devices subsystem somewhere
    mkdir ${cgroup_dir}
  fi

  if ! mountpoint -q ${cgroup_dir}; then
    if ! mount -t cgroup -o $devices_subsytems none ${cgroup_dir}; then
      return 1
    fi
  fi

  # permit our cgroup to do everything with all devices
  # ignore failure in case something has already done this; echo appears to
  # return EINVAL, possibly because devices this affects are already in use
  echo a > ${cgroup_dir}${devices_subdir}/devices.allow || true
}