首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >启动系统d服务共享无头系统上的会话D总线

启动系统d服务共享无头系统上的会话D总线
EN

Server Fault用户
提问于 2018-01-16 14:53:18
回答 1查看 27.5K关注 0票数 22

我需要帮助启动服务,通过会话(而不是系统)D总线在无头Linux系统上进行通信。关键是没有人会登录到无头系统。

到目前为止,我已经能够启动一个D总线守护进程,并代表一个没有登录的用户(“其他用户”)在三个不同的终端中测试D总线通信:

在第一个终端中,我为“其他用户”启动了一个D总线守护进程:

代码语言:javascript
复制
$ sudo -u otheruser dbus-daemon --session --print-address 1
unix:abstract=/tmp/dbus-a5cU7r4IHc,guid=6c0a9bbfd02f5f68da0fe32f5a5e0a48

在第二个终端中,我使用上面的DBUS_SESSION_BUS_ADDRESS响应启动D总线服务器应用程序:

代码语言:javascript
复制
$ sudo -u otheruser DBUS_SESSION_BUS_ADDRESS="unix:abstract=/tmp/dbus-a5cU7r4IHc,guid=6c0a9bbfd02f5f68da0fe32f5a5e0a48" /usr/bin/my-dbus-service

然后,在第三个终端中,我可以测试连接:

代码语言:javascript
复制
$ sudo -u otheruser DBUS_SESSION_BUS_ADDRESS="unix:abstract=/tmp/dbus-a5cU7r4IHc,guid=6c0a9bbfd02f5f68da0fe32f5a5e0a48" gdbus introspect --session --dest com.mycompany.myappname --object-path /com/mycompany/interface

但是,我想通过systemd启动D总线服务器应用程序以及一些客户端D总线服务。如何通过systemd启动D总线会话,以便将其DBUS_SESSION_BUS_ADDRESS环境变量传播到D总线服务器和“其他用户”的客户端服务?

一种可能的解决方案可能是将dbus-守护进程的输出输送到"somefile“中,然后在启动D-Bus服务器和客户端之前设置DBUS_SESSION_BUS_ADDRESS=$(cat somefile)。这对我来说有点太尴尬了;特别是因为我知道systemd服务文件中有一个用于systemd总线连接的"Busname“指令。如何正确启动“其他用户”的systemd服务,以便这些systemd服务能够与会话D总线接口通信?

EN

回答 1

Server Fault用户

回答已采纳

发布于 2018-04-05 17:21:33

你需要几样东西才能让这件事起作用。

  1. 启用用户服务在启动时运行,而不需要用户登录(systemd逗留)。
  2. 一个systemd套接字文件,用于为systemd分配指定D总线套接字。
  3. 一个systemd服务来启动启动的D总线会话总线,然后为其他systemd服务设置DBUS_SESSION_BUS_ADDRESS env。
  4. 确保您的systemd my-dbus-client.service文件为Type=dbus或依赖于dbus.socket单元,以确保它们分配dbus会话总线套接字,并在尚未启动的情况下启动dbus会话服务。

首先,要使某个给定用户的Systemd服务在没有登录的情况下在启动时启动,您需要启用systemd用户停留--在为用户进行配置以启用它时,只需要将其作为根用户执行一次:

代码语言:javascript
复制
# loginctl enable-linger otheruser

接下来,如果您是在基于Debian的系统上,那么接下来的两个步骤,您可以简单地安装包dbus-user会话包:

代码语言:javascript
复制
# apt-get install dbus-user-session

如果您正在使用其他发行版,则希望手动执行此操作,或者只想了解它如何继续工作。否则,跳过dbus.servicedbus.socket的创建。

创建文件/usr/lib/systemd/user/dbus.socket (注意,在某些发行版上,用户目录可能位于/lib而不是/usr/lib下),其内容如下:

代码语言:javascript
复制
[Unit]
Description=D-Bus User Message Bus Socket

[Socket]
ListenStream=%t/bus
ExecStartPost=-/bin/systemctl --user set-environment DBUS_SESSION_BUS_ADDRESS=unix:path=%t/bus

[Install]
WantedBy=sockets.target
Also=dbus.service

DBUS_SESSION_BUS_ADDRESS传播到所有服务(这是您主要关心的问题)将由下面的ExecPostStart行来解决--下面的所有服务都将设置该设置。

%tXDG_RUNTIME_DIR所取代--这是一个在/run下创建的临时目录,该目录由特定于用户会话的systemd创建,您可以填充文件。如果你想在其他地方创建这个套接字,你没有理由不能这样做,只要确保它是暂时的,否则它会在重新启动/会话删除时被清理掉。

我确实遇到了一些问题,试图使dbus unix套接字成为抽象的单系统,但出于某种原因,我似乎不喜欢表单unix:abstract=@前缀。

现在创建具有以下内容的文件/usr/lib/systemd/user/dbus.service

代码语言:javascript
复制
[Unit]
Description=D-Bus User Message Bus
Requires=dbus.socket

[Service]
ExecStart=/usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation
ExecReload=/usr/bin/dbus-send --print-reply --session --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig

[Install]
Also=dbus.socket

在系统d的幕后,有一点魔力可以将已经创建的unix套接字传递给dbus-守护进程。Systemd使用来自dbus.socket的信息创建套接字,它的文件描述符在环境变量LISTEN_FDS中进行设置,该变量被传递给dbus-daemon。上面列出的特殊选项使得dbus-守护进程使用传入的文件描述符,而不是创建新的。这允许dbus客户端与dbus-守护进程并行启动,无需担心套接字不存在。

最后,创建您自己的systemd用户服务,确保将类型设置为Type=dbus,将BusName=设置为将由该服务注册的dbus服务名称之一,或者确保在Unit部分中指定了Requires=dbus.socket。下面是一个示例:

代码语言:javascript
复制
[Unit]
Description=Config Server Startup

[Service]
Type=dbus
BusName=com.example.app.configuree
ExecStart=/opt/example/app/configuration_server
Restart=on-failure

[Install]
WantedBy=default.target

您可以将它们放置在以下几个地方之一:

  • $HOME/.config/systemd/user
  • /usr/lib/systemd/user

使用systemctl --user enable 和重新启动启用您的服务,一切都应该正常工作。

要使systemctl --user ..工作,需要有一个完整的systemd登录环境才能存在/run/user/{uid}。.创建的轻量级环境。-登录或不设置此设置。您需要ssh,登录到控制台,或者,如果您运行一个正确设置的systemd发行版,您可以抓取并使用machinectl shell在当前shell中创建完整的systemd环境。

参考文献:

  • 留声机man loginctl
  • man pam_systemd获取XDG_RUNTIME_DIR信息
  • man systemd.service用于Type=dbus、BusName=和对dbus.socket的隐式依赖
  • man sd_listen_fds获取有关LISTEN_FDS环境变量的信息
  • https://wiki.archlinux.org/index.php/Systemd/User -系统用户会话的一般信息
票数 28
EN
页面原文内容由Server Fault提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://serverfault.com/questions/892465

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档