I’m trying to run Waydroid in Incus container, but without luck. When starting Waydroid, I see this error:
RuntimeError: Command failed: % mount -o ro /var/lib/waydroid/images/system.img /var/lib/waydroid/rootfs
Maybe someone solved this problem and can help me a bit?
Container details
Waydroid works, when installed on my vanilla Ubuntu 24.04 host (ZFS backend) and not nested inside Incus. It requires binder_linux
kernel module provided by default Ubuntu 24.04 kernel 6.8.0-52-generic (there’s no need for ashmem_linux
kernel module).
So for running Waydroid inside Incus, I need to:
- Make sure
binder_linux
kernel module is loaded - Enable system call interception for mount
This is my container:
incus launch images:ubuntu/24.04/cloud waydroid \
-p default \
-p gui \
-c security.nesting=true \
-c linux.kernel_modules=binder_linux \
-c security.syscalls.intercept.mount=true \
-c security.syscalls.intercept.mount.fuse=ext2=fuse2fs
I’m using ext2=fuse2fs
because that seem to be the file system of Android images used by Waydroid. Changing ext2
to ext4
didn’t make a difference.
I also tried without fuse2fs
:
-c security.syscalls.intercept.mount=true \
-c security.syscalls.intercept.mount.shift=true \
-c security.syscalls.intercept.mount.allowed=ext2
The gui profile for this container is very simple:
gui profile
config:
raw.idmap: |-
uid 1000 1000
gid 1000 1000
description: GUI Wayland and xWayland profile with pipewire and pulseaudio, shifting enabled for all socket.
devices:
gpu:
gid: "44"
type: gpu
pipewire_manager_socket:
path: /mnt/.container_sockets/pipewire-0-manager
shift: "true"
required: "false"
source: /run/user/1000/pipewire-0-manager
type: disk
pipewire_socket:
path: /mnt/.container_sockets/pipewire-0
shift: "true"
required: "false"
source: /run/user/1000/pipewire-0
type: disk
pulseaudio_socket:
path: /mnt/.container_sockets/native
shift: "true"
required: "false"
source: /run/user/1000/pulse/native
type: disk
wayland_socket:
path: /mnt/.container_sockets/wayland-0
shift: "true"
required: "false"
source: /run/user/1000/wayland-0
type: disk
xauthority_cookie:
path: /mnt/.container_sockets/.mutter-Xwaylandauth.copy
shift: "true"
required: "false"
source: /run/user/1000/.mutter-Xwaylandauth.copy
type: disk
xwayland_socket:
path: /mnt/.container_sockets/X1
shift: "true"
required: "false"
source: /tmp/.X11-unix/X1
type: disk
Next I logged into the container, installed fuse2fs
and some basic packages, and added ubuntu user to two groups:
incus exec waydroid -- sudo --login --user ubuntu
sudo apt install fuse2fs pulseaudio-utils dbus-user-session nano bash-completion
sudo usermod -a -G video,render "$LOGNAME"
In /home/ubuntu/.profile
file, I added some lines that link sockets to their proper locations:
.profile file
[[ ! -d "${/run/user/1000}/pulse" ]] && mkdir -m 700 "${/run/user/1000}/pulse"
[[ -S "${/mnt/.container_sockets}/native" && -d "${/run/user/1000}/pulse" && ! -e "${/run/user/1000}/pulse/native" ]] && ln -s "${/mnt/.container_sockets}/native" "${/run/user/1000}/pulse/native"
[[ -S "${/mnt/.container_sockets}/pipewire-0" && ! -e "${/run/user/1000}/pipewire-0" ]] && ln -s "${/mnt/.container_sockets}/pipewire-0" "${/run/user/1000}/pipewire-0"
[[ -S "${/mnt/.container_sockets}/pipewire-0-manager" && ! -e "${/run/user/1000}/pipewire-0-manager" ]] && ln -s "${/mnt/.container_sockets}/pipewire-0-manager" "${/run/user/1000}/pipewire-0-manager"
[[ -S "${/mnt/.container_sockets}/wayland-0" && ! -e "${/run/user/1000}/wayland-0" ]] && ln -s "${/mnt/.container_sockets}/wayland-0" "${/run/user/1000}/wayland-0"
[[ -S "${/mnt/.container_sockets}/X0" && ! -e "${/tmp/.X11-unix}/X0" ]] && ln -s "${/mnt/.container_sockets}/X0" "${/tmp/.X11-unix}/X0"
[[ -S "${/mnt/.container_sockets}/X1" && ! -e "${/tmp/.X11-unix}/X1" ]] && ln -s "${/mnt/.container_sockets}/X1" "${/tmp/.X11-unix}/X1"
[[ -f "${/mnt/.container_sockets}/.mutter-Xwaylandauth.copy" && ! -e "${/run/user/1000}/.mutter-Xwaylandauth.copy" ]] && cp "${/mnt/.container_sockets}/.mutter-Xwaylandauth.copy" "${/run/user/1000}/.mutter-Xwaylandauth.copy"
export WAYLAND_DISPLAY=wayland-0
export XDG_SESSION_TYPE=wayland
export QT_QPA_PLATFORM=wayland
export DISPLAY=:1
export XAUTHORITY=${/run/user/1000}/.mutter-Xwaylandauth.copy
Finally, I restarted the container:
exit
incus restart waydroid
incus exec waydroid -- sudo --login --user ubuntu
Installing Waydroid
I followed official instructions:
sudo apt install curl ca-certificates -y
curl -s https://repo.waydro.id | sudo bash
sudo apt install waydroid -y
Then initialized Waydroid:
sudo waydroid init -s GAPPS
This downloads Android images (seems they are ext2
) and starts a service:
$ file /var/lib/waydroid/images/*.img
/var/lib/waydroid/images/system.img: Linux rev 1.0 ext2 filesystem data, UUID=a09c7f74-67d7-4fd8-b092-251f4e05593e (extents) (large files) (huge files)
/var/lib/waydroid/images/vendor.img: Linux rev 1.0 ext2 filesystem data, UUID=5f40d370-5918-427a-9f92-2458da269fc3, volume name "vendor" (extents) (large files) (huge files)
Note: Starting a container with a Waydroid installed takes about 30 seconds, so don’t be surprised.
Error when running Waydroid
When starting Waydroid I get this error:
$ waydroid show-full-ui
[10:57:01] Starting waydroid session
[10:57:01] RuntimeError: Command failed: % mount -o ro /var/lib/waydroid/images/system.img /var/lib/waydroid/rootfs
Logs tell me that the mount
failed, because the destination directory doesn’t exist:
$ cat /var/lib/waydroid/waydroid.log
(000372) [10:57:57] % mount -o ro /var/lib/waydroid/images/system.img /var/lib/waydroid/rootfs
mount: /var/lib/waydroid/rootfs: mount failed: No such file or directory.
But that’s not true:
$ ll /var/lib/waydroid/rootfs
total 17K
drwxr-xr-x 2 root root 2 sty 30 22:01 ./
drwxr-xr-x 9 root root 12 sty 31 23:18 ../
When using mount
command by hand I get the same error:
$ sudo mount -o ro /var/lib/waydroid/images/system.img /var/lib/waydroid/rootfs
mount: /var/lib/waydroid/rootfs: mount failed: No such file or directory.
But when using fuse2fs
(it was installed before any mount
operation) I get a success:
$ sudo fuse2fs -o ro /var/lib/waydroid/images/system.img /var/lib/waydroid/rootfs
Mounting read-only.
Unfortunately, Waydroid doesn’t recognize that and won’t start, thinking it wasn’t initialized:
$ waydroid show-full-ui
ERROR: WayDroid is not initialized, run "waydroid init"
Questions
- How to get rid of the
mount
error? - I’m using ZFS backend. Could this be the cause of the issue?
- Should I use other value than
ext2=fuse2fs
forsecurity.syscalls.intercept.mount.fuse
? Theext4
didn’t work.
I will be grateful for any help.