units: symlink well-known Varlink services into /run/varlink/registry/

So far we didn't provide any concept to enumerate local Varlink
services. Let's change that.

Let's define very light-weight scheme for this: provide a well-known dir
/run/varlink/registry/ where services that implement public interfaces
can link their sockets into. When enumerating services it's thus
sufficient to enumerate inodes in that directory.

The usecase for this is twofold:

1. It's simply very useful to be able to see which public services are
   bound on the local system, for debugging/admin/development purposes.

2. At Amutable we'd like to optionally provide a HTTP-to-Varlink bridge
   on individual nodes, that allows remote peers (after authentication)
   to access local Varlink services. For that it's essential we know the
   list of services and their entrypoints to expose, it would be
   security-wise highly problematic for clients to provide AF_UNIX
   entrypoint paths when connecting. hence: let's instead just have a
   dir with the public stuff, and let's ensure the HTTP-to-Varlink
   bridge simply exposes that stuff, and nothing else.

Non-public interfaces (such as the oomd interfaces between PID 1 and
oomd), and interfaces with multiple implementors (such as the resolved
hook interface, or the metrics collection stuff) should not be linked
in.

This is inspired by the Varlink.org "registry" concept, briefly
explained here:

https://varlink.org/FAQ#how-do-i-find-the-service-which-implements-a-local-interface

Note however that the described Varlink interface is not actually
implemented here, the directory is introduced however in a fashion that
conceptually matches the registry defined there, and would allow us to
implement the registry interface on top of it. (One of the reason the
registry Varlink API is not implemented right now is that the URI format
it relies on is entirely unspecified in the Varlink docs right now. Some
research needs to be done to extract what's implemented in the reference
implementation and to determine how it maps to the Varlink entrypoint
address format systemd's own tooling currently uses)

This primarily installs the symlinks via Symlinks= in unit files and via
a new tmpfiles.d/ drop-in. But since we touch all .socket units relating
to Varlink this also sets the FileDescriptorName= to varlink for each,
just to minimize diffrences and make things work more alike (the
services in questin don't care about the name, so this doesn't change).
In one case we replace a pair of separate sockets for two closely
related varlink services by a socket and a symlink, so that we can
safely use Symlinks= to also install the registry symlinks.
This commit is contained in:
Lennart Poettering
2026-02-09 10:44:47 +01:00
parent 4a54381d07
commit 382f141fea
27 changed files with 65 additions and 4 deletions
+18
View File
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# See tmpfiles.d(5) for details.
# Varlink AF_UNIX entrypoint socket inodes of relevant system services may be
# linked into this directory, to make them "well-known". Typically, tools such
# as the Varlink HTTP bridge expose services linked in here as public
# interfaces. The symlink should be named after the Varlink interface to
# expose. Interfaces that may be implemented by multiple services (such as
# the generic "io.systemd.service") should not be symlinked here.
d /run/varlink/registry/ 0755 root root
# Socket activated services should use Symlinks= in the .socket unit file to
# create these symlinks. If that's not applicable, consider creating the
# symlinks via a tmpfiles.d/ snippet, like we do here, so that registration can
# be influenced by the administrator.
L /run/varlink/registry/io.systemd.Unit - - - - ../../systemd/io.systemd.Manager
L /run/varlink/registry/io.systemd.Manager - - - - ../../systemd/io.systemd.Manager
L /run/varlink/registry/io.systemd.Journal - - - - ../../systemd/journal/io.systemd.journal
+3
View File
@@ -13,6 +13,7 @@ files = [['README' ],
['systemd-nspawn.conf', 'ENABLE_MACHINED' ],
['systemd-pstore.conf', 'ENABLE_PSTORE' ],
['systemd-resolve.conf', 'ENABLE_RESOLVE' ],
['20-systemd-varlink.conf' ],
['systemd-tmp.conf' ],
['tmp.conf' ],
['x11.conf' ],
@@ -59,3 +60,5 @@ endforeach
if install_sysconfdir
install_emptydir(sysconfdir / 'tmpfiles.d')
endif
subdir('user')
+7
View File
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# See tmpfiles.d(5) for details.
d %t/varlink/registry/ 0755
L %t/varlink/registry/io.systemd.Unit - - - - ../../systemd/io.systemd.Manager
L %t/varlink/registry/io.systemd.Manager - - - - ../../systemd/io.systemd.Manager
+11
View File
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
files = [ '20-systemd-varlink.conf' ]
foreach f : files
install_data(f, install_dir : usertmpfilesdir)
endforeach
if install_sysconfdir
install_emptydir(sysconfdir / 'user-tmpfiles.d')
endif
+1
View File
@@ -15,6 +15,7 @@ Before=sockets.target
[Socket]
ListenStream=/run/systemd/io.systemd.AskPassword
Symlinks=/run/varlink/registry/io.systemd.AskPassword
FileDescriptorName=varlink
SocketMode=0666
Accept=yes
+1
View File
@@ -16,6 +16,7 @@ Before=sockets.target
[Socket]
ListenStream=/run/systemd/io.systemd.BootControl
Symlinks=/run/varlink/registry/io.systemd.BootControl
FileDescriptorName=varlink
SocketMode=0600
Accept=yes
+1
View File
@@ -15,6 +15,7 @@ Before=sockets.target
[Socket]
ListenStream=/run/systemd/io.systemd.Credentials
Symlinks=/run/varlink/registry/io.systemd.Credentials
FileDescriptorName=varlink
SocketMode=0666
Accept=yes
+1
View File
@@ -15,6 +15,7 @@ Before=sockets.target
[Socket]
ListenStream=/run/systemd/io.systemd.FactoryReset
Symlinks=/run/varlink/registry/io.systemd.FactoryReset
FileDescriptorName=varlink
SocketMode=0666
Accept=yes
+1
View File
@@ -15,5 +15,6 @@ Documentation=man:machine-info(5)
[Socket]
ListenStream=/run/systemd/io.systemd.Hostname
Symlinks=/run/varlink/registry/io.systemd.Hostname
FileDescriptorName=varlink
SocketMode=0666
+1
View File
@@ -20,5 +20,6 @@ Before=shutdown.target
[Socket]
ListenStream=/run/systemd/io.systemd.Import
Symlinks=/run/varlink/registry/io.systemd.Import
FileDescriptorName=varlink
SocketMode=0666
+1
View File
@@ -13,6 +13,7 @@ Documentation=man:systemd-logind.service(8)
[Socket]
ListenStream=/run/systemd/io.systemd.Login
Symlinks=/run/varlink/registry/io.systemd.Login
FileDescriptorName=varlink
SocketMode=0666
Service=systemd-logind.service
+1 -1
View File
@@ -13,6 +13,6 @@ Documentation=man:systemd-machined.service(8)
[Socket]
ListenStream=/run/systemd/machine/io.systemd.Machine
ListenStream=/run/systemd/machine/io.systemd.MachineImage
Symlinks=/run/systemd/machine/io.systemd.MachineImage /run/varlink/registry/io.systemd.Machine /run/varlink/registry/io.systemd.MachineImage
FileDescriptorName=varlink
SocketMode=0666
+2
View File
@@ -16,6 +16,8 @@ Before=sockets.target shutdown.target
[Socket]
ListenStream=/run/systemd/io.systemd.MountFileSystem
Symlinks=/run/varlink/registry/io.systemd.MountFileSystem
FileDescriptorName=varlink
SocketMode=0666
[Install]
+1
View File
@@ -17,6 +17,7 @@ Before=shutdown.target
[Socket]
ListenStream=/run/systemd/io.systemd.MuteConsole
Symlinks=/run/varlink/registry/io.systemd.MuteConsole
FileDescriptorName=varlink
SocketMode=0600
Accept=yes
+1
View File
@@ -17,6 +17,7 @@ Conflicts=shutdown.target
[Socket]
ListenStream=/run/systemd/netif/io.systemd.Network
Symlinks=/run/varlink/registry/io.systemd.Network
FileDescriptorName=varlink
SocketMode=0666
Service=systemd-networkd.service
+2 -1
View File
@@ -16,7 +16,8 @@ Before=sockets.target shutdown.target
[Socket]
ListenStream=/run/systemd/io.systemd.NamespaceResource
Symlinks=/run/systemd/userdb/io.systemd.NamespaceResource
Symlinks=/run/systemd/userdb/io.systemd.NamespaceResource /run/varlink/registry/io.systemd.NamespaceResource
FileDescriptorName=varlink
SocketMode=0666
[Install]
+1
View File
@@ -17,6 +17,7 @@ ConditionSecurity=measured-uki
[Socket]
ListenStream=/run/systemd/io.systemd.PCRExtend
Symlinks=/run/varlink/registry/io.systemd.PCRExtend
FileDescriptorName=varlink
SocketMode=0600
Accept=yes
+1
View File
@@ -17,6 +17,7 @@ ConditionSecurity=measured-uki
[Socket]
ListenStream=/run/systemd/io.systemd.PCRLock
Symlinks=/run/varlink/registry/io.systemd.PCRLock
FileDescriptorName=varlink
SocketMode=0600
Accept=yes
+1
View File
@@ -17,6 +17,7 @@ Before=shutdown.target
[Socket]
ListenStream=/run/systemd/io.systemd.Repart
Symlinks=/run/varlink/registry/io.systemd.Repart
FileDescriptorName=varlink
SocketMode=0600
Accept=yes
+1
View File
@@ -17,6 +17,7 @@ Conflicts=shutdown.target
[Socket]
Service=systemd-resolved.service
ListenStream=/run/systemd/resolve/io.systemd.Resolve.Monitor
Symlinks=/run/varlink/registry/io.systemd.Resolve.Monitor
FileDescriptorName=varlink-monitor
SocketMode=0666
+1
View File
@@ -17,6 +17,7 @@ Conflicts=shutdown.target
[Socket]
Service=systemd-resolved.service
ListenStream=/run/systemd/resolve/io.systemd.Resolve
Symlinks=/run/varlink/registry/io.systemd.Resolve
FileDescriptorName=varlink
SocketMode=0666
+1
View File
@@ -17,6 +17,7 @@ ConditionCapability=CAP_SYS_ADMIN
[Socket]
ListenStream=/run/systemd/io.systemd.sysext
Symlinks=/run/varlink/registry/io.systemd.sysext
FileDescriptorName=varlink
SocketMode=0666
Accept=yes
+1
View File
@@ -17,6 +17,7 @@ ConditionPathIsReadWrite=/sys
[Socket]
Service=systemd-udevd.service
ListenStream=/run/udev/io.systemd.Udev
Symlinks=/run/varlink/registry/io.systemd.Udev
FileDescriptorName=varlink
SocketMode=0600
RemoveOnStop=yes
+2 -1
View File
@@ -15,7 +15,8 @@ Before=sockets.target
[Socket]
ListenStream=/run/systemd/userdb/io.systemd.Multiplexer
Symlinks=/run/systemd/userdb/io.systemd.NameServiceSwitch /run/systemd/userdb/io.systemd.DropIn
Symlinks=/run/systemd/userdb/io.systemd.NameServiceSwitch /run/systemd/userdb/io.systemd.DropIn /run/varlink/registry/io.systemd.UserDatabase
FileDescriptorName=varlink
SocketMode=0666
RemoveOnStop=yes
+1
View File
@@ -15,6 +15,7 @@ Before=sockets.target
[Socket]
ListenStream=%t/systemd/io.systemd.AskPassword
Symlinks=%t/varlink/registry/io.systemd.AskPassword
FileDescriptorName=varlink
SocketMode=0600
Accept=yes
+1
View File
@@ -14,5 +14,6 @@ Documentation=man:org.freedesktop.import1(5)
[Socket]
ListenStream=%t/systemd/io.systemd.Import
Symlinks=%t/varlink/registry/io.systemd.Import
FileDescriptorName=varlink
SocketMode=0600
+1 -1
View File
@@ -13,6 +13,6 @@ Documentation=man:systemd-machined.service(8)
[Socket]
ListenStream=%t/systemd/machine/io.systemd.Machine
ListenStream=%t/systemd/machine/io.systemd.MachineImage
Symlinks=%t/systemd/machine/io.systemd.MachineImage %t/varlink/registry/io.systemd.Machine %t/varlink/registry/io.systemd.MachineImage
FileDescriptorName=varlink
SocketMode=0600