<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  <!ENTITY % general-entities SYSTEM "../general.ent">
  %general-entities;
]>

<sect1 id="ch-scripts-systemd-custom" revision="systemd">
  <?dbhtml filename="systemd-custom.html"?>

  <title>Systemd 使用和配置</title>

  <indexterm zone="ch-scripts-systemd-custom">
    <primary sortas="e-Systemd">Systemd Customization</primary>
  </indexterm>

  <sect2>
    <title>基础设置</title>

	<para><filename>/etc/systemd/system.conf</filename>
		文件包含一组控制 systemd 基本功能的选项。
		默认文件中所有条目都被注释掉，并标明了默认值。
		可以在这里修改日志级别，以及其他一些基本日志设定。
		参阅 <filename>systemd-system.conf(5)</filename>
		man 手册页面了解每个选项的详细信息。</para>

  </sect2>

  <sect2>
    <title>禁用引导时自动清屏</title>

    <para>Systemd 的默认行为是在引导过程结束时清除屏幕。
    如果希望的话，您可以运行以下命令，修改这一行为：</para>

<screen role="nodump"><userinput>mkdir -pv /etc/systemd/system/getty@tty1.service.d

cat &gt; /etc/systemd/system/getty@tty1.service.d/noclear.conf &lt;&lt; EOF
<literal>[Service]
TTYVTDisallocate=no</literal>
EOF</userinput></screen>

    <para>您总是可以用 root 身份运行
    <userinput>journalctl -b</userinput> 命令，查阅引导消息。</para>

  </sect2>

  <sect2>
    <title>禁止将 tmpfs 挂载到 /tmp</title>

	<para>默认情况下，
		<filename class="directory">/tmp</filename> 被挂载 tmpfs 文件系统。
		如果不希望这样，可以执行以下命令覆盖这一行为：</para>

<screen role="nodump"><userinput>ln -sfv /dev/null /etc/systemd/system/tmp.mount</userinput></screen>

    <para>或者，如果希望使用一个单独的
    <filename class="directory">/tmp</filename> 分区，
    在 <filename>/etc/fstab</filename> 中为其添加一个条目。</para>

    <warning>
      <para>
        如果使用了单独的
		<filename class="directory">/tmp</filename> 分区，
		不要创建上面的符号链接。这会导致根文件系统（/）
		无法重新挂载为可读写，使得系统在引导后不可用。
      </para>
    </warning>

  </sect2>

  <sect2>
    <title>配置文件自动创建和删除</title>

    <para>有一些创建或删除文件、目录的服务：</para>

    <itemizedlist>
      <listitem><para>systemd-tmpfiles-clean.service</para></listitem>
      <listitem><para>systemd-tmpfiles-setup-dev.service</para></listitem>
      <listitem><para>systemd-tmpfiles-setup.service</para></listitem>
    </itemizedlist>
  
    <para>它们的系统配置文件位于
    <filename>/usr/lib/tmpfiles.d/*.conf</filename>，
    本地配置文件位于
    <filename class="directory">/etc/tmpfiles.d</filename>。
    <filename class="directory">/etc/tmpfiles.d</filename>
    中的文件覆盖
	<filename class="directory">/usr/lib/tmpfiles.d</filename>
	中的同名文件。参阅
    <filename>tmpfiles.d(5)</filename> man 手册页面，
    了解配置文件格式的细节。</para>

    <para>
      注意
      <filename>/usr/lib/tmpfiles.d/*.conf</filename> 文件的语法较难理解。
	  例如，删除 /tmp 目录下文件的默认规则是文件
	  <filename>/usr/lib/tmpfiles.d/tmp.conf</filename> 的一行： 

<screen role="nodump">q /tmp 1777 root root 10d</screen>

    <!--The type field, q, discusses creating a subvolume with quotas which
      is really only applicable to btrfs filesystems.  It references type v
      which in turn references type d (directory). This then creates the
      specified directory if is is not present and adjusts the permissions
      and ownership as specified.  Contents of the directory will be
	  subject to time based cleanup if the age argument is specified. -->
	  类别字段 q 表示创建一个带有配额的子卷，它实际上只适用于 btrfs
	  文件系统。它引用类别 v ，类别 v 又引用类别 d ，
	  类别 d 在目录不存在时自动创建它，并根据配置文件调整其权限和所有者。
	  如果 age 参数被指定（如上面的 10d），该目录中较老的文件会被自动清理。
     </para>

     <!--para>
      If the default parameters are not desired, then the file should
      be copied to <filename class="directory">/etc/tmpfiles.d</filename>
	  and edited as desired.  For example:-->
     <para>如果默认参数不符合您的期望，您可以将文件复制到
		 <filename class="directory">/etc/tmpfiles.d</filename>
		 目录，再编辑复制得到的副本。例如：

<screen role="nodump"><userinput>mkdir -p /etc/tmpfiles.d
cp /usr/lib/tmpfiles.d/tmp.conf /etc/tmpfiles.d</userinput></screen>
     </para>

  </sect2>

  <sect2>
    <title>覆盖系统服务默认行为</title>

	<para>Systemd 单元的参数可以通过在
		<filename class="directory">/etc/systemd/system</filename>
		中创建一个包含配置文件的目录而覆盖。例如：</para>

<screen role="nodump"><userinput>mkdir -pv /etc/systemd/system/foobar.service.d

cat > /etc/systemd/system/foobar.service.d/foobar.conf &lt;&lt; EOF
<literal>[Service]
Restart=always
RestartSec=30</literal>
EOF</userinput></screen>

	 <para>参阅 <filename>systemd.unit(5)</filename>
     man 手册页面获取更多信息。在创建配置文件后，执行
     <userinput>systemctl daemon-reload</userinput> 和 <userinput>systemctl
     restart foobar</userinput>，激活对服务进行的修改。</para>

  </sect2>

  <sect2>
    <title>调试引导过程</title>

    <!--para>Rather than plain shell scripts used in SysVinit or BSD style init
    systems, systemd uses a unified format for different types of startup
    files (or units). The command <command>systemctl</command> is used to
    enable, disable, control state, and obtain status of unit files. Here 
    are some examples of frequently used commands:</para-->
    <para>与 SysVinit 或 BSD 风格 init 系统不同，
		systemd 使用统一格式处理不同种类的启动文件（或称为单元）。
		命令 <command>systemctl</command> 能够启用、禁用单元文件，
		或控制、查询单元文件的状态。以下是一些常用的命令：</para>

    <itemizedlist>
       <listitem>
         <para><command>systemctl list-units -t service [--all]</command>:
         列出已加载的服务（service）类型单元文件。</para>
       </listitem>
       <listitem>
         <para><command>systemctl list-units -t target [--all]</command>:
         列出已加载的目标（target）类型单元文件。</para>
       </listitem>
       <listitem>
         <para><command>systemctl show -p Wants <replaceable>multi-user.target</replaceable></command>:
         显示所有依赖于 multi-user 目标的单元，
		 目标（target）是一种和 SysVinit 中运行级别（runlevel）
		 地位相同的特殊单元文件。</para>
       </listitem>
       <listitem>
         <para><command>systemctl status <replaceable>&lt;servicename.service&gt;</replaceable></command>:
         显示名为 servicename 的服务的状态。如果没有同名的其他类型单元文件，
		 可以省略 .service 后缀。其他类型的单元文件有 .socket 文件
	    （它创建一个监听套接字，提供和 inetd/xinetd 类似的功能）。</para>
       </listitem>
    </itemizedlist>

  </sect2>

  <sect2>
    <title>使用 systemd 日志</title>

    <!--para>Logging on a system booted with systemd is handled with
    systemd-journald (by default), rather than a typical unix syslog daemon.
    You can also add a normal syslog daemon and have both work side by
    side if desired. The systemd-journald program stores journal entries in a
    binary format rather than a plain text log file. To assist with
    parsing the file, the command <command>journalctl</command> is provided.
    Here are some examples of frequently used commands:</para-->
    <para>（默认情况下）在使用 systemd 引导的系统上，
		systemd-journald 服务负责处理日志，它取代了传统的 Unix syslog
		守护进程。如果您希望的话，也可以添加一个普通 syslog 守护进程，
		它和 systemd-journald 可以一起工作。systemd-journald
		程序将日志项储存为二进制格式，而不是纯文本日志文件。
		为了解析日志文件，需要使用 systemd 提供的
		<command>journalctl</command> 命令。下面是该命令的常见用法：</para>

    <itemizedlist>
       <listitem>
         <para><command>journalctl -r</command>：按时间顺序，
         倒序显示所有日志内容。</para>
       </listitem>
       <listitem>
         <para><command>journalctl -u <replaceable>UNIT</replaceable></command>:
         显示与给定单元 UNIT 关联的日志。</para>
       </listitem>
       <listitem>
         <para><command>journalctl -b[=ID] -r</command>:
			 按时间倒序，显示自上次引导以来（或编号为 ID 的引导中）
			 的所有日志。</para>
       </listitem>
       <listitem>
         <para><command>journalctl -f</command>: 提供类似
         tail -f 的功能（不断将新日志项输出到屏幕）。</para>
       </listitem>
    </itemizedlist>

  </sect2>

  <sect2>
    <title>持续运行进程</title>

    <!--para>Beginning with systemd-230, all user processes are killed when a user
    session is ended, even if nohup is used, or the process uses the
    <function>daemon()</function> or <function>setsid()</function> functions.
    This is a deliberate change from a historically permissive environment to a
    more restrictive one. The new behavior may cause issues if you depend on
    long running programs (e.g., <command>screen</command> or
    <command>tmux</command>) to remain active after ending your user session.
    There are three ways to enable lingering processes to remain after a user
    session is ended.</para-->
    <para>从 systemd 的 230 版本开始，在用户会话结束时，
		所有用户进程都被杀死，即使使用了 nohup 或
		<function>daemon()</function> 、<function>setsid</function>
		等函数也不例外。这是开发者有意做出的修改，
		将传统的宽松环境改为更加严格的环境。如果您需要让持续运行的程序
		（例如 <command>screen</command> 或 <command>tmux</command>）
		在用户会话结束后保持运行，这项新的行为会导致问题。
		有三种方法使得这类驻留进程在用户会话结束后继续运行：</para>

    <itemizedlist>
      <listitem>
        <para>
          <emphasis>为选定的用户启用进程驻留</emphasis>：
		  <!--Normal users have permission to enable process lingering
          with the command <command>loginctl enable-linger</command> for their
          own user. System administrators can use the same command with a
          <parameter>user</parameter> argument to enable for a user. That user
          can then use the <command>systemd-run</command> command to start
          long running processes. For example: <command>systemd-run scope
          user /usr/bin/screen</command>. If you enable lingering for your
          user, the user@.service will remain even after all login sessions are
          closed, and will automatically start at system boot. This has the
          advantage of explicitly allowing and disallowing processes to run
          after the user session has ended, but breaks backwards compatibility
          with tools like <command>nohup</command> and utilities that use
		  <function>deamon()</function>.-->
		  普通用户有执行命令 <command>loginctl enable-linger</command>
		  启用进程驻留的权限，管理员可以使用带
		  <parameter>user</parameter> 参数的该命令，为特定用户启用进程驻留。
		  在启用进程驻留后，可以使用 <command>systemd-run</command>
		  命令启动持续运行的进程。例如，
		  <command>systemd-run --scope --user /usr/bin/screen</command>。
		  如果您为您的用户启用了进程驻留，则 user@.service 将持续运行，
		  甚至在所有登录会话关闭后仍然运行，而且会在系统引导时自动启动。
		  这种方法的好处是可以显式地允许或禁止进程在用户会话结束后继续运行，
		  但却破坏了和 <command>nohup</command> 等工具，和使用
		  <function>daemon()</function> 函数的工具的兼容性。
        </para>
      </listitem>
      <listitem>
        <para>
          <emphasis>为整个系统启用进程驻留</emphasis>:
          您可以在 <filename>/etc/logind.conf</filename> 中设定
		  <parameter>KillUserProcesses=no</parameter> 参数，
		  为所有用户全局地启用进程驻留。
		  它的好处是允许所有用户继续使用旧方法，但无法进行明确控制。
        </para>
      </listitem>
      <listitem>
        <para>
          <emphasis>在构建时禁用新功能</emphasis>: 您可以在构建
		  systemd 时向 <command>configure</command> 命令添加参数
		  <parameter>--without-kill-user-process</parameter>，
		  使得 systemd 默认启用进程驻留。
		  这完全禁用了 systemd 在会话结束时杀死用户进程的功能。
        </para>
      </listitem>
    </itemizedlist>

  </sect2>

</sect1>
