From: Lennart Poettering Date: Fri, 6 Feb 2026 14:04:11 +0000 (+0100) Subject: units: symlink well-known Varlink services into /run/varlink/registry/ X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=382f141fead03714820f274319bc606883a61c48;p=thirdparty%2Fsystemd.git 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. --- diff --git a/tmpfiles.d/20-systemd-varlink.conf b/tmpfiles.d/20-systemd-varlink.conf new file mode 100644 index 00000000000..96905ff4f1e --- /dev/null +++ b/tmpfiles.d/20-systemd-varlink.conf @@ -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 diff --git a/tmpfiles.d/meson.build b/tmpfiles.d/meson.build index 7f3fce48c9f..c8f9015b2ec 100644 --- a/tmpfiles.d/meson.build +++ b/tmpfiles.d/meson.build @@ -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') diff --git a/tmpfiles.d/user/20-systemd-varlink.conf b/tmpfiles.d/user/20-systemd-varlink.conf new file mode 100644 index 00000000000..6df6408f183 --- /dev/null +++ b/tmpfiles.d/user/20-systemd-varlink.conf @@ -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 diff --git a/tmpfiles.d/user/meson.build b/tmpfiles.d/user/meson.build new file mode 100644 index 00000000000..551e4fe56b9 --- /dev/null +++ b/tmpfiles.d/user/meson.build @@ -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 diff --git a/units/systemd-ask-password.socket b/units/systemd-ask-password.socket index c8d203b077b..df5eaffc22b 100644 --- a/units/systemd-ask-password.socket +++ b/units/systemd-ask-password.socket @@ -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 diff --git a/units/systemd-bootctl.socket b/units/systemd-bootctl.socket index f9553b840be..e720f24f543 100644 --- a/units/systemd-bootctl.socket +++ b/units/systemd-bootctl.socket @@ -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 diff --git a/units/systemd-creds.socket b/units/systemd-creds.socket index bf13c11e0fa..3ea3ca5b053 100644 --- a/units/systemd-creds.socket +++ b/units/systemd-creds.socket @@ -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 diff --git a/units/systemd-factory-reset.socket b/units/systemd-factory-reset.socket index d833ffdb995..467517ec24b 100644 --- a/units/systemd-factory-reset.socket +++ b/units/systemd-factory-reset.socket @@ -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 diff --git a/units/systemd-hostnamed.socket b/units/systemd-hostnamed.socket index 2a2cfce6531..288e736b471 100644 --- a/units/systemd-hostnamed.socket +++ b/units/systemd-hostnamed.socket @@ -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 diff --git a/units/systemd-importd.socket b/units/systemd-importd.socket index d1c9c22a4cd..a538ef0d0e0 100644 --- a/units/systemd-importd.socket +++ b/units/systemd-importd.socket @@ -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 diff --git a/units/systemd-logind-varlink.socket b/units/systemd-logind-varlink.socket index 3978e8ab903..1d3652e0497 100644 --- a/units/systemd-logind-varlink.socket +++ b/units/systemd-logind-varlink.socket @@ -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 diff --git a/units/systemd-machined.socket b/units/systemd-machined.socket index 3df5c7d8c30..75a91bb0ccc 100644 --- a/units/systemd-machined.socket +++ b/units/systemd-machined.socket @@ -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 diff --git a/units/systemd-mountfsd.socket b/units/systemd-mountfsd.socket index cd88003af90..431369a1a18 100644 --- a/units/systemd-mountfsd.socket +++ b/units/systemd-mountfsd.socket @@ -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] diff --git a/units/systemd-mute-console.socket b/units/systemd-mute-console.socket index 16032e94b4c..5eae6d5acd0 100644 --- a/units/systemd-mute-console.socket +++ b/units/systemd-mute-console.socket @@ -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 diff --git a/units/systemd-networkd-varlink.socket b/units/systemd-networkd-varlink.socket index 7d194fff345..1f4db858bc6 100644 --- a/units/systemd-networkd-varlink.socket +++ b/units/systemd-networkd-varlink.socket @@ -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 diff --git a/units/systemd-nsresourced.socket b/units/systemd-nsresourced.socket index 2e3c8e9baa2..c159a5676ae 100644 --- a/units/systemd-nsresourced.socket +++ b/units/systemd-nsresourced.socket @@ -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] diff --git a/units/systemd-pcrextend.socket b/units/systemd-pcrextend.socket index 4f747481254..d429150eda0 100644 --- a/units/systemd-pcrextend.socket +++ b/units/systemd-pcrextend.socket @@ -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 diff --git a/units/systemd-pcrlock.socket b/units/systemd-pcrlock.socket index ca1cd53aeac..e166caf3d84 100644 --- a/units/systemd-pcrlock.socket +++ b/units/systemd-pcrlock.socket @@ -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 diff --git a/units/systemd-repart.socket b/units/systemd-repart.socket index c9fc308b1b2..ecd275414d5 100644 --- a/units/systemd-repart.socket +++ b/units/systemd-repart.socket @@ -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 diff --git a/units/systemd-resolved-monitor.socket b/units/systemd-resolved-monitor.socket index a778e60dd29..3674a1f876e 100644 --- a/units/systemd-resolved-monitor.socket +++ b/units/systemd-resolved-monitor.socket @@ -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 diff --git a/units/systemd-resolved-varlink.socket b/units/systemd-resolved-varlink.socket index 7ac83e5ec9a..a5701683732 100644 --- a/units/systemd-resolved-varlink.socket +++ b/units/systemd-resolved-varlink.socket @@ -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 diff --git a/units/systemd-sysext.socket b/units/systemd-sysext.socket index 97d1695780e..61d7268f377 100644 --- a/units/systemd-sysext.socket +++ b/units/systemd-sysext.socket @@ -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 diff --git a/units/systemd-udevd-varlink.socket b/units/systemd-udevd-varlink.socket index 74353e7f1ae..c2b7652e5ea 100644 --- a/units/systemd-udevd-varlink.socket +++ b/units/systemd-udevd-varlink.socket @@ -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 diff --git a/units/systemd-userdbd.socket b/units/systemd-userdbd.socket index 6ef1adeca74..6793d1b41df 100644 --- a/units/systemd-userdbd.socket +++ b/units/systemd-userdbd.socket @@ -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 diff --git a/units/user/systemd-ask-password.socket b/units/user/systemd-ask-password.socket index ce9ccd9e55a..56492fae54d 100644 --- a/units/user/systemd-ask-password.socket +++ b/units/user/systemd-ask-password.socket @@ -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 diff --git a/units/user/systemd-importd.socket b/units/user/systemd-importd.socket index d266d927f85..67ea62bdb0a 100644 --- a/units/user/systemd-importd.socket +++ b/units/user/systemd-importd.socket @@ -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 diff --git a/units/user/systemd-machined.socket b/units/user/systemd-machined.socket index d368215e98e..17e552a7dcb 100644 --- a/units/user/systemd-machined.socket +++ b/units/user/systemd-machined.socket @@ -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