根据这个答案,DHCPd 租约文件每小时清除一次。目标是连续备份租约文件,这样租约就不会丢失。这很困难,因为不清楚小时计时器是基于系统时间(例如文件在凌晨 1 点、2 点、3 点等重写)还是基于进程时间(service_start + 1h、service_start + 2h 等)。假设租约文件在凌晨 3 点准时清除,租约在 2:58:55 授予;备份租约文件的服务需要在文件清除之前快速运行。
DHCPd 进程会自行将文件备份到/var/lib/dhcpd/dhcpd.leases~
。那么最好的办法似乎是编写一个脚本,每小时将此文件备份到另一个位置。但是,如果重新启动 DHCPd 进程,并且计时器与进程相关,则备份任务上的小时标记可能会对齐,这可能会导致一个进程读取而另一个进程写入,这可能会损坏文件(取决于执行方式)。因此,备份任务需要了解 DHCPd 何时启动。这变得很复杂。
备份 DHCPd 租约文件的“正确”方法是什么,以免租约丢失?
答案1
从DHCP 源:
if (snprintf (backfname, sizeof backfname, "%s~", path_dhcpd_db) >= sizeof backfname) [...] if (unlink (backfname) < 0 && errno != ENOENT) { [...] if (link(path_dhcpd_db, backfname) < 0) {
先前的备份文件被删除,然后当前租约文件被硬链接为备份,并带有尾随的~
。
在 Linux 上,使用inotify(7)事件设施中,硬链接被视为创建事件。
我建议使用inotifywait
(来自inotify-tools
包)来发出此类事件发生时的信号。人们应该期望出现/var/lib/dhcpd/dhcpd.leases~
直接准备备份的文件(它是原始文件的硬链接)。由于文件每次都是不同的文件(不同的 inode),因此应该监视目录以进行正确的检测,例如,--include
可以使用该选项来简化 shell 处理(不进行处理,甚至读取的行也会被丢弃在虚拟变量中):
inotifywait -m -e create --include dhcpd.leases~ /var/lib/dhcpd | while read dummy; do
do_backup /var/lib/dhcpd/dhcpd.leases~
done
如果命令不够新,它可能无法理解,--include
在这种情况下,测试必须在事件循环中完成:
inotifywait -m -e create /var/lib/dhcpd | while read -r dir event filename; do
if [ "$filename" = dhcpd.leases~ ]; then
do_backup /var/lib/dhcpd/dhcpd.leases~
fi
done
或者,该incron
软件包(至少在 CentOS 8 Stream 上可用)可以与入口如同:
/var/lib/dhcpd IN_CREATE,recursive=false if_correct_file_do_backup $#
例如,使用if_correct_file_do_backup
shell 检查这是否是预期的文件名:
#!/bin/sh
if [ "$1" = dhcpd.leases~ ]; then
do_backup /var/lib/dhcpd/dhcpd.leases~
fi