Menu

#610 LXDM / LXDE Logout doesn't kill all session

closed
dgod.osa
lxdm (80)
5
2014-09-08
2013-09-26
Sonicle Srl
No

Hi, I recently built and packaged lxde 0.4.1 for our upcoming XStreamOS Desktop, based on illumos kernel.
While it works ok under startx (running compmgr+cairo-dock+startlxde), and it correctly kills back to text console on logout,
I cannot manage to logout correctly via lxdm.
If I start lxdm as root, then login via the graphical ui, my lxde desktop starts (as with startx), and I can see all the processes of this user.
Once I try to logout, the lxsession-logout screen appears, then once I click Logout, it returns back to the desktop, not completely sane:
- lxsession has been killed
- cairo-dock shows wrong icons here and there
- I can still see the processes of the user, no more children of lxsession, but of process 1, lxsession is dead.

Because lxdm.conf and Xsession in /etc/lxdm works running ck-launch-session, I checked with ck-list-sessions while inside the desktop through lxdm,
and I find one session with ACTIVE=FALSE, and no session id.
The same, anyway, happens if I just startx.

What should I investigate?
Thanx
Gabriele.

Discussion

1 2 > >> (Page 1 of 2)
  • Sonicle Srl

    Sonicle Srl - 2013-09-26

    Forgot to add that I already applied the patch to lxconn.c about "kill user processes" when in xcb mode.

    Also I forgot to add that once I kill everything with ctrl+alt+backspace and then kill lxdm from shell, I find a residual process of gnome-keyring-daemon

     
  • dgod.osa

    dgod.osa - 2013-09-27

    lxdm.conf try to set
    [server]
    reset=1

    really there are no good way to killall session process in traditional linux,
    Only systemd can do it well.

     
  • Sonicle Srl

    Sonicle Srl - 2013-09-30

    I already tried the reset flag, nothing changes.
    What actually happen is that, once logged in and with the desktop running, using ptree I can see the process tree of lxsession, parent of openbox and lxpanel.
    Once I try to logout, the process tree changes: lxsession is <defunct>, while openbox
    and lxpanel are moved under the pid 1 parent.
    This lxsession defunct pid cannot be killed, and appears child of lxdm-binary.
    Any idea why lxsession doesn't actually die, and doesn't automatically kills its children?

     
  • dgod.osa

    dgod.osa - 2013-09-30

    from what you said, lxdm in a bad state, where lxdm can't manage its child sessions.

    but I don't have this problem. You should try the latest git version.

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-01

    Ok, I did some debugging.

    First of all, I found some bad code in lxcom.c, even in git repo.
    Look at the lxcom_send function, you open two sockets on the same variable "s".
    Then use s to connect and later read data, and (if res is not null, which is the case when lxdm looks for the user list) reuse s (which is not the one intended) to bind to a pid socket: this one fails (at least on illumos).
    I had to change the source code to manage two different variables, sr and sw, being careful to close them both when needed.
    Once I did this, I could see my added g_message showing lxdm trying to load the user list on startup.

    But this is not solving my problem.
    I added a lot of g_message here and there, here is what I get once I login, and try to logout:

    ==DURING LOGIN==
    ** Message: user sonicle auth ok
    ** Message: login user sonicle session /usr/bin/startlxde lang (null)
    ** Message: Have libck-connector
    ** Message: Have libpam, setting up /usr/bin/startlxde
    ** Message: Setting up ck-connector
    ** Message: Set up XDG_SESSIONCOOKIE=d73cf90a63461c9d8adad94000000030-1380630919.684408-1287727181
    ** Message: Adding child watch on pid 2339
    ** Message: lxcom_func: arg 0 = SIGNAL
    ** Message: lxcom_func: pid = 0
    ** Message: lxcom_func: arg 0 = SIGNAL
    ** Message: lxcom_func: pid = 0

    ==DURING LOGOUT==
    ** Message: lxcom_func: arg 0 = SIGNAL
    ** Message: lxcom_func: pid = 0

    The problem seems that the child pid is not sent, so the code cannot detect
    that the session has died.
    I'm not completely aware of how the code is handling this callback, I mean how
    this callback is registered to be called upon lxsession child death.
    Maybe this may be different on Solaris brands (illumos)?

    Also, I found this on lxdm standard error:

    Oct 1 13:18:35 xstreamos console-kit-daemon[538]: [ID 702911 daemon.crit] CRITICAL: polkit_authority_check_authorization: assertion `POLKIT_IS_AUTHORITY (authority)' failed

    and also during system startup of consolekit service:

    Oct 1 10:45:24 xstreamos console-kit-daemon[538]: [ID 702911 daemon.warning] WARNING: polkit_authority_get: Error getting authority: Error initializing authority: Exhausted all available authentication mechanisms (tried: EXTERNAL, DBUS_COOKIE_SHA1, ANONYMOUS) (available: EXTERNAL, DBUS_COOKIE_SHA1, ANONYMOUS)

    I don't know if these last consolekit/polkit errors may cause my logout problem,
    but I don't think so.

    Any other clue??
    Thanks a lot!
    Gabriele.

     
  • dgod.osa

    dgod.osa - 2013-10-01

    I don't think there are any problem in lxcom_send, everyone use an socket to send and recv data. I alyways success here, userlist is always ok.

     
  • dgod.osa

    dgod.osa - 2013-10-01

    you should check /var/run/lxdm directory is exist or not.
    in lxdm.c there is mkdir, it should always success
    if(0!=mkdir("/var/run/lxdm",0755))

    as you say, you call user list fail, in that case, what does it print out, there is an perror("bind");

    do you run lxdm as root? It's necceary.

    One problem maybe my unix socket code is not compatible with Illumos kernel. You should check it.

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-02

    about lxcom_send, if you look at the code, you have two subsequent equal sections creating the socket, as if you wanted to create two socket, but obviously second one overwrite first one. This triggered me the idea you wanted two different ones.
    What happens is that after doing the connect, illumos complains about binding on it, with a "bind: invalid argument", going through in perror("bind"). Dividing the two sockets it works.

    Then, yes /var/run/lxdm is fine, and it contains the socket files when lxdm is up.
    And yes, lxdm runs as root, it would obviously exit with the error message.

    At the moment, looks like the socket code works, but the process signaling is not.
    I believe that the lxdm code is expecting to receive a signal of SIGCHLD with the pid that has gone, but instead it receives pid=0.

    How is exactly lxdm registering to receive child messages? It's hard to get it from the code.

     
  • dgod.osa

    dgod.osa - 2013-10-02

    There is only one socket() call, so I don't want to call create two socket, And recv and send data on one socket is normal usage, as datagram socket, connect and bind in one socket is normal. If Illumos can't recv and send data on same socket, I think it's bug of it.

    In lxcom_init(), there is a sigaction call to register SIGCHLD, the handler is sig_handler, it send the signal to the main socket by lxcom_raise_signal, which call lxcom_write. In lxcom_dispatch, recv the data, dispatch to the signal handler.

    One bug maybe recvmsg in lxcom_dispatch, there some code check the cred data.

    I have write code for xstream code in git, which implements ucred support in lxcom_dispatc, bug I can't debug it, I install xstreamos on vbox, and meet l l lot of problems, automake, gettext version match, link socket. Finally, I compile the code, but can't start Xorg with "no screens found", likely no video driver.

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-03

    about the double socket, look here, you have two identical socket calls:

    ........
    gboolean lxcom_send(const char *sock,const char *buf,char **res)
    {
    int s;
    int ret;
    struct sockaddr_un su;
    int count=strlen(buf)+1;
    char *addr=NULL;

    memset(&su,0,sizeof(su));
    su.sun_family=AF_UNIX;
    s=socket(AF_UNIX,SOCK_DGRAM,0);
    assert(s!=-1);
    fcntl(s,F_SETFL,O_NONBLOCK|fcntl(self_server_fd,F_GETFL));
    s=socket(AF_UNIX,SOCK_DGRAM,0);
    assert(s!=-1);
    fcntl(s,F_SETFL,O_NONBLOCK|fcntl(self_client_fd,F_GETFL));
    .....

    taken here: http://lxde.git.sourceforge.net/git/gitweb.cgi?p=lxde/lxdm;a=blob_plain;f=src/lxcom.c;hb=HEAD

    Nice that you tried XStreamOS yourself :)
    But that is the text only version.
    You would need my dev version, with hundreds more packages for Desktop :)
    Just give me the code you added, and tell me where should I place it ;)
    I'll try it.

    Thanx so much!

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-03

    Great, I'm merging your changes in my patch (the one I had to do for the bind problem).
    At the moment, compile time, I just had to comment out this:

    #define _XPG4_2

    it would issue a redefine warning on illumos base.

    I'm almost done, I'll tell you what happens ;)

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-03

    Ok, something happened!
    Logging out of LXDE takes me immediately to the Logout choices.

    But I'm not sure if it's your change or something I corrected today on consolekit...

    Anyway, it still doesn't logout :(
    I have to go now, tomorrow I'll enable my own g_messages again to debug what's happening during logout, signals etc.

    Thanx so much again ;)
    Gabriele.

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-04

    Something must be wrong in lxcom_dispatch, now.
    Before applying your changes, the callback was called (even though pid was always 0). Now, the callback is never called: the g_message debugs in lxcom_func never appear. Here is the dispatch function, as it is now:

    static gboolean lxcom_dispatch (GSource *source,GSourceFunc callback,gpointer user_data)
    {
    char buf[4096];
    char ctrl[/*CMSG_SPACE(sizeof(LXDM_CRED))*/1024];
    struct sockaddr_un peer;
    struct iovec v={buf,sizeof(buf)};
    struct msghdr h={&peer,sizeof(peer),&v,1,ctrl,sizeof(ctrl),0};
    struct cmsghdr *cmptr;
    int ret;

    while(1)
    {
    peer.sun_family=0;
    ret=recvmsg(self_server_fd,&h,0);

    if(ret<0) break;
    if(ret>4000) continue;
    buf[ret]=0;
    for(cmptr = CMSG_FIRSTHDR(&h);cmptr!=NULL;cmptr=CMSG_NXTHDR(&h,cmptr))
    {
    LXDM_CRED *c;
    int size;
    int argc;
    char **argv;
    GString *res;

    #if defined(__sun)
    size = ucred_size();
    #elif defined(__NetBSD__)
    if (cmptr->cmsg_len < SOCKCREDSIZE(0)) break;
    size = SOCKCREDSIZE(((cred *)CMSG_DATA(cmptr))->sc_ngroups);
    #else
    size = sizeof(LXDM_CRED);
    #endif

    if (cmptr->cmsg_len != CMSG_LEN(size)) break;
    if (cmptr->cmsg_level != SOL_SOCKET) break;
    if (cmptr->cmsg_type != SCM_CREDS) break;
    c=(LXDM_CRED*)CMSG_DATA(cmptr);
    if(g_shell_parse_argv(buf,&argc,&argv,NULL))
    {
    res=((LXComFunc)callback)(user_data,ucred_geteuid(c),ucred_getpid(c),argc,argv);
    g_strfreev(argv);
    if(res)
    {
    do{
    ret=sendto(self_server_fd,res->str,res->len,0,(struct sockaddr*)&peer,sizeof(peer));
    }while(ret==-1 && errno==EINTR);
    g_string_free(res,TRUE);
    if(ret==-1) perror("sendto");
    }
    }
    break;
    }
    }

    return TRUE;
    }

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-04

    Ok, I had to change lxcom_write like this, and I got lxcom_func messages appearing again, still with pid=0 though :(

    static ssize_t lxcom_write(int s,const void *buf,size_t count)
    {
    struct iovec iov[1] ={{(void*)buf,count,}};
    struct msghdr msg = { 0, 0, iov, 1, 0, 0, 0 };
    /* PROBABLY THIS CODE IS NEEDED on __sun #if !defined(linux) && !defined(__NetBSD__) && !defined(__sun) */
    #if !defined(linux) && !defined(__NetBSD__)

    #if defined(__sun)
    int size = ucred_size();
    #else
    int size = sizeof(LXDM_CRED);
    #endif

    char ctrl[CMSG_SPACE(size)];
    struct cmsghdr *cmptr;
    char *p;
    int i;

    msg.msg_control = ctrl;
    msg.msg_controllen = sizeof(ctrl);

    cmptr = CMSG_FIRSTHDR(&msg);
    cmptr->cmsg_len = CMSG_LEN(size);
    cmptr->cmsg_level = SOL_SOCKET;
    cmptr->cmsg_type = SCM_CREDS;
    p=(char*)CMSG_DATA(cmptr);
    for(i=0;i<ucred_size();i++)
    p[i]=0;
    #endif
    return sendmsg(s,&msg,0);
    }

     
  • dgod.osa

    dgod.osa - 2013-10-04

    maybe ucred_getpid() really do nothing.
    in lxcom_func(), change
    if((pid==-1 && uid==0) || pid==getpid())
    to
    if(uid==0 || pid==getpid())

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-04

    Tried your change, but here is debug messages in lxcom_func:

    ** Message: lxcom_func: arg 0 = SIGNAL

    ** Message: lxcom_func: arg 1 = 18

    ** Message: lxcom_func: pid = 0, uid=-1, getpid()=971

    and before:

    ** Message: Adding child watch on pid 1024

    :(

     
  • dgod.osa

    dgod.osa - 2013-10-04

    18 is the SIGCHLD, so everything is ok, it should waitpid now, and call on_session_stop() later.

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-04

    yes, signal is ok, but getpid (me, not child) is 971, passed pid=0, watched pid is 1024.
    I believe there is something not correct in the cred data manipulation before calling callback, that actually get pid=0 instead of child pid....

     
  • dgod.osa

    dgod.osa - 2013-10-04

    getpid() return pid of lxdm, watched pid is pid of session, so they always not same.
    cred data may not correct, but it not important if not concern security. you should make it work first, in current status, it's possible.

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-04

    It works! :)

    I had to change the pid check and let it go through even in case is pid=0 :)

    if(uid==0 || pid==getpid() || pid==0)

    maybe this check may be completely omitted?
    Thanks! I have lxdm running fine! :)
    I'll let you know as soon as I have something for you to download and install as test :)

    Great to have Lxde for XStreamOS Desktop, it will be the default.

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-04

    Just a couple of questions to fine tune the installation:

    - on lxdm login screen, if I use the Quit/Shutdown button, it just exits to the shell (I ran lxdm as root manually). What should I do to let it actually do an "init 5"?

    - once logged in, I can shutdown the machine via Logout/Shutdown (it works from here). What happens is that during shutdown it returns to the desktop view, while I would like to show some image showing "shutting down", maybe animated. Possible?

     
  • dgod.osa

    dgod.osa - 2013-10-04

    reboot or shutdown is in lxdm.c, lxdm_do_reboot() lxdm_do_shutdown(), just call system command who can do it.
    lxsession's quit is to call upower on linux, not use the system command. xtreamos has reboot and shutdown command, you should make them really can work.

    animation really is not related to lxdm. On fedora, systemd do the job, when display-manager quit, launch an service to display the animation, but not smooth, as fedora is shutdown very fast, it's useless.

    One thing you should concern is security, now, the ucred likely not work correctly, so everyone can send data to lxdm by unix socket. But if just the desktop usage, may not very big problem.

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-07

    Yes, I think it's not a very big security problem, at the moment.

    Anyway I found that lxdm was 99% cpu once logged in.
    Doing a "truss" of the process, showed it was continuosly calling recvmsg.
    That function is called only once inside lxcom.c:

    ret=recvmsg(self_server_fd,&h,0);

    do you have any clue for this?? :)

     
  • Sonicle Srl

    Sonicle Srl - 2013-10-07

    Correction: lxdm goes 99% cpu since it starts, not only when logged in.
    Looks like the lxcom_dispatch loop is never sleeping...

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.

MongoDB Logo MongoDB
Gen AI apps are built with MongoDB Atlas
Atlas offers built-in vector search and global availability across 125+ regions. Start building AI apps faster, all in one place.