Search code examples
vnckvmxen

do xen support multiple vnc client connecting?


I open one vnc viewer to connect the xen virtual machines,that works right. At the same time, I open another vnc viewer to connect the same virtual machines, the vnc viewer cann't connect. The status is always be " Connecting....". As far as I know, the reason for that is Xen can not support multiple vnc client connect the same virtual machine at the same time. If anyone has the same problem? How to fix this? Expecting your answer.


Solution

  • The vncserver has options to allow different kinds of sharing, notably:

       -nevershared
              Never allow shared desktops.
    
       -alwaysshared
              Always allow shared desktops.
    

    Normally I'd say to hunt down the vncserver command being used and modify it, but Xen appears to work differently, only exposing some options through flags to set. With Xen, I think multiple VNC connections was added to vanilla QEMU in 2010 or so, and being considered for addition to Xen around the same time, but I'm not seeing the expected benefit of that in the Xen docs I'm finding on the 'net, so maybe it didn't happen.

    If Xen still doesn't support it directly, and you're only trying to make additional connections to an existing X server, you could probably run x11vnc within your first session to add support for extra connections (look for the -shared and probably -forever options). Note that your x11vnc should only allow connections from localhost, and then additional connections can be added by using SSH to make a tunnel to the VM using the following commands:

    On the VM:

    # :0 -> port 5900, increase if needed.  If vncserver's already there, definitely do.
    # x11vnc require root access to reach a Ubuntu login screen, or matching user access
    #   if a user is already logged in.
    # An -auth option is usually needed - this one is for lighdm, but can vary wildly,
    #   the output of x11vnc has a lot info on this.  The running X server will often
    #   have the exact thing you need in its own command line.
    #
    x11vnc -shared -forever -auth /var/run/lightdm/root/:0 -display :0 -rfbwait 600
    

    On your local computer:

    # adjust the 5900 to be the sum of 5900 plus the number after the ":" in x11vnc:
    # the 5901 tells which :(something) to use with vncviewer, just subtract 5900.
    #
    ssh -XC -L5901:localhost:5900 yourvmhostname
    #          |               |
    #  local port for :1       target port on VM for :0
    

    Then locally run (here the :1 is why we have 5901 above, adjust to taste):

    vncviewer :1    # connects to the 5901 part on your *own* host, provided by the ssh.
    

    One quirk: these commands rely on the .Xauthority file having magic cookies for the :(n) display you want to use. Note that the vncserver script normally makes these for you, and once they exist, you don't need to recreate them. If you're not using vncserver itself, you might need to make them yourself with:

    remdpy=7     # assuming you need cookies for display :7 for some reason.
    host=$(uname -n)
    cookie=1fedaff375011821b5e0b4cf514d574a  # or something, see vncserver's example
    for key in $host:$remdpy $host/unix:$remdpy ; do
      if xauth list $key | grep -sq . ; then
        echo $key already present
      else
        xauth -f ~/.Xauthority add $key . $cookie
      fi
    done
    

    Don't use the same cookie this shows.

    Note that to punch through a gateway host that hides some internal subnet of VMs (or real hosts), the first step is to set up a tunnel through it. Something like this (root is just an assumption, use lesser IDs if you can):

    gateway=192.168.0.1
    hidehost=172.16.0.1
    # make a tunnel from localhost:2222 to $hidehost:22
    ssh -CNn -L2222:$hidehost:22 root@$gateway &
    # connect through it to $hidehost and run x11vnc there
    ssh -C -p 2222 -L5901:127.0.0.1:5900 root@127.0.0.1 \
       'x11vnc -shared -forever -auth /var/run/lightdm/root/:0 -display :0 -rfbwait 600'
    # connect to VNC on localhost:5901 - which uses the 2nd tunnel we just made
    vncviewer :1  # run in a different window.
    

    This worked in my test. The two SSHes can be combined using -OProxyCommand (so that one doesn't have to clean up the backgrounded SSH job) but that's more involved. Example:

    gateway=192.168.0.1
    hidehost=172.16.0.1
    ssh -C -oProxyCommand="ssh root@$gateway -n -W $hidehost:22" \
      -L5901:127.0.1:5900 root@127.0.0.1 \
      'x11vnc -shared -forever -auth /var/run/lightdm/root/:0 -display :0 -rfbwait 600'
    vncviewer :1   # run in a different window.