Menu

#54 xrdp-sesman defunct sessions lock out users

v1.0 (example)
open
nobody
None
5
2021-10-17
2014-11-12
Bryon Gill
No

We have been using xrdp-0.5 on CentOS6.5 with multiple concurrent users and when we allow a session to persist for some number of hours after they have disconnected, some of those sessions become unavailable but sesman tries (and fails) to connect the user back up to them. The processes for these sessions show as <defunct> in ps output. There doesn't seem to be any way to force a new session for these users (we tried allowing them to set the port in remote desktop login but sesman ignored this and tried to connect to the old session). The only way to get rid of them is to kill the parent process, i.e., reset the xrdp service and lose all other user sessions.

When the user tries to log in they see a message like this:

Sending login info to session manager, please wait...
Xrdp_mm_process_login_response: login successful for display
Started connecting
Connecting 127.0.0.1.5917
Error - problem connecting

We are able to minimize the impact of this by killing inactive Xvnc processes periodically (http://pastebin.com/xxrg9CVS), but our users would like their desktop sessions to persist. If there is a workaround that could somehow clean up a user's defunct session without restarting the whole server that would be very helpful. Happy to document this further as needed.

Discussion

  • Bryon Gill

    Bryon Gill - 2014-11-19

    A quick update; we've discovered that we can work around the lockouts by having the users reconnect with a different screen resolution which creates a new session rather than trying to reuse the old one. The user is stil locked out of their previous session though obviously.

     
  • Steven

    Steven - 2014-12-10

    Hi Bryon,

    i encountered similar problems in our setup. Maybe your problem is related?

    Our process tree looks like this with more xrdp-sessvc processes following.

    9945 ?        S      0:00 /usr/sbin/xrdp-sesman
    9393 ?        S      0:00  \_ //usr/sbin/xrdp-sessvc 9395 9394
    9394 ?        S      0:00  |   \_ MyProgram
    9395 ?        S      0:00  |   \_ Xvnc :22 -geometry 1904x1121 -depth 16 ...
    9397 ?        Sl     0:00  |   \_ xrdp-chansrv
    

    So, if MyProgram (which also started the window manager) closes, xrdp-sessvc tries to stop XVnc and xrdp-chansrv as well by sending them the SIGTERM signal. But if either of those processes does not react to the signal and does therefore not exit, xrdp-sessvc will hang forever. xrdp-sesman therefore sees this still as active and will forward an incoming request which matches (same resolution, type, bpp, source ip and think) to this session.

    Do you have by chance a ps output, where i can see, which process is defunct and how the process tree looks?

    Steven

     
  • Bryon Gill

    Bryon Gill - 2015-02-13

    Here's the first few relevant lines of a typical process tree when this happens:

    10399 pts/0    S      0:06 /usr/sbin/xrdp-sesman TERM=xterm PATH=/sbin:    /usr/sbin:/bin:/usr/bin PWD=/ LANG=en_US.UTF-8 SHLVL=2 _=/usr/sbin/xrdp-sesman
    12096 pts/0    S      0:00  \_ /usr/sbin/xrdp-sessvc 12098 12097 TERM=xterm PATH=/sbin:/usr/sbin:/bin:/usr/bin PWD=/ LANG=en_US.UTF-8 SHLVL=2 _=/usr        /sbin/xrdp-sesman XRDP_SESSVC_DISPLAY=16 DISPLAY=:16.0
    12097 pts/0    S      0:00  |   \_ /usr/sbin/xrdp-sesman TERM=xterm PATH=/sbin:/usr/sbin:/bin:/usr/bin PWD=/ LANG=en_US.UTF-8 SHLVL=2 _=/usr/sbin/xrdp-sesman
    12100 pts/0    Sl     0:00  |   \_ xrdp-chansrv TERM=xterm PATH=/sbin:/usr/sbin:/bin:/usr/bin PWD=/ LANG=en_US.UTF-8 SHLVL=2 _=/usr/sbin/xrdp-sesman XRDP_SESSVC_DISPLAY=16 DISPLAY=:16.0
     5411 pts/0    Z      0:00  \_ [xrdp-sessvc] <defunct>
    30359 pts/0    Z      0:00  \_ [xrdp-sessvc] <defunct>
    23708 pts/0    Z      0:00  \_ [xrdp-sessvc] <defunct>
    
     
  • Paul van Tilburg

    Yes, I have been debugging this all morning and it seems that SIGCHLD is blocked somewhere.

    If I apply this patch (to 0.6.1):

    --- a/sesman/sesman.c
    +++ b/sesman/sesman.c
    @@ -306,6 +308,7 @@
       g_signal_user_interrupt(sig_sesman_shutdown); /* SIGINT  */
       g_signal_kill(sig_sesman_shutdown); /* SIGKILL */
       g_signal_terminate(sig_sesman_shutdown); /* SIGTERM */
    +  g_signal_usr1(sig_sesman_session_end); /* SIGUSR1 */
       g_signal_child_stop(sig_sesman_session_end); /* SIGCHLD */
     #endif
     #if 0
    

    and I send a USR1 to sesman after a user has terminated his/her session, the xrdp-sessvc zombie process is properly reaped and marked as terminated after which the user can login again. I have still been unable to find out why the signal handler is not fired for SIGCHLD.

     

    Last edit: Paul van Tilburg 2015-09-22
  • Paul van Tilburg

    This dirty hack has fixed the problem for me. For some reason, after forking xrdp-sessvc and the entire session, the signal handler for SIGCHLD is lost. The extra call in this patch reconnects it after the fork but... this should be necessary.

    --- a/sesman/session.c
    +++ b/sesman/session.c
    @@ -563,6 +563,7 @@
       }
       else /* parent sesman process */
       {
    +    g_signal_child_stop(sig_sesman_session_end); /* SIGCHLD */
         temp->item->pid = pid;
         temp->item->display = display;
         temp->item->width = width;
    

    I still wonder why the more modern sig handler thread is disabled?

     
  • Nathan Revo

    Nathan Revo - 2015-10-09

    Thank you for posting this. We are using the xorg driver, but experiencing a similar issue.

     
  • Paul Vixie

    Paul Vixie - 2021-10-17

    thank you for posting this. the bug still exists in 2021, and your patch still fixes it, though with different line numbering and context since the surrounding source code has been reorganized.

    --- xrdp-0.9.13.1/sesman/session.c.orig 2021-10-17 21:26:45.386189301 +0000
    +++ xrdp-0.9.13.1/sesman/session.c 2021-10-17 21:26:26.638741197 +0000
    @@ -833,6 +833,7 @@
    }
    else
    {
    + g_signal_child_stop(sig_sesman_session_end); / SIGCHLD /
    temp->item->pid = pid;
    temp->item->display = display;
    temp->item->width = s->width;

     

    Last edit: Paul Vixie 2021-10-17

Log in to post a comment.