XDG_RUNTIME_DIR on a system with no "logins"

Simon McVittie smcv at collabora.com
Wed Dec 18 16:20:23 UTC 2019

On Wed, 18 Dec 2019 at 13:10:14 +0100, Guillermo Rodriguez wrote:
> > > >But how is this done for a system where normally no users "log in",
> > > >e.g. a fixed-function embedded system with a graphical user interface?

Decide what "logging in" means for you, and make it work like that.

Imagine for a moment that your fixed-function embedded system was
running an ordinary desktop Linux system. You'd probably configure a
display manager (gdm or equivalent) to auto-log-in without displaying a
prompt or asking for a password, logging in as the user who owns the GUI
processes, to a special desktop session that runs the top-level process
of your embedded GUI (the same way a desktop session would run the
top-level process of a desktop environment, like gnome-session).

One, relatively heavy-weight, option is that you could literally do that.
For example, that's what SteamOS does for its games-console-style UI.
The advantage of that approach is that swapping from your embedded UI
to an ordinary interactive UI is just a matter of reconfiguring the
display manager.

The option you'll probably prefer is to aim to get the same practical
result, but in a simpler and more-hard-coded way: declare "launched
the GUI" to be the closest thing you have to "logging in", create an
XDG_RUNTIME_DIR that reflects that just before the first GUI process
starts, and clean it up after the last GUI process exits.  On an embedded
system, "after the last GUI process exits" is probably a power-off or
reboot anyway, so if you put the XDG_RUNTIME_DIR on a tmpfs it will get
cleaned up without you needing to do anything special.

If you're using systemd-logind, you can register a login session by
arranging for the pam_systemd PAM module to be entered (interactively or
otherwise), for example with PAMName in a system service unit; if you do,
systemd-logind will automatically allocate an XDG_RUNTIME_DIR for you,
for the duration of that service's lifetime. However, you mentioned SysV
init scripts, which suggests that you are probably not using systemd.

> OK so I can just "make up" a xdg dir which is not bound to any specific
> user. Although this obviously wouldn't meet the specs quoted above
> ("The lifetime of the directory MUST be bound to the user being logged
> in" ...)

You're the system integrator, so you get to choose precisely what "being
logged in" means.

> > If you invent XDG_RUNTIME_DIR like this, please also make sure to
> > adhere to the XDG specification requirements. Specifically, it is a
> > good idea to use a tmpfs for this. If it is backed by an actual
> > disk, it may incur unnecessary disk I/O, which in embedded systems
> > might be really bad.

To make it as easy as possible to adhere to the spec requirements and as
likely as possible that everything will work, I'd recommend mounting a
tmpfs on /run (which you are hopefully doing already), and then using
the same path for XDG_RUNTIME_DIR that systemd-logind uses, which is
"/run/user/$(id -u)" - that way, anything that incorrectly hard-codes
that path will still work. It's a bug to hard-code it, but there's no
particularly good reason to choose any other path either, so you might
as well make the same choice that systemd-logind did.

systemd mounts a separate tmpfs per user, but if your system doesn't
have any untrusted users or any need to prevent denial of service by
its users, then you can probably just use /run for everything.


More information about the wayland-devel mailing list