LXC container runs X Server (continued 2-port forwarding)

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 host
lxc.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 1
linlin@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)

Guess you like

Origin blog.51cto.com/13752418/2603398