如何创建 systemd 目标?

如何创建 systemd 目标?

在对有关 systemd 的大量帖子、Youtube 视频和“文档”进行了大量搜索之后,我仍然不知所措。

链接 (https://wiki.archlinux.org/index.php/systemd#Create_custom_target)似乎很有希望,但(对我来说)有点模糊。

问题

如何创建一个自定义的 systemd 目标(IE: foo.target ),以便可以使用选择的 .service 单元启动?

例子

  1. 系统启动default.target(“foo.target”的符号链接)
  2. “foo.target”仅启动准系统 X 服务器和 GUI 程序,例如“gvim”。

原因

我只是想创建一个自定义目标来快速启动一个 X 程序。我很乐意排除所有我不需要的服务。

提前致谢!

答案1

通读man 5 systemd.unitman 5 systemd.target告诉我们,单元文件用于定义目标以及 systemd 的其他所有内容。没有专门关于如何创建的文档目标,所以很难确定应该如何完成,但这与创建服务没有太大区别。

当您创建目标时,您需要符号链接target.wants从 systemd services 目录到该目录。然后你可以设置/启动你的目标。根据您的示例,它可能如下所示。

/etc/systemd/system/foo.target

这是目标的单元文件。如果以graphical.target为例,我们可以使用它作为基础来创建我们自己的目标。

[Unit]
Description=Foobar boot target
Requires=multi-user.target
Wants=foobar.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target
AllowIsolate=yes

解释 systemd 联机帮助页中的选项;

  • Description——描述目标。你应该明白
  • Requires-- 目标的硬依赖性。您应该在启动自己的服务之前先启动基本系统
  • Wants——软依赖性。目标不要求这些就可以开始了。
  • Conflicts-- 如果一个单元与另一个单元有冲突设置,则启动前者将停止后者,反之亦然。
  • After-- 在这些服务之后启动
  • AllowIsolate-- 完全取决于您和您的环境。详细信息可在联机帮助页中找到systemd.unit(5)

/etc/systemd/system/foo.target.wants/

您将在该目录中链接为目标创建/需要的服务。相当于Wants=单元文件中的选项。创建此目录,然后像这样创建符号链接;ln -s /usr/lib/systemd/system/bar.service /etc/systemd/system/foo.target.wants/bar.service。这将创建一个从系统目录中的 bar.service 到 foo.target.wants 目录的符号链接。


我认为为服务创建单元文件有点超出了这个答案的范围,而且这个问题肯定有更多记录,所以我现在将其保留。创建单元文件时,只需将其符号链接到 target.wants 目录或将其添加到Wants=指令中。

答案2

前面的答案中没有提到的是,为了让自定义 systemd 目标在启动时像 multi-user.target 一样工作,您必须以某种方式将其指定为启动过程的一部分。

基本上你想要做的是检查你当前的默认值是什么:systemctl get-default。它很可能是graphical.targetmulti-user.target

然后,您需要在/etc/systemd/system新的默认目标中创建符号链接,并确保您的目标是引导过程的扩展。

ln -s /etc/systemd/system/foo.target /etc/systemd/system/default.target

检查:

systemctl daemon-reload
systemctl get-default

如果multi-user.target是您以前的默认值,您将需要在您的自定义单元中对其进行配置,如下所示,如 m32 所提到的:

[Unit]
Description=Foobar boot target
Requires=multi-user.target
Wants=foobar.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target
AllowIsolate=yes

请注意,此处重要的一点是 multi-user.target 被指定为 Requires。有关所有含义的详细信息,请参阅 @m32 的答案。

您在这里所做的是使用您的自定义单元扩展启动过程。将其设置为 systemd 的默认值会指示 systemd 在启动时加载该单元。然后,该目标的配置会拉动任何其他目标,直到达到最基本的目标为止。至少我现在是这么理解的。

然后,就像其他答案中提到的那样,您可以在Wants=指令中指定您的单元foo.target并将其添加WantedBy=foo.target到单元的安装部分。请注意,您仍然需要激活您想要在启动时使用的任何单元systemd enable foobar.service

总结一下:

  1. 创建您的目标作为现有目标的扩展
  2. 创建符号链接以使其成为您的默认目标
  3. 在您想要以此开始的所有单位中指定该目标
  4. 以这种方式启用您想要在启动时启动的任何单元

这篇关于运行级别的文档有更多细节:https://www.landoflinux.com/linux_runlevels_systemd.html

答案3

我强烈建议您在完成这项任务之前先看看这些例子,

vim /lib/systemd/system/*.target

请注意,如果您要创建自己的目标,则无需手动链接任何内容。

您只需将服务添加到/etc/systemd/system并在其上运行即可systemctl enable。只要它WantedByRequiredBysystemd 就会为您完成所有工作。

相关内容