我正在尝试找到我的显示插座,以便将其传递到容器中。我希望它位于/tmp/X11.unix
或中/run/user/xxxx/wayland-0
,但两者都不存在。我正在使用 KDE Plasma 和 X11。
答案1
根据注释中看到的确切结果,系统可能已切换为仅使用抽象套接字,或者 unix 套接字文件已被删除,或者 X 服务器本身在其他安装命名空间中运行,该命名空间将在备用命名空间中隐藏套接字/tmp
(就像 systemd 的一些设置PrivateTmp=yes
一样)或任何其他类似的事情。无论如何,不能使用经典的 unix 套接字(对于/tmp
安装命名空间中的备用套接字,它应该是可访问的,但不能绑定安装以便在容器中使用)。
在相当传统的 X11 显示器上,我可以比较以下各项:
# ss -xlnp src == unix:/tmp/.X11-unix/X0
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
u_str LISTEN 0 4096 /tmp/.X11-unix/X0 20428 * 0 users:(("Xorg",pid=1287,fd=8))
和:
# ss -xlnp src == unix:@/tmp/.X11-unix/X0
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
u_str LISTEN 0 4096 @/tmp/.X11-unix/X0 20427 * 0 users:(("Xorg",pid=1287,fd=7))
同一过程提供了使用两种不同套接字类型的两种方法。前者是带有文件系统的经典 unix 套接字,而/tmp/.X11-unix/X0
后者是一个(Linux 特定)抽象 unix 套接字没有文件系统存在。其实是网络命名空间绑定。这意味着它无法在其他网络命名空间(例如容器)中轻松使用,但通常可以被代理。
人们可以使用像这样的工具socat
从经典 UNIX 套接字中继到抽象套接字。例如,这将在其通常的位置返回这样的套接字:
socat unix-listen:/tmp/.X11-unix/X0,umask=000,fork abstract-connect:/tmp/.X11-unix/X0
只要在 X11 内授予足够的权限(例如:xhost +si:localuser:someuser
用户someuser
运行该socat
进程)。
一旦socat
运行该命令,就可以再次使用容器技术提供的常用绑定安装方法来访问容器内的该套接字。
否则,人们甚至可以想象停留在主机网络命名空间(以访问抽象套接字)并切换到容器的挂载命名空间以直接在那里创建一个经典的 unix 套接字,但如果这不是工具本身进行切换,则意味着命令(例如socat
)必须在容器中可用,并且很可能所有内容都必须以 root 身份运行(从主机)才能获得足够的权限。
例如,对于一个名为 LXC 的容器,somecontainer
该容器已在运行并socat
安装了该命令,则可以在主机上运行:
作为拥有 X11 显示器的用户:
xhost +si:localuser:root
作为根用户:
nsenter -t $(lxc-info -Hp -n somecontainer) --mount -- sh -c 'mkdir -p -m 1777 /tmp/.X11-unix; exec socat unix-listen:/tmp/.X11-unix/X0,umask=000,fork abstract-connect:/tmp/.X11-unix/X0'
注意:Docker 的等效项lxc-info -Hp -n somecontainer
是docker inspect --format '{{.State.Pid}}' somecontainer
.
对于 Wayland 套接字,相同的方法可能会失败,因为 Wayland 协议还在 unix 套接字通信中将文件描述符作为旁路数据传递,并且socat
对此一无所知。