The previous article introduced the read-only mount host /tmp/.X11-unix to the vm1 container /var/lib/lxc/vm1/rootfs/tmp/.X11-unix, to realize the container running the X desktop environment, and because it is read-only, it is protected The host /tmp/.X11-unix is not destroyed by the container, but therefore the container's X Server failed to create a socket file, causing some applications such as ssh's X11 forwarding to rely on the socket file and cannot be used in the container
Socat is a powerful port forwarding tool that can implement socket forwarding, just like ssh's X11 forwarding. This article is to implement socat forwarding X, so that the container can run the X desktop environment and keep the container /var/lib/lxc/ vm1/rootfs/tmp/.X11-unix can be written
1.Review the previous article ( https://blog.51cto.com/13752418/2461908 ) the
host started Xephyr to create a socket file (under /tmp/.X11-unix/) and abstract unix domain
read-only mount host/ tmp/.X11-unix/ to container/tmp/.X11-unix/, that is, the host socket file is shared to the container. The
container can only communicate with the host through the host socket file, and cannot
start Xephyr through the host abstract unix domain container. Runs on the host Xephyr (via the host socket file), and creates a container abstract unix domain. Because the container is read-only /tmp/.X11-unix/, the container cannot create a socket file. The
container's graphics program abstracts unix through the container The domain runs on the container Xephyr
and the X11 forwarding of ssh happens to only pass through the socket file, not the abstract unix domain.
1) Host
linlin@debian:~$ netstat -lp |grep X
(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.)
Active UNIX domain sockets (only servers)
unix 2 [ ACC ] STREAM LISTENING 19548 - @/tmp/.X11-unix/X0
unix 2 [ ACC ] STREAM LISTENING 19549 - /tmp/.X11-unix/X0
unix 2 [ ACC ] STREAM LISTENING 29044 Xephyr /tmp/.X11-unix/X1
unix 2 [ ACC ] STREAM LISTENING 29043 Xephyr @/tmp/.X11-unix/X1
linlin@debian:~$
X1 is the host Xephyr
2) Container
linlin@vm1:~$ ls -a /tmp |grep X*lock
.X30-lock
linlin@vm1:~$ ls /tmp/.X11-unix
X0
X1
linlin@vm1:~$ netstat -lp |grep X
Active UNIX domain sockets (only servers)
unix 2 [ ACC ] STREAM LISTENING 29054 Xephyr @/tmp/.X11-unix/X30
linlin@vm1:~$
X0 and X1 are the host,
X30 is the container Xephyr, only the abstract unix domain, no socket file
2. Edit the container configuration file /var/lib/lxc/vm1/config and
add the following line in the hostlxc.mount.entry = /tmp/.X11-unix tmp/.X11-unix-host none bind,ro,optional,create=dir
As in the previous article, read-only mount host /tmp/.X11-unix, but the path in the container becomes tmp/.X11-unix-host, and the path name is whatever you want, as long as it is not tmp/.X11-unix
, the original in the container Do not mount the path /tmp/.X11-unix with --bind
3. Host
ordinary users run the following commands
linlin@debian:~$ ls /tmp/.X11-unix/
X0
linlin@debian:~$
X0 means there is display number 0
Run Xephyr and create a new display number 1linlin@debian:~$ Xephyr :1
4. Container
1) install socat
root@vm1:/# apt-get install socat
2) List the display number
linlin@vm1:~$ ls /tmp/.X11-unix-host
X0 X1
linlin@vm1:~$
You can see the host's X0, X1 after mount --bind
linlin@vm1:~$ ls -l /tmp/.X11-unix
(空)
linlin@vm1:~$
Visible container has no display number
3) Forward X1 from /tmp/.X11-unix-host to the path /tmp/.X11-unix/
linlin@vm1:~$ socat UNIX-LISTEN:/tmp/.X11-unix/X20,fork UNIX-CONNECT:/tmp/.X11-unix-host/X1&
linlin@vm1:~$ ls -l /tmp/.X11-unix
srwxr-xr-x 1 linlin linlin 0 3月 22 02:40 X20
linlin@vm1:~$
It can be seen that the socket file X20 has been created under /tmp/.X11-unix/, which is the display number X20 (that is, the host's [Xephyr :1])
4) Run Xephyr to
specify the creation display number 30
linlin@vm1:~$ DISPLAY=:20 Xephyr :30 &
458 pts/1 00:00:00 Xephyr
linlin@vm1:~$ ls -l /tmp/.X11-unix
srwxr-xr-x 1 linlin linlin 0 3月 22 02:40 X20
linlin@vm1:~$ netstat |grep X
Active UNIX domain sockets (w/o servers)
unix 3 [ ] STREAM CONNECTED 321359 /tmp/.X11-unix/X20
linlin@vm1:~$ netstat -lp |grep X
Active UNIX domain sockets (only servers)
unix 2 [ ACC ] STREAM LISTENING 318282 451/socat /tmp/.X11-unix/X20
linlin@vm1:~$
Did not see X30
linlin@vm1:~$ DISPLAY=:30 xlogo
Can't open display: :30
linlin@vm1:~$
Failed to run the graphics program on X30 because the display number 30 does not exist
It can be seen that although Xephyr is running, it did not create the socket file X30, nor did it create the abstract unix domain.
That is to say, using socat forwarding, Xephyr cannot create the display number X30.
5) Run other graphics programs
linlin@vm1:~$ DISPLAY=:20 xlogo
This graphics program runs normally on display number X20.
X20 is actually the host X1, although the graphics program in the container can run normally on [Xephyr :1], But my purpose is to run a complete container desktop environment, to run an X Server in the container first, and the graphics program to run on the container's own X Server
6) Use Xnest instead of Xephyr in the container, and the host still uses Xephyr
root@vm1:/# apt-get install xnest
Specify to create display number 30, and run
linlin@vm1:~$ DISPLAY=:20 Xnest :30 &
[2] 435
linlin@vm1:~$ ls -l /tmp/.X11-unix
srwxr- on [:20] xr-x 1 linlin linlin 0 March 22 03:11 X20
srwxrwxrwx 1 linlin linlin 0 March 22 03:12 X30
linlin@vm1:~$ netstat -lp |grep X
Active UNIX domain sockets (only servers)
unix 2 [ ACC ] STREAM LISTENING 403819 435/Xnest /tmp/.X11-unix/X30
unix 2 [ ACC ] STREAM LISTENING 403818 435/Xnest @/tmp/.X11-unix/X30
unix 2 [ ACC ] STREAM LISTENING 401403 431/socat /tmp/.X11-unix/X20
linlin@vm1:~$
Xnest successfully created the socket file X30, and also created the abstract unix domain
linlin@vm1:~$ DISPLAY=:30 jwm &
Run the graphics program on [ Xnest :30] normally
linlin@vm1:~$ exit
Log out user linlin, Because it is running in the background, Xnest and socat are still running after logging out
7) The login manager is
started by xdm. Xnest
will be changed in the container's /etc/X11/xdm/Xservers
: 0 local /usr/bin/X :0 vt7 -nolisten tcp
line to
: 30 local /usr/bin/Xnest- geometry 800x600+0+0 :30
Where: 30 is the display number created by Xnest, and the screen size is 800x600
root@vm1:~# DISPLAY=:20 xdm -nodaemon &
The xdm dialog box has been successfully started. The display number of the environment variable specified by running xdm is 20, but the display number 20 should be mainly passed to Xnest. Xnest runs on [:20], which is the host forwarded by socat [Xephyr :1]
Refer to the host xdm to start /usr/bin/X, the host xdm dialog box must be above the display number of its /usr/bin/X. The container xdm dialog box should run on the container [Xnest:30], not environment variables [:20]
root@vm1:~# ps -e
进程号
...
117 pts/2 00:00:00 bash
125 pts/4 00:00:00 socat
126 pts/5 00:00:00 xdm
129 ? 00:00:00 Xnest
130 pts/4 00:00:00 socat
133 ? 00:00:00 xdm
291 pts/2 00:00:00 ps
root@vm1:~#
socat two processes, process number 125 and 130, respectively; xdm has two processes, each process ID 126 and 133, No. 126 xdm xdm is a daemon process running pts / No. 5,133
embodies the above process from the command process start sequence number In order, it can be seen that running the xdm(126) command in the terminal starts Xnest, and the xdm(133) that is started after Xnest should also be started by xdm(126),
so xdm(133) should be running in [Xnest:30] Xdm login dialog above
root@vm1:~# netstat -lp |grep X
Active UNIX domain sockets (only servers) 进程号/命令名
unix 2 [ ACC ] STREAM LISTENING 127087 129/Xnest @/tmp/.X11-unix/X30
unix 2 [ ACC ] STREAM LISTENING 127085 125/socat /tmp/.X11-unix/X20
unix 2 [ ACC ] STREAM LISTENING 127088 129/Xnest /tmp/.X11-unix/X30
root@vm1:~# netstat -p |grep X
Active UNIX domain sockets (w/o servers)
unix 3 [ ] STREAM CONNECTED 126180 - /tmp/.X11-unix/X20
unix 3 [ ] STREAM CONNECTED 126183 129/Xnest @/tmp/.X11-unix/X30
unix 3 [ ] STREAM CONNECTED 124810 130/socat /tmp/.X11-unix/X20
unix 3 [ ] STREAM CONNECTED 127090 129/Xnest
unix 3 [ ] STREAM CONNECTED 124817 129/Xnest @/tmp/.X11-unix/X30
root@vm1:~#
Install lsof, view and open the file
root@vm1:~# apt-get install lsof
root@vm1:~# lsof -U |grep xdm
进程号 描述符
xdm 133 root 4u unix 0x0000000050f42d76 0t0 124814 type=STREAM
xdm 133 root 5u unix 0x000000005a6b92b7 0t0 126189 type=STREAM
root@vm1:~#
It is seen that xdm (133, daemon) uses unix domain inter-process communication, and xdm (126, command line) is not found to use unix domain
root@vm1:~# lsof /tmp/.X11-unix/X30
(empty)
root@vm1:~#
Check the socket file X30 open status, the result is empty, don’t understand
Through netstat and lsof, I still can’t tell whether the xdm(133) dialog box is above [:20] or [Xnest:30]. I can’t find any way to check which processes have opened the socket file, so I just Can guess that the xdm(133) dialog is running on [Xnest:30] according to the process startup sequence
root@vm1:~# kill -9 133
kills the xdm(133) process, it can be seen that the xdm dialog box is restarted immediately, the 125 and 126 processes remain intact, and the others are killed and restarted
root@vm1:~# ps -e
PID TTY TIME CMD
...
117 pts/2 00:00:00 bash
125 pts/4 00:00:00 socat
126 pts/5 00:00:00 xdm
以下新的进程
331 ? 00:00:00 Xnest
332 pts/4 00:00:00 socat
335 ? 00:00:00 xdm
343 pts/2 00:00:00 ps
root@vm1:~#
Every desktop session logout/login is accompanied by the re-creation of a new daemon xdm
5. Summary of
1) read-only mount the container to the host /tmp/.X11-unix/ /tmp/.X11-unix-host/
2) a container /tmp/.X11-unix/ intact writable
3) containers socat Forward X from /tmp/.X11-unix-host/ to /tmp/.X11-unix/4
) The container uses Xnest instead of Xephyr
(Attached: LXC container graphic front end fglxc-ver0.2.1.zip source code download address http://u.163.com/m8BXHXFWv extraction code: i1bG8PwH)