Xserver inside LXC container: xf86OpenConsole: Switching VT failed

Dear all,

I am trying to run an Xserver inside a priviledged LXC container by giving the container access to the hardware. Unfortunately I cannot get it to work. When I try to startx I get the following error:

xf86OpenConsole: Switching VT failed

System is Intel Bay Trail with Intel HD graphics, the container is Debian/Devuan Stable. LXC is version 2.1.1.

I am trying to run the entire x11 server inside the container with direct access to the hardware. I am aware that there is a solution to run the server on the host and only the apps in the container but that is not what I am looking for.

Any help would be really appreciated! Please help I am really stuck here…

Thank you,
Alex

config of the LXC container:

lxc.cgroup.devices.allow = c 226:0 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:7 rwm
lxc.cgroup.devices.allow = c 4:8 rwm

Script inside container:

mknod -m 666 /dev/dri/card0 c 226 0
mknod -m 666 /dev/tty0 c 4 7
mknod -m 666 /dev/tty7 c 4 7
mknod -m 666 /dev/tty8 c 4 8

Error message from Xorg

[ 4733.780]
X.Org X Server 1.19.2
Release Date: 2017-03-02
[ 4733.781] X Protocol Version 11, Revision 0
[ 4733.781] Build Operating System: Linux 4.9.0-8-amd64 x86_64 Debian
[ 4733.781] Current Operating System: Linux desktop 4.14.95 #0 SMP Wed Jan 30 12:21:02 2019 x86_64
[ 4733.781] Kernel command line: BOOT_IMAGE=/boot/vmlinuz root=PARTUUID=3bbf27a1-02 rootfstype=ext4 rootwait i915.modeset=0 acpi_enforce_resources=lax console=tty0 console=ttyS0,115200n8 noinitrd
[ 4733.781] Build Date: 03 November 2018 03:09:11AM
[ 4733.781] xorg-server 2:1.19.2-1+deb9u5 (Debian -- User Support)
[ 4733.781] Current version of pixman: 0.34.0
[ 4733.781] Before reporting problems, check http://wiki.x.org
to make sure that you have the latest version.
[ 4733.781] Markers: (–) probed, () from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
[ 4733.782] (==) Log file: “/var/log/Xorg.0.log”, Time: Sat May 25 18:16:33 2019
[ 4733.783] (==) Using system config directory “/usr/share/X11/xorg.conf.d”
[ 4733.783] (==) No Layout section. Using the first Screen section.
[ 4733.783] (==) No screen section available. Using defaults.
[ 4733.783] (
) |–>Screen “Default Screen Section” (0)
[ 4733.783] (**) | |–>Monitor “”
[ 4733.784] (==) No monitor specified for screen “Default Screen Section”.
Using a default monitor configuration.
[ 4733.784] (==) Automatically adding devices
[ 4733.784] (==) Automatically enabling devices
[ 4733.784] (==) Automatically adding GPU devices
[ 4733.784] (==) Max clients allowed: 256, resource mask: 0x1fffff
[ 4733.784] (WW) The directory “/usr/share/fonts/X11/cyrillic” does not exist.
[ 4733.784] Entry deleted from font path.
[ 4733.784] (==) FontPath set to:
/usr/share/fonts/X11/misc,
/usr/share/fonts/X11/100dpi/:unscaled,
/usr/share/fonts/X11/75dpi/:unscaled,
/usr/share/fonts/X11/Type1,
/usr/share/fonts/X11/100dpi,
/usr/share/fonts/X11/75dpi,
built-ins
[ 4733.784] (==) ModulePath set to “/usr/lib/xorg/modules”
[ 4733.784] (II) The server relies on udev to provide the list of input devices.
If no devices become available, reconfigure udev or disable AutoAddDevices.
[ 4733.784] (II) Loader magic: 0x56489ee7ee00
[ 4733.784] (II) Module ABI versions:
[ 4733.784] X.Org ANSI C Emulation: 0.4
[ 4733.784] X.Org Video Driver: 23.0
[ 4733.784] X.Org XInput driver : 24.1
[ 4733.784] X.Org Server Extension : 10.0
[ 4733.787] (–) using VT number 2
[ 4733.787] (II) systemd-logind: logind integration requires -keeptty and -keeptty was not provided, disabling logind integration
[ 4733.788] (II) xfree86: Adding drm device (/dev/dri/card0)
[ 4733.793] (–) PCI:*(0:0:2:0) 8086:0f31:1458:1000 rev 14, Mem @ 0xd0000000/4194304, 0xc0000000/268435456, I/O @ 0x0000f080/8, BIOS @ 0x???/131072
[ 4733.793] (II) LoadModule: “glx”
[ 4733.793] (II) Loading /usr/lib/xorg/modules/extensions/libglx.so
[ 4733.797] (II) Module glx: vendor=“X.Org Foundation”
[ 4733.798] compiled for 1.19.2, module version = 1.0.0
[ 4733.798] ABI class: X.Org Server Extension, version 10.0
[ 4733.798] (==) Matched modesetting as autoconfigured driver 0
[ 4733.798] (==) Matched fbdev as autoconfigured driver 1
[ 4733.798] (==) Matched vesa as autoconfigured driver 2
[ 4733.798] (==) Assigned the driver to the xf86ConfigLayout
[ 4733.798] (II) LoadModule: “modesetting”
[ 4733.798] (II) Loading /usr/lib/xorg/modules/drivers/modesetting_drv.so
[ 4733.799] (II) Module modesetting: vendor=“X.Org Foundation”
[ 4733.799] compiled for 1.19.2, module version = 1.19.2
[ 4733.799] Module class: X.Org Video Driver
[ 4733.799] ABI class: X.Org Video Driver, version 23.0
[ 4733.799] (II) LoadModule: “fbdev”
[ 4733.800] (II) Loading /usr/lib/xorg/modules/drivers/fbdev_drv.so
[ 4733.800] (II) Module fbdev: vendor=“X.Org Foundation”
[ 4733.800] compiled for 1.19.0, module version = 0.4.4
[ 4733.800] Module class: X.Org Video Driver
[ 4733.800] ABI class: X.Org Video Driver, version 23.0
[ 4733.800] (II) LoadModule: “vesa”
[ 4733.801] (II) Loading /usr/lib/xorg/modules/drivers/vesa_drv.so
[ 4733.801] (II) Module vesa: vendor=“X.Org Foundation”
[ 4733.801] compiled for 1.19.0, module version = 2.3.4
[ 4733.801] Module class: X.Org Video Driver
[ 4733.801] ABI class: X.Org Video Driver, version 23.0
[ 4733.801] (II) modesetting: Driver for Modesetting Kernel Drivers: kms
[ 4733.801] (II) FBDEV: driver for framebuffer: fbdev
[ 4733.801] (II) VESA: driver for VESA chipsets: vesa
[ 4733.802] (WW) xf86OpenConsole: VT_GETSTATE failed: Inappropriate ioctl for device
[ 4733.802] (WW) xf86OpenConsole: VT_ACTIVATE failed: Inappropriate ioctl for device
[ 4733.802] (EE)
Fatal server error:
[ 4733.802] (EE) xf86OpenConsole: Switching VT failed
[ 4733.802] (EE)
[ 4733.802] (EE)
Please consult the The X.Org Foundation support
at http://wiki.x.org
for help.
[ 4733.802] (EE) Please also check the log file at “/var/log/Xorg.0.log” for additional information.
[ 4733.802] (EE)
[ 4733.803] (WW) xf86CloseConsole: KDSETMODE failed: Inappropriate ioctl for device
[ 4733.803] (WW) xf86CloseConsole: VT_GETMODE failed: Inappropriate ioctl for device
[ 4733.803] (EE) Server terminated with error (1). Closing log file.

Off the top of my head, you’d need read/write permissions to /dev/tty and /dev/tty* as well as prevent liblxc from turning those into symlinks to pts devices.

lxc.tty.max=0 and possibly lxc.autodev=0 may fix this for you.

Hi Stéphane,

Thank you for your reply. I did several more tests with your suggested changes but unfortunately it still does not work. Here is the log:

[ 261.970]
X.Org X Server 1.20.3
X Protocol Version 11, Revision 0
[ 261.970] Build Operating System: Linux 4.9.0-8-amd64 x86_64 Debian
[ 261.970] Current Operating System: Linux desktop 4.14.95 #0 SMP Wed Jan 30 12:21:02 2019 x86_64
[ 261.971] Kernel command line: BOOT_IMAGE=/boot/vmlinuz root=PARTUUID=3bbf27a1-02 rootfstype=ext4 rootwait i915.modeset=0 acpi_enforce_resources=lax console=tty0 console=ttyS0,115200n8 noinitrd
[ 261.971] Build Date: 25 October 2018 06:15:23PM
[ 261.971] xorg-server 2:1.20.3-1 (Debian -- User Support)
[ 261.971] Current version of pixman: 0.36.0
[ 261.971] Before reporting problems, check http://wiki.x.org
to make sure that you have the latest version.
[ 261.971] Markers: (–) probed, () from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
[ 261.971] (==) Log file: “/var/log/Xorg.0.log”, Time: Fri May 31 12:55:00 2019
[ 261.972] (==) Using system config directory “/usr/share/X11/xorg.conf.d”
[ 261.972] (==) No Layout section. Using the first Screen section.
[ 261.973] (==) No screen section available. Using defaults.
[ 261.973] (
) |–>Screen “Default Screen Section” (0)
[ 261.973] (**) | |–>Monitor “”
[ 261.974] (==) No monitor specified for screen “Default Screen Section”.
Using a default monitor configuration.
[ 261.974] (==) Automatically adding devices
[ 261.974] (==) Automatically enabling devices
[ 261.974] (==) Automatically adding GPU devices
[ 261.974] (==) Max clients allowed: 256, resource mask: 0x1fffff
[ 261.974] (WW) The directory “/usr/share/fonts/X11/cyrillic” does not exist.
[ 261.974] Entry deleted from font path.
[ 261.974] (==) FontPath set to:
/usr/share/fonts/X11/misc,
/usr/share/fonts/X11/100dpi/:unscaled,
/usr/share/fonts/X11/75dpi/:unscaled,
/usr/share/fonts/X11/Type1,
/usr/share/fonts/X11/100dpi,
/usr/share/fonts/X11/75dpi,
built-ins
[ 261.974] (==) ModulePath set to “/usr/lib/xorg/modules”
[ 261.974] (II) The server relies on udev to provide the list of input devices.
If no devices become available, reconfigure udev or disable AutoAddDevices.
[ 261.974] (II) Loader magic: 0x5648f5cbbe20
[ 261.974] (II) Module ABI versions:
[ 261.974] X.Org ANSI C Emulation: 0.4
[ 261.974] X.Org Video Driver: 24.0
[ 261.975] X.Org XInput driver : 24.1
[ 261.975] X.Org Server Extension : 10.0
[ 261.978] (–) using VT number 2
[ 261.978] (II) systemd-logind: logind integration requires -keeptty and -keeptty was not provided, disabling logind integration
[ 261.979] (II) xfree86: Adding drm device (/dev/dri/card0)
[ 261.993] (–) PCI:*(0@0:2:0) 8086:0f31:1458:1000 rev 14, Mem @ 0xd0000000/4194304, 0xc0000000/268435456, I/O @ 0x0000f080/8, BIOS @ 0x???/131072
[ 261.993] (II) LoadModule: “glx”
[ 261.993] (II) Loading /usr/lib/xorg/modules/extensions/libglx.so
[ 261.997] (II) Module glx: vendor=“X.Org Foundation”
[ 261.997] compiled for 1.20.3, module version = 1.0.0
[ 261.997] ABI class: X.Org Server Extension, version 10.0
[ 261.997] (==) Matched modesetting as autoconfigured driver 0
[ 261.997] (==) Matched fbdev as autoconfigured driver 1
[ 261.997] (==) Matched vesa as autoconfigured driver 2
[ 261.997] (==) Assigned the driver to the xf86ConfigLayout
[ 261.997] (II) LoadModule: “modesetting”
[ 261.998] (II) Loading /usr/lib/xorg/modules/drivers/modesetting_drv.so
[ 261.998] (II) Module modesetting: vendor=“X.Org Foundation”
[ 261.998] compiled for 1.20.3, module version = 1.20.3
[ 261.998] Module class: X.Org Video Driver
[ 261.998] ABI class: X.Org Video Driver, version 24.0
[ 261.998] (II) LoadModule: “fbdev”
[ 261.999] (II) Loading /usr/lib/xorg/modules/drivers/fbdev_drv.so
[ 261.999] (II) Module fbdev: vendor=“X.Org Foundation”
[ 261.999] compiled for 1.20.0, module version = 0.5.0
[ 261.999] Module class: X.Org Video Driver
[ 261.999] ABI class: X.Org Video Driver, version 24.0
[ 261.999] (II) LoadModule: “vesa”
[ 262.000] (II) Loading /usr/lib/xorg/modules/drivers/vesa_drv.so
[ 262.001] (II) Module vesa: vendor=“X.Org Foundation”
[ 262.001] compiled for 1.20.1, module version = 2.4.0
[ 262.001] Module class: X.Org Video Driver
[ 262.001] ABI class: X.Org Video Driver, version 24.0
[ 262.001] (II) modesetting: Driver for Modesetting Kernel Drivers: kms
[ 262.001] (II) FBDEV: driver for framebuffer: fbdev
[ 262.001] (II) VESA: driver for VESA chipsets: vesa
[ 262.001] (EE)
Fatal server error:
[ 262.002] (EE) xf86OpenConsole: Cannot open virtual console 2 (No such file or directory)
[ 262.002] (EE)
[ 262.002] (EE)
Please consult the The X.Org Foundation support
at http://wiki.x.org
for help.
[ 262.002] (EE) Please also check the log file at “/var/log/Xorg.0.log” for additional information.
[ 262.002] (EE)
[ 262.002] (WW) xf86CloseConsole: KDSETMODE failed: Bad file descriptor
[ 262.002] (WW) xf86CloseConsole: VT_GETMODE failed: Bad file descriptor
[ 262.003] (EE) Server terminated with error (1). Closing log file.

Here is the config file for the container:

lxc.include = /usr/share/lxc/config/debian.common.conf
lxc.arch = linux64
lxc.rootfs.path = dir:/mnt/container/lxc/desktop/rootfs
lxc.uts.name = desktop
lxc.net.0.type = veth
lxc.net.0.link = br-lan
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:11:22:33:44:8b
lxc.cgroup.devices.allow = c 226:0 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:7 rwm
lxc.cgroup.devices.allow = c 4:8 rwm
lxc.tty.max=0
LXC.autodev=0

enablling lxc.autodev=0 unfortunately also did not solve the problem. Any ideas what I could try next? What is the reason for the message:

xf86OpenConsole: Cannot open virtual console 2 (No such file or directory)

Ok, so you’re making progress. The no such file or directory indicates that those /dev/tty and /dev/ttyX devices may be missing, which is a bit better than before where they were there but wrong.

You’ll likely want a script which mknod them to the right type (same as your host) and then things may end up just working.

Hi Stéphane,

Thank you very much. I tried to experiment with different settings for mknodes but I still cannot get it to work. Here are the devices in the container:

c–x–x–x 1 root root 136, 2 Jun 1 15:00 console
drwxr-xr-x 2 root root 60 Jun 1 14:25 dri
lrwxrwxrwx 1 root root 13 Jun 1 14:25 fd → /proc/self/fd
crw-rw-rw- 1 root root 1, 7 Jun 1 14:25 full
srw-rw-rw- 1 root root 0 Jun 1 14:25 log
crw-rw-rw- 1 root root 1, 3 Jun 1 14:25 null
crw-rw-rw- 1 root root 5, 2 Jun 1 14:25 ptmx
drwxr-xr-x 2 root root 0 Jun 1 14:25 pts
crw-rw-rw- 1 root root 1, 8 Jun 1 14:25 random
drwxrwxrwt 2 root root 60 Jun 1 14:25 shm
lrwxrwxrwx 1 root root 15 Jun 1 14:25 stderr → /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun 1 14:25 stdin → /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jun 1 14:25 stdout → /proc/self/fd/1
crw-rw-rw- 1 root root 5, 0 Jun 1 14:25 tty
crw-rw-rw- 1 root root 4, 0 Jun 1 14:25 tty0
crw-rw-rw- 1 root root 4, 7 Jun 1 14:25 tty7
crw-rw-rw- 1 root root 4, 8 Jun 1 14:25 tty8
crw-rw-rw- 1 root root 1, 9 Jun 1 14:25 urandom
prw-r----- 1 root adm 0 Jun 1 14:25 xconsole
crw-rw-rw- 1 root root 1, 5 Jun 1 14:25 zero

For comparison, here are the devices on the host (I have deleted all lines that are not in the container for clarity):

crw------- 1 root root 14, 3 May 31 12:50 dsp

crw-rw-rw- 1 root root 1, 7 May 31 12:50 full

srw-rw-rw- 1 root root 0 May 31 12:50 log

crw-rw-rw- 1 root root 1, 3 May 31 12:50 null

crw-rw-rw- 1 root root 5, 2 Jun 1 15:04 ptmx
drwxr-xr-x 2 root root 0 May 31 12:50 pts
crw-rw-rw- 1 root root 1, 8 May 31 12:50 random
crw------- 1 root root 10, 57 May 31 12:50 rfkill

lrwxrwxrwx 1 root root 8 May 31 12:50 shm → /tmp/shm

crw-rw-rw- 1 root root 5, 0 Jun 1 14:25 tty
crw------- 1 root root 4, 0 May 31 12:50 tty0

crw------- 1 root root 4, 7 May 31 12:50 tty7
crw------- 1 root root 4, 8 May 31 12:50 tty8

Here is the mknodes.sh that I have created to create the missing nodes in the container:

cd /dev
mkdir -p dri
mknod -m 666 /dev/dri/card0 c 226 0
#mknod -m 666 /dev/fb0 c 29 0
#mknod -m 666 /dev/tty c 4 1
mknod -m 666 /dev/tty0 c 4 0
mknod -m 666 /dev/tty7 c 4 7
mknod -m 666 /dev/tty8 c 4 8

Do you have any idea/suggestion what I could try next?

i am wondering about this concept of switching VTs. is it possible, in a purely text use case, to have the host using a couple of specific VTs while a container uses 2 more and another container does likewise. will the chvt command work in the container if they have full privileges?

Hi Phil,

I will try and report back. To be honest, so far I did not work with VTs at all. I just booted the system, started the container with lxc-start -n desktop end then entered the container with lxc-attach -n desktop.

Thank you,
alex

So I installed the package kbd. Interestingly the screen slightly changed at the installation of the tool. The font looked a bit differently. I can change to VT 8 but I only see a blinking cursor and cannot make any entries. With Ctr.+Alt+F1 I could get back to screen 1 and make my entries. No error messages have been displayed on the screen.

sounds like X did not get notified of the VT switch so the hardware stayed in text mode. normally X switches the text/graphical mode. so this notification needs to get passed down to the container, too, so X therein can be notified and can switch the hardware to graphical mode.

What is your recommendation to pass the notification? I have compiled the i915 graphics driver in the kernel (system is a Intel HD Graphics 515). What should I do/change to pass the notification down to the container?

i really don’t know. it is probably not a display hardware thing. since the kernel normally carries out VT switching, it surely starts there, since the kernel does not do the video mode switching. it lets X do that. it is probably some kind of VT logistics thing. i don’t have any idea how VTs are handled by containers, yet, not even just in text mode. does each container have its own tty1? how is it decided which VT goes to which container and as which virtual VT? just in text mode its already complicated.

OK, thank you anyhow! Maybe there is someone else who has an idea? Any help would really be appreciated!

in addition to notifying X that VT switching came to its VT so it can take control of the hardware, again (and reload the mode), X also needs to be notified when to release control of the hardware. i believe it has to restore text mode since the kernel apparently does not know how to do this on the variety of hardware X knows about (and BIOS can do via a branch to video ROM specific to that hardware in x86 CPU mode). so there need to be 2 ways to notify. but the latter is easy if switched by keyboard input … X gets the input. but it also can happen by some root process doing the ioctrl call that the chvt command does. now i remember reading somewhere, that X was sent a HUP signal. that is not enough to tell X what is going on though it may be able to guess most of it by whether it has hardware control now, or not. in the case of switching to X it can know. in the case of switching away, either it has to finish the VT switch when the text mode is restored (if going to another instance of X that next X will be notified to take over the hardware), or it has to sync with the kernel to let the kernel finish the VT switch. i suspect the latter can be done via another ioctl syscall.

note that the specific VT being displayed is not relevant to graphics mode. once X has taken over the hardware, it has control of what is displayed. 2 Xs taking control together can at best make for a flashy wrong display to at worse cause a hardware crash that can spread to everywhere (even the CPU(s)).

in the case of the black screen you got. it might still be in text mode (X didn’t get notified or it did but didn’t switch mode for some reason, or couldn’t for some reason, or maybe it did partially and froze), but the keyboard has been taken over, so you can’t switch manually. you could test this by having a timed process in the background on the host (not in a container) do sudo chvt 1 to see if you get text mode back to console 1, or not.

some reading here

i am now worried that VTs are a host-only feature creating up to 63 hardware devices (plus the generic /dev/tty). these can, perhaps, be mapped or permitted for use in a container, but that would be done by device major,minor, not by c device in the file system. then it would matter what all, devices an ioctl calls, root processes in that container are allowed to do. i need to go back and get deeper into cgroups when i get my current project done (probably many days

about 2h later:

i had to reboot due to a lightdm crash, so i started thinking about lightdm and am wondering if it, or some other display manager, can do the VT switching that is needed. it switches between the 10 instances of Xorg i have running (no containers here, yet) for 10 different concurrently logged in users. most of the time it works just fine.

Hi Phil, any updates for your experiments? Any logs or other test that I could help with? I have followed the instructions from this blog:

https://mraw.org/blog/2011/04/05/Running_X_from_LXC/

Based on the author of this blog, it is possible to run an X server inside the container.

i have not had time to run experiments and probably won’t for quite a long time (weeks). that blog looks interesting from the first read. i’ll need to re-read it a few times to really get a good feel for what it does.

My setup for running Xserver inside an LXC container is described in a new thread.

Sorry for the late reply. I was traveling. Thank you! Will try tonight and report back.

i guess, ultimately, we need to get X to not even try a VT switch. it will need access to the hardware. that much appears to be done.