Hello William,

Replies inline

> I would suggest that, overall, it may be very helpful to look at the
> > implementation of an existing display manager for guidance (i.e. GDM,
> > plasmadm, lightdm, etc).
>
> I have been, GDM seems best reference, not exactly clear how others are
> integrating, but its several functions deep wrapped and they are
> launching and doing many things differently in GDM. That is my primary
> reference along with logind code.
>

Yeah, GDM is quite complex, partially because it runs multiple worker
processes at once in an attempt to run the fingerprint sensor and password
entry at the same time.

The new plasmadm is another modern implementation you can look at, and it's
going to be a bit simpler because, as far as I know, they're not doing the
whole "run multiple PAM stacks in tandem" thing that GDM does.

Another was spawny but I am unsure how accurate that implementation was
> as its quite old, and I never used it to confirm it worked, proper
> approach, etc.
> https://github.com/marcelhollerbach/spawny


I do not know the quality of spawny. Never heard of it


> > You don't. logind is started during boot by systemd. A logind session
> > is started by the `pam_systemd.so` PAM module
>
> Yes, but in my case, this happens when the shell session is created and
> desktop is launched, and we cannot connect to logind at that point, and
> maybe it should be D-Bus vs logind via C-API.
>

Sorry, what do you mean by connect? The C API doesn't connect to anything.
It just reads some state files that logind leaves for it in /run


> From what I can tell, either the DM or logind can create the seat.
> Given the code in logind/elogind for seat creation, I am unsure if that
> is something the DM should be doing or not. Why have both the DM and
> logind doing seat management?
>

I don't think the DM has the ability to create a seat. Can you point me at
what you're referring to?

Note that the display manager is free to create a session that's not
associated with a seat. This is done for remote sessions, like for RDP.
But outside of that, logind manages the seats and the display manager just
listens to logind.


> It was hard coded to "seat0" per freedesktop documentation for
> sometime, but recently switched to letting logind do that as part of
> attempted integration, and that seems fine, just no way to detect
> changes or talk to logind.


Talking to logind is only available via D-Bus. Listening for changes, in a
strictly read-only way, is doable via the C API. See below for more detail.


> Setting XDG_SESSION_CLASS to "greeter", we do, not sure the benefit.
>

The benefit is that the session is clearly marked as belonging to a
greeter. The DM can use this to find its own sessions, and in general
it's helpful to identify what sessions belong to where.


> I am unsure if there will ever be > seat0 though, and how that applies
> to say VT or other.
>

Yeah, other seats exist. They get created by logind when a "master-of-seat"
device appears (normally a GPU, but I'm not sure that this
is strictly required...). It takes some manual configuration in udev, but
you can plug in a second GPU, make udev tag it as "master-of-seat",
allocate some hardware to that seat (a second keyboard, second mouse, USB
hub, etc), and it all should work.

seat0 is special in a few ways, though. First: it always exists, even
without a master-of-seat. It starts in text mode, without graphics-capable
hardware driving it, and then its master-of-seat GPU appears and it becomes
a graphical seat. It's also the only seat that has the concept of
a "VT", no other seat does. So, to answer your question about how this
interacts with VTs: except for seat0, it doesn't. VT's don't make sense
for anything other than seat0.


> > - Do the normal PAM authentication and session setup dance
> > - PAM, as part of its session setup, will talk to logind for you!
> > - Now that you're inside of the session, run the session leader (i.e.
> > the
> > command you find in `Exec=` in the chosen
> > /usr/share/{wayland-,x}sessions/*.desktop file)
> >
> > This is, fundamentally, what you'd already be doing to start a
> > session on Linux with PAM. Really all you need to do is remove the
> > consolekit stuff, add the environment variables, and make sure that
> > `pam_systemd` is present in your PAM stack.
>
> Check, logind starts and that session is running, but the DM is not
> connected to that, DM and logind do not communicate. The DM is waiting
> for the PID to exit, but no means to connect to logind (same PID),
> short of forking another process, etc.
>

Sorry, I'm not totally understanding what you mean here. It seems that you
think that logind is running as a child of the display manager
somehow? And that to talk to logind you need to somehow talk to this child
process?

logind runs as a systemd service, child of PID 1. logind isn't started by
the DM, and doesn't run as part of the session. You can basically
think of logind as a daemon that's running off to the side, next to the
display manager, which acts as a database to keep track of running
sessions. When you start a session, you're not starting logind. The
pam_systemd module just makes an IPC call to the already-running
logind daemon, and tells it about the new session.

You can connect to logind by talking to org.freedesktop.login1 via the
d-bus system bus. For read-only tasks, you can also use the C API.


> That is where I am stuck. It seems like the DM needs no logind
> integration at all. Unless logind and the DM are supposed to
> communicate, and what that communication should be, which seems to be
> monitoring seats per below.
>

Indeed. As the documentation points out: porting to logind is mostly about
just deleting your consolekit code. At least for a minimum
viable integration.


> > The other big change that might need to happen, is that you should
> > run your greeter session through PAM also. Maybe you're not doing
> > that, I don't know. You can set up a PAM stack that basically amounts
> > to "allow login without authentication, and run pam_systemd.so".
>
> We are using pam, I was considering making it no longer optional, but
> it BSD can run without pam, whereas pam is standard on most any Linux
> distro. BSD may not have logind/elogind either so that is moot.
>

Just to make the distinction, because it sounds that you're confirming to
me that you run the login session via PAM. That's good, but you
also need to run the login screen itself, as a session, also via PAM.

The greeter must be a fully fledged session, PAM and all, for logind to be
able to manage it or even know about it existing. And that is
required if you want to support multiseat. If you don't start a session,
logind will not be willing to give an unprivileged display server
(like an unprivileged instance of XOrg, or a Wayland compositor) access to
privileged hardware like the GPU, and *especially* input
devices like the keyboard and mouse. This is critical security
infrastructure as well, otherwise any process would be able to keylog
the user's input


> > If you want multi-seat to work, you have to monitor (via DBus) logind
> > for SeatAdded/SeatRemoved events. Whenever a seat appears, check if
> > it's graphical (and note that a seat can become graphical later!),
> > and if it's graphical start a greeter session for it. You can
> > associate the session to the seat via the `XDG_SEAT` environment
> > variable, as mentioned above. If you want to get yourself going
> > without multiseat support, just set `XDG_SEAT` to `seat0`, or
> > don't set it at all. When that greeter tries to start a session, you
> > can query its seat, and set `XDG_SEAT` on that new session
> > accordingly.
>
> Ok, this is along the lines of what I am seeking, so the DM is
> monitoring for seat events, and this is done via D-Bus, though I think
> you can get R/O events from the logind C-API, assuming we can talk to
> PID, but seems more like we need to be integrating against D-Bus.
>

Ah, you are correct that you can get read-only events from the logind C
API. Via sd_login_monitor_new, you can hook up the C API's
event monitoring into your main loop, and then get notified whenever there
are changes. Basically this just sets up an inotify watch on
the directories in /run that logind uses to communicate with the C API.
This way, when the inotify watch fires, the C API tells you that
"something changed", and you can call functions like sd_get_seats to get a
listing of the current seats that exist.

Alternatively, you can talk to logind via D-Bus. It owns the
org.freedesktop.login1 bus name, and that's where you can reach it.

I've already addressed the "talking to the PID" misconception


> I was originally assuming I needed to integrate against D-BUS and not
> logind via the API as another did, I hate to remove all their logind
> integration code. Its seems it works for them, but given issues in CI
> and how it works, I fail to see how. The logind PID is not associated
> until after we launch session and at that point we are waiting for the
> PID to exit, no further communication.
>

Well, if you've got an implementation using the C API then great. That
should work if you don't actually need to tell logind anything,
and it seems that you don't really need to. Basic integration into display
managers was the kind of thing the C API was made for!

Also note that you can mix and match! If you're using the C API for most
things, but need to ask logind to do something, you can
also make a D-Bus call without rewriting everything.

Again, already addressed the "talking to the PID" misconception


> I am curious to learn more about this seat becoming graphical later,
> and how another seat shows up. I am curious all around about seats,
> multi-seat, if a multi-seat system exist, and what that entails.
>

Another seat will appear if a device labeled as "master-of-seat" appears.
Usually (and maybe always? I'm not sure) this is a GPU. With the
C API, you can use sd_login_monitor to listen for changes, and then call
sd_get_seats to list all the seats, and then basically see if any new
values appeared or disappeared since the last time you called that. Via
D-Bus, you need to listen to the SeatAdded / SeatRemoved signals
emitted by logind.

seat0 starts without any support for graphics, but gains graphics support
later, when the kernel finishes probing your GPU. With the C API,
again you can use sd_login_monitor to listen for changes. Then you can call
sd_seat_can_graphical to see if the seat is capable of graphics.
If it is, you should start a greeter session on it. Via D-Bus, the "Seat"
D-Bus objects exposed via logind have a "CanGraphical" D-Bus property
on them. When the seat's ability to run graphics changes, logind emits a
standard D-Bus property changed signal

Seems like mainframe stuff, multiple monitors, keyboards, and mice. I
> have read up on it a lot over the years, some details fail my present
> memory, I know other devices can be part of all that.
>

Yes. Each "seat" is a set of devices (monitor, keyboard, mouse, audio,
other peripherals like USB devices). You can have more than one, and
basically one computer can run multiple sets of monitor/keyboard/mouse, and
thus act like multiple machines.


> Seems also like seat0 uses :0 and also a VT
> ( VT and :0 maybe same thing, not totally clear on that )
>

:0 is just the address of the first X server, via local Unix socket.
Depending on how you implemented your display manager, this will
either be per-user (rootless Xorg) or system-wide (rootful Xorg). The
second X server gets the :1 socket, the third gets :2, etc.

VTs correspond to /dev/tty1, /dev/tty2, up through /dev/ttyN for some N.
These are natively supported by the kernel, and it's what you
switch between when you hit Ctrl+Alt+F1/F2/F3 and so on. (This is a bit of
a simplification, logind is involved here too but in a very subtle
way. Long story short, with logind you can switch between sessions on seats
that don't have VTs, and on modern kernels you can completely
compile out support for VTs and logind will continue to offer session
switching even on seat0 without VTs)


> > The final piece of the puzzle is the display server. When it wants to
> > gain DRM control, or access input devices, or whatnot, it needs to
> > ask logind (again, via D-Bus). Logind will hand over the resources
> > that are appropriate for the seat that the given session belongs to
> > (as determined when the session was created, via the XDG_SEAT
> > environment variable). Note that what the docs say about the `-seat`
> > parameter and `systemd-multi-seat-x` is out-of-date, XOrg natively
> > supports this for you. So do most Wayland
> > compositors
>
> This so far seems fine, recent changes added support for starting
> Wayland sessions, so both X11 and Wayland can be launched. I believe
> the main "need" or "issue" around logind and also from consolekit is
> system actions. If a session is not setup, some desktops won't show
> like restart/reboot/hibernate, etc system actions. All that has been
> long working, via pam -> logind and a hard coded seat0.
>

System actions are, indeed, one of logind's major responsibilities.

But actually, the primary need for logind is the resource delegation. As I
mentioned above: logind is what gives the display server permission to
talk to the GPU, and also the keyboard and mouse. Without logind or
something like it, the display server must run privileged to be able to
access
the raw device nodes in /dev.


> It seems the integration mostly benefits multi-seat and when seats
> appear etc, which I have yet to observe or know how to even replicate
> for testing etc. But it seems like its more D-Bus integration and
> monitoring than logind.
>

If you do D-Bus integration, you'd be talking to logind via D-Bus.

But also, you can keep using the C API


> If we are not getting what we need from D-Bus wrt to logind, then
> logind sessoin may not be running yet, then that is where the "greeter"
> class sessions and others may come in.
>

Generally, to enforce system security, logind will prevent you from doing
certain things unless you're inside of a session. Like, for instance,
grabbing control of the display and input devices. So you're correct, this
is where the "greeter" class sessions come in: you start your greeter
UI as a session, and then logind will grant it access to hardware. If you
don't, it won't, and the session will fail to run unprivileged.

Right now, short of trying to run the DM under Wayland, I see no point
> in having the greeter session have anything to do with logind. Its
> mostly for when the users logs in, and seat aside, making sure system
> actions are available etc. Unless seats can change and DM needs to
> spawn greeters on those.
>

Seats can change, and the DM does need to spawn greeters on those.

But also, again without logind you must run the greeters with enough
privileges to talk to the raw device nodes in /dev. Maybe you're doing
that, with a rootful X server. But running the X server as root has been an
anti-pattern for a long time now. logind allows you to run the X server,
or any other display server, without privileges. Wayland compositors will
often just refuse to run as root nowadays.


> It still seems like this is all a WIP, more theory than application, as
> I would love to see a multi-seat system and how all this is supposed to
> work, which back to the start, GDM seems best reference, and I guess
> the primary roadmap for all this.
>

> Its FOSS, I know juggling, but if there will never be > seat0, seems
> like a hard coded is all one would ever need, KISS!
>

This isn't WIP stuff. It's been used in practice since logind was first
introduced over a decade ago

Hope this helps clarify.

Best,
Adrian

Reply via email to