Debian Buster:如何在 systemd 中 open-iscsi 后启动 ZFS

Chr*_*ner 5 zfs debian open-iscsi systemd

我安装了 Debian 10 (Buster) 并从 Backports 添加了 ZFS。我有 4 个 iSCSI-LUN,用作 ZFS 的磁盘。每个 LUN 都有一个单独的 zpool。

到目前为止,ZFS 设置有效。但是系统不是重启稳定的。有时重新启动后,所有 ZFS 卷都会恢复并正确安装,有时则不会。我认为会发生这种情况,因为 ZFS 不会等待 iSCSI 完成。

我试过:

/etc/systemd/system/zfs-import-cache.d/after-open-iscsi.conf

[Unit]
After=open-iscsi.service
BindsTo=open-iscsi.service
Run Code Online (Sandbox Code Playgroud)

systemd-analyze 关键链 zfs-import-cache.service

The time after the unit is active or started is printed after the "@" character.
The time the unit takes to start is printed after the "+" character.

zfs-import-cache.service +1.602s
??open-iscsi.service @2min 1.033s +286ms
  ??iscsid.service @538ms +72ms
    ??network-online.target @536ms
      ??ifup@eth0.service @2min 846ms
        ??apparmor.service @2min 748ms +83ms
          ??local-fs.target @2min 745ms
            ??exports-kanzlei.mount @2min 3.039s
              ??local-fs-pre.target @569ms
                ??keyboard-setup.service @350ms +216ms
                  ??systemd-journald.socket @347ms
                    ??system.slice @297ms
                      ??-.slice @297ms
Run Code Online (Sandbox Code Playgroud)

这不能解决我的问题。可能 iSCSI 的东西还没有准备好,但已经被系统激活,因此 ZFS 找不到它的设备。

目前唯一非常肮脏的解决方法是在 /etc/rc.local 中设置一些规则:

systemctl start zfs-import-cache.service
systemctl start zfs-mount.service
systemctl start zfs-share.service
systemctl start zfs-zed.service

zfs mount -a
Run Code Online (Sandbox Code Playgroud)

这有效,但我想要一个干净的解决方案。

我真的不明白并且让我发疯的是,在 Debian 中确实存在 /etc/init.d/scriptname 和 systemd 单元文件。使用哪一种?sysvinit 还是 systemd?为什么两者都提供?哪些是更好的?

所以目前我觉得我这里的启动过程不稳定。

谢谢你的帮助 ;-)

rei*_*ost 0

推荐的方法可能是使用规则udev,但我不太了解udev。这是我目前的解决方法(请告诉我如何做得更好):

  1. 为您需要等待的 iSCSI 磁盘设备创建一个服务(/dev/sdb1在我的例子中为 ):

    $ sudo EDITOR=vim systemctl edit --force --full dev-sdb1.service

  2. 在服务定义中,让ZFS依赖它。

  3. 在服务定义中,使其等待设备可用。

3是棘手的部分。我所拥有的是这样的:

[Unit]
Description="Monitor the existence of /dev/sdb1"
Before=zfs-import-cache.service
# Requires=dev-sdb1.device
# After=dev-sdb1.device
# I thought this would wait for the device to become available.
# It doesn't, and there appears to be no way to actually do so.

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'while [ ! -e /dev/sdb1 ]; do sleep 10; done'
# pathetic

[Install]
WantedBy=multi-user.target
RequiredBy=zfs-import-cache.service 
Run Code Online (Sandbox Code Playgroud)

显然,最好不使用 shell 脚本来轮询设备。阅读有关设备单元的文档以及这些 Stack Exchange 问题的答案后:

并验证dev-sdb1.device启动后是否存在,我希望能够通过添加规则来zfs-import-cache.service等待/dev/sdb1

After=dev-sdb1.device
Requires=dev-sdb1.device
Run Code Online (Sandbox Code Playgroud)

到它的定义。那是行不通的;它会说服务failed with result 'dependency',无论是什么意思。我想它dev-sdb1.device还不存在,systemd不知道它会很快被创建,而且我找不到一个指令来表示“只需等待它”。

替代方法:

  1. 使用路径单元而不是 shell 脚本来等待设备。我没试过这个。
  2. 添加udev规则匹配/dev/sdbor /dev/sdb1(如果可能)以显式使其设备单位可用。我没试过这个;我不明白为什么它会有所帮助(设备单元已经被创建),并且我不知道如何弄清楚这是否会对设备初始化产生任何其他影响并因此破坏任何内容。