Hello,

I've already explained the way you start a logind session: by just running
a PAM stack. I've also explained all that
the DM is supposed to do to integrated with logind multiseat: watch logind
for seats appearing/disappearing, and start
greeter sessions on those seats.

GDM calls methods like sd_pid_get_sesssion because it is a complicated
display manager with advanced features, like
reauthentication channels for the GNOME lock screen. It needs to be able to
receive a D-Bus method call, look up who
made the call, and try to associate the caller to a running session. These
are the manager bits you've linked to. GDM
also has a client library used by the greeter frontend (which is actually
just gnome-shell), and that is your second set
of links. The greeter uses libgdm to figure out what .desktop files it
should offer to the user, and libgdm uses
sd_pid_get_session on its own PID to find out what session and thus seat
the calling process (i.e. the greeter) belongs to.
The libgdm functions are not called by the display manager (the privileged
system daemon that runs at boot), but by the
greeter (an unprivileged program that runs as part of the session the
display manager starts for each seat). So yes: GDM has
calls to sd_pid_get_session, but not in its implementation of multiseat and
not as part of its basic integration with logind.
These are auxiliary features that your display manager is unlikely to have.

I'll try to summarize, again, what a display manager needs to do for
multi-seat to work. This time I'll just refer to the
functions you need to call. I hope that will help answer your questions,
because if not them I am sorry but I am out
of ideas for how else to explain this, and at that point all I can do is
wish you luck. At the very least, what I write
here might be useful documentation in the future for someone wishing to
experiment with writing a display manager.

1) Call sd_login_monitor_new to create a login monitor. This is how you
will listen to events from logind. You can listen
   specifically for seat changes by passing "seat" to that function
2) Hook the sd_login_monitor object the previous call created into your
event loop. I can't tell you in detail how to do
   that because I do not know how the EFL event loop works. However, it
shouldn't be too hard. Ultimately it's a file
   descriptor that you call poll() on.
3) You should now be able to tell whenever a seat has appeared,
disappeared, or changed. You can call some callback
   in response to this, which will do the following steps to look up
information about seats. You should also do the following
   steps once on startup, to process the events that have happened before
your display manager started (i.e. seat0 being
   created very early during boot)
4) Call sd_get_seats to get a list of seats that currently exist. For each
seat, do the following steps
5) Check if you have a session running on that seat. In other words, loop
over your data structure of running sessions and
   find the one you've associated with the seat
6) Call sd_seat_can_graphical to see if the seat is capable of graphics
7) If sd_seat_can_graphical returned false, but you found a running
session, you need to stop the session (i.e. send SIGTERM to
   the session leader process, the one where you did the PAM conversation
to start the session). Then move on to the next seat.
8) If sd_seat_can_graphical returned true, but you found a running session,
all is good. Move on to the next seat.
9) The only remaining case is that sd_seat_can_graphical returned true, but
you found no running session. You need to start a
   greeter session on the seat.
8) Fork off your PAM worker process, and set up PAM to use a service that
trivially passes authentication. GDM uses "gdm-launch-environment"
   for this purpose. In the worker process, use PAM to set XDG_SEAT= to the
ID of the seat you want to start the session for. Also set
   XDG_SESSION_CLASS=greeter. Then do the whole PAM song and dance to
authenticate and start a session. Finally, run your greeter from
   within this new session you've created.
9) Meanwhile, in the display manager, you'll keep track of this PAM worker
process and the seat you used to start it. This is how you'll
   look for running sessions later, when the sd_login_monitor tells you
that something changed and you find yourself back at step 5.
10) You're done handling this seat. Move on to the next seat returned by
sd_get_seats.
11) When you're done looping over all the seats, loop through all your
running sessions and make sure that you don't have any greeter sessions
    that belong to a seat that has disappeared. If you find a session that
belongs to a seat that wasn't returned by sd_get_seats, then end
    that session (again, SIGTERM to the session leader)
12) Each running greeter will eventually start a PAM conversation to handle
the password textbox. Presumably, the greeter is using IPC to communicate
    back to the display manager, and the display manager is forking off
another PAM worker process to handle the conversation. This PAM worker
    will eventually become the final user session. Since you know the
greeter that started the PAM conversation, and the seat that this greeter
    belongs to (you stored it in step 9!), you can set XDG_SEAT= on this
new PAM worker process
13) Since the password box PAM worker will eventually become the final user
session, the final user session will start on the right seat!

And that's it! This is the same approach to multiseat as used by GDM, only
translated into the logind C API. Note how there's no need to
look up anything by PID before a session exists. You can, of course, look
up sessions by PID after you've started those sessions.

Hope that helps, and best of luck.
Adrian

On Mon, Mar 2, 2026 at 10:08 PM William L. Thomson Jr <[email protected]> wrote:

> Adrian,
>
> On Mon, 2026-03-02 at 19:09 -0500, Adrian Vovk wrote:
> >
> >
> > It does not. This is the root of the misconception.
>
> GDM has a lot of the same code.
>
> >
> > Processes can exist inside of a logind session. Namely, the
> > aforementioned "session leader" and its entire tree of descendents.
> > The `sd_pid_get_session` function lets you look up the logind session
> > that the specified process is a part of. This does not mean
> > that that PID has anything to do with the existence of the logind
> > session, or that the PID is somehow being used to communicate
> > with logind. No. You're just looking up the session ID of the session
> > that contains the process you're querying.
>
> The PID is bound to the existence of active logind session, otherwise,
> that function will return an error.
>
> My issue is the PID being known before the logind session exists. The
> PID belongs to the shell that logind session exists in and the desktop
> is running in; all under samd PID. The PID is associated to a logind
> session once the shell session is active.
>
> I just need another process or thread to use that PID to obtain the
> session, as my primary process is waiting for that PID to exit. But the
> the desktop is already started.
>
>
> > > GDM is doing this as well, calling
> > >
> > > ret = sd_pid_get_session (pid, &session_id);
> > >
> > > https://github.com/GNOME/gdm/blob/main/libgdm/gdm-sessions.c#L80
> >
> >
> > This is called from _inside_ of the session, not by the display
> > manager.
> > The process linking against libgdm here (namely: gnome-shell)
> > uses these functions to find its own seat.
>
> So this happening inside a session?
>
> /* First try to look up the session using the pid. We need this
>  * at least for the greeter, because it currently runs multiple
>  * sessions under the same user.
>  * See also commit 2b52d8933c8ab38e7ee83318da2363d00d8c5581
>  * which added an explicit dbus-run-session for all but seat0.
>  */
> https://github.com/GNOME/gdm/blob/master/common/gdm-common.c#L823
>
> Pretty sure that is the DM they are talking about, greeter.
>
> Going further, this commit seems to make it clear they are looking up
> the session, which you are saying is happening inside a session?
>
> https://github.com/GNOME/gdm/commit/32646105196ed7a687f3684b69ea544dd01d2ade
>
> Clearly talking about the DM, commit comment prefix "manager:".
>
>
> There are 3 different usages of sd_pid_get_session
>
> https://github.com/search?q=repo%3AGNOME%2Fgdm%20sd_pid_get_session&type=code
>
>
> This further confirms my remarks that multi-seat is more theory than
> reality, this still seems like a WIP...
>
> https://github.com/GNOME/gdm/commit/2b52d8933c8ab38e7ee83318da2363d00d8c5581
>
> Seems to be starting a session there, not calling something from within
> a session.
>
> Cheers!
>
> --
> Sincerely,
> William L. Thomson Jr.
>

Reply via email to