备份 ISC DHCPd 租约文件的正确方法是什么?

备份 ISC DHCPd 租约文件的正确方法是什么?

根据这个答案,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_backupshell 检查这是否是预期的文件名:

#!/bin/sh

if [ "$1" = dhcpd.leases~ ]; then
    do_backup /var/lib/dhcpd/dhcpd.leases~
fi

相关内容