Run graphical app and mount image file inside lxd container

Hi,

I have created and setup a container (ubuntu 16.04) that allows me to run graphical apps using the host display. This works well.
I then changed the config to mount an image file inside the container using /dev/loop0. To achieve this I had to make the container privileged with lxc config set c1security.privileged true.
This also works well, I can mount the image in the container but now I can’t run graphical apps anymore.

~$ thunar &
[1] 456
~$ No protocol specified
Thunar : Cannot open display:

If I make the container unprivileged again, I can run graphical apps but cannot mount the image file. The error I get tryig to mount rootfs is:
mount: /dev/loop0 is already mounted or rootfs busy
Of course /dev/loop0 is not mounted and rootfs not busy.

Is it possible to have both working?

Thanks in advance for your help.


Raphaël.

I manage to run X11 apps in a privileged container according to these instructions,
https://blog.simos.info/how-to-run-graphics-accelerated-gui-apps-in-lxd-containers-on-your-ubuntu-desktop/

Can you list the commands you use to mount an image file in a container?

Hi simos,

sure, here it is done in the privileged container (but then no graphical apps, I followed your instructions but stopped before setting the gpu):

sysadmin@buildroot:~/looptest$ ls -l
total 131080
drwxr-xr-x 2 sysadmin sudo 4096 avr 10 10:11 rootfs
-rw-r–r-- 1 sysadmin sudo 134217728 avr 10 14:09 rootfs.ext2

sysadmin@buildroot:~/looptest$ sudo mount -o loop,user,rw rootfs.ext2 rootfs

sysadmin@buildroot:~/looptest$ ls -l
total 131077
drwxr-xr-x 22 root root 1024 mar 18 2016 rootfs
-rw-r–r-- 1 sysadmin sudo 134217728 avr 10 14:10 rootfs.ext2

sysadmin@buildroot:~/looptest$ ls -l rootfs
total 42
drwxrwxr-x 2 root root 3072 mar 18 2016 bin
drwxrwxr-x 3 root root 1024 aoû 18 2014 data
drwxr-xr-x 3 root root 1024 mar 18 2016 dev
drwxr-xr-x 13 root root 1024 mar 18 2016 etc
drwxrwxr-x 2 root root 1024 déc 16 2014 exchange
drwxrwxr-x 2 root root 1024 aoû 18 2014 ext_data
drwxrwxr-x 3 root root 1024 avr 1 2014 home
drwxrwxr-x 4 root root 3072 mar 18 2016 lib
lrwxrwxrwx 1 root root 3 mar 18 2016 lib32 -> lib
lrwxrwxrwx 1 root root 11 mar 18 2016 linuxrc -> bin/busybox
drwx------ 2 root root 16384 mar 18 2016 lost+found
drwxrwxr-x 2 root root 1024 avr 1 2014 media
drwxrwxr-x 2 root root 1024 avr 1 2014 mnt
drwxrwxr-x 2 root root 1024 avr 1 2014 opt
drwxrwxr-x 2 root root 1024 avr 1 2014 proc
drwx------ 3 root root 1024 mar 18 2016 root
drwxrwxr-x 3 root root 1024 mar 18 2016 run
drwxr-xr-x 2 root root 3072 mar 18 2016 sbin
drwxrwxr-x 2 root root 1024 avr 1 2014 sys
drwxrwxrwt 3 root root 1024 mar 18 2016 tmp
drwxrwxr-x 8 root root 1024 aoû 18 2014 usr
drwxrwxr-x 5 root root 1024 mar 18 2016 var

And here is how I setup the container to allow mounting an image:

~$ lxc config device add c1 loop0 unix-block path=/dev/loop0
Device loop0 added to c1
~$ lxc config device add c1 loop1 unix-block path=/dev/loop1
Device loop1 added to c1
~$ lxc config device add c1 loop2 unix-block path=/dev/loop2
Device loop2 added to c1
~$ lxc config device add c1 loop3 unix-block path=/dev/loop3
Device loop3 added to c1
~$ lxc config device add c1 loop4 unix-block path=/dev/loop4
Device loop4 added to c1
~$ lxc config device add c1 loop5 unix-block path=/dev/loop5
Device loop5 added to c1
~$ lxc config device add c1 loop6 unix-block path=/dev/loop6
Device loop6 added to c1
~$ lxc config device add c1 loop7 unix-block path=/dev/loop7
Device loop7 added to c1
~$ lxc config device add c1 loop-control unix-char path=/dev/loop-control
Device loop-control added to c1
~$ lxc config set c1 raw.apparmor “mount,”
~$ lxc config set c1 security.privileged true

Can you show that the loop devices on the host are not already used by something else?

You can get a fresh and available loop device with

losetup -f

Before mounting image in container:

~/container-config$ losetup -f
/dev/loop0

After mounting image in container:

~/container-config$ losetup -f
/dev/loop1

configuring container unprivileged to have graphical apps working:

~/container-config$ lxc config set buildroot security.privileged false
~/container-config$ losetup -f
/dev/loop0

unprivileged container config (graphical apps ok, mounting image not ok):

~$ lxc config show c1
architecture: x86_64
config:
  raw.apparmor: mount,
  raw.idmap: both 1000 1001
  security.privileged: "false"
  volatile.base_image: c5bbef7f4e1c19f0104fd49b862b2e549095d894765c75c6d72775f1d98185ec
  volatile.eth0.hwaddr: 00:16:3e:b1:b7:d6
  volatile.idmap.base: "0"
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":165536,"Nsid":0,"Maprange":1001},{"Isuid":true,"Isgid":true,"Hostid":1000,"Nsid":1001,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":166538,"Nsid":1002,"Maprange":64534},{"Isuid":false,"Isgid":true,"Hostid":165536,"Nsid":0,"Maprange":1001},{"Isuid":true,"Isgid":true,"Hostid":1000,"Nsid":1001,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":166538,"Nsid":1002,"Maprange":64534}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":165536,"Nsid":0,"Maprange":1001},{"Isuid":true,"Isgid":true,"Hostid":1000,"Nsid":1001,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":166538,"Nsid":1002,"Maprange":64534},{"Isuid":false,"Isgid":true,"Hostid":165536,"Nsid":0,"Maprange":1001},{"Isuid":true,"Isgid":true,"Hostid":1000,"Nsid":1001,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":166538,"Nsid":1002,"Maprange":64534}]'
  volatile.last_state.power: RUNNING
devices:
  X0:
    path: /tmp/.X11-unix/X0
    source: /tmp/.X11-unix/X0
    type: disk
  Xauthority:
    path: /home/sysadmin/.Xauthority
    source: /home/sysadmin/.Xauthority
    type: disk
  loop-control:
    path: /dev/loop-control
    type: unix-char
  loop0:
    path: /dev/loop0
    type: unix-block
  loop1:
    path: /dev/loop1
    type: unix-block
  loop2:
    path: /dev/loop2
    type: unix-block
  loop3:
    path: /dev/loop3
    type: unix-block
  loop4:
    path: /dev/loop4
    type: unix-block
  loop5:
    path: /dev/loop5
    type: unix-block
  loop6:
    path: /dev/loop6
    type: unix-block
  loop7:
    path: /dev/loop7
    type: unix-block
  root:
    path: /
    type: disk
ephemeral: false
profiles:
- default
stateful: false
description: ""

privileged container config(graphical apps not ok, mounting image ok):

~$ lxc config set c1 security.privileged true
~$ lxc config show c1
architecture: x86_64
config:
  raw.apparmor: mount,
  raw.idmap: both 1000 1001
  security.privileged: "true"
  volatile.base_image: c5bbef7f4e1c19f0104fd49b862b2e549095d894765c75c6d72775f1d98185ec
  volatile.eth0.hwaddr: 00:16:3e:b1:b7:d6
  volatile.idmap.base: "0"
  volatile.idmap.next: '[]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":165536,"Nsid":0,"Maprange":1001},{"Isuid":true,"Isgid":true,"Hostid":1000,"Nsid":1001,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":166538,"Nsid":1002,"Maprange":64534},{"Isuid":false,"Isgid":true,"Hostid":165536,"Nsid":0,"Maprange":1001},{"Isuid":true,"Isgid":true,"Hostid":1000,"Nsid":1001,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":166538,"Nsid":1002,"Maprange":64534}]'
  volatile.last_state.power: RUNNING
devices:
  X0:
    path: /tmp/.X11-unix/X0
    source: /tmp/.X11-unix/X0
    type: disk
  Xauthority:
    path: /home/sysadmin/.Xauthority
    source: /home/sysadmin/.Xauthority
    type: disk
  loop-control:
    path: /dev/loop-control
    type: unix-char
  loop0:
    path: /dev/loop0
    type: unix-block
  loop1:
    path: /dev/loop1
    type: unix-block
  loop2:
    path: /dev/loop2
    type: unix-block
  loop3:
    path: /dev/loop3
    type: unix-block
  loop4:
    path: /dev/loop4
    type: unix-block
  loop5:
    path: /dev/loop5
    type: unix-block
  loop6:
    path: /dev/loop6
    type: unix-block
  loop7:
    path: /dev/loop7
    type: unix-block
  root:
    path: /
    type: disk
ephemeral: false
profiles:
- default
stateful: false
description: ""

Okay, I beautified the markup a bit. It should be easier for someone to fully replicate and figure out what’s wrong.

OK, thanks for your help.


Raphaël.