NBD 用于提供块设备给远程设备使用是一种非常简便、低成本的方法。然而,让 NBD 开始工作的方法在网上能找到很多,但是 NBD 客户端的配置持久化却很难搜到比较完整的资料。在参考了一些过时博客、manpage 等比较分散的资料之后,我总算是凭借蛛丝马迹找到了应当是正确的配置方法。
1、自动加载 nbd 内核模块
echo nbd > /etc/modules-load.d/nbd.conf
(虽然——我觉得这件事应该在 nbd 包里完成,因为上游不愿意默认提供的理由只是为了考虑 nbd 未被编译为内核模块的情况。)
2、/etc/nbdtab
没错,光是发现这个东西就花了我不少时间。
nbd 服务器、连接选项等本来在 nbd-client 命令中配置的内容,应当被写到这个文件里。
一个简单的例子:
nbd0 192.168.0.10 export0 persist
显而易见,分别对应设备名、服务器地址、服务器上配置的 export 名、其他选项。完整的介绍可以参考对应的 manpage。
3、/etc/fstab 和 nbd@<设备名>.service
到这里就是最后一步了,也是非常容易出错的一步。
此处的设备名应当和 nbdtab 内配置的设备名相符,nbdtab 的配置由这个对应的服务应用。和其他网络设备一样,挂载点、挂载相关的配置应当设置在 /etc/fstab。
这里需要使用 x-systemd.requires 来声明对 systemd 服务的依赖关系。由于服务会被这个依赖关系自动唤起,不需要手动 enable 服务。
/dev/nbd0 /var/lib/archbuild btrfs defaults,x-systemd.requires=nbd@nbd0.service,_netdev,nofail 0 0
这里的 _netdev 会让 systemd 等待网络可用后再进行挂载。注意我在这里写了 nofail 以避免因为网络原因使设备无法启动。如果要考虑在访问时再挂载,也可以改用 noauto,x-systemd.automount 之类的方法。
参考资料:
有没有可能给 service 添加 Wants&After=modprobe@nbd.service? 毕竟某 initrd generator (namely, dracut) 会想要把 /etc/modules-load.d 的内容塞进 initrd.