Discussion:
Preserving unbound cache across reboots
Maxim Khitrov
2015-01-30 15:22:23 UTC
Permalink
Hi all,

I wrote two simple functions for rc.shutdown and rc.login that
save/restore unbound cache when the system is restarted. Since each
record has a relative TTL field, the cache can only be restored within
a short time window to avoid serving stale data to clients. I set this
window to 10 minutes; enough to survive a reboot, but not for any
extended downtime. Is there any interest in including this
functionality in the base OS (moved to /etc/rc)?

- Max

--- /var/backups/etc_rc.shutdown.current Mon Aug 4 21:03:16 2014
+++ /etc/rc.shutdown Fri Jan 30 10:06:11 2015
@@ -8,3 +8,17 @@
powerdown=NO # set to YES for powerdown

# Add your local shutdown actions here.
+
+save_unbound_cache() {
+ local db=/var/db/unbound.cache
+ /etc/rc.d/unbound check || return
+ echo -n 'saving unbound cache: '
+ if unbound-control dump_cache > $db; then
+ chmod 0600 $db
+ echo 'done.'
+ else
+ rm -f $db
+ fi
+}
+
+save_unbound_cache

--- /var/backups/etc_rc.local.current Mon Aug 4 21:03:16 2014
+++ /etc/rc.local Fri Jan 30 10:07:00 2015
@@ -4,3 +4,17 @@
# can be done AFTER your system goes into securemode. For actions
# which should be done BEFORE your system has gone into securemode
# please see /etc/rc.securelevel.
+
+restore_unbound_cache() {
+ local db=/var/db/unbound.cache
+ test -s $db && /etc/rc.d/unbound check || return
+ echo -n 'restoring unbound cache: '
+ if [ $(($(date '+%s') - $(stat -qf '%m' $db))) -lt 600 ]; then
+ unbound-control load_cache < $db
+ else
+ echo 'failed (cache expired).'
+ fi
+ rm -f $db
+}
+
+restore_unbound_cache
Ingo Schwarze
2015-01-30 17:54:37 UTC
Permalink
Hi,
Post by Maxim Khitrov
I wrote two simple functions for rc.shutdown and rc.login that
save/restore unbound cache when the system is restarted. Since each
record has a relative TTL field, the cache can only be restored within
a short time window to avoid serving stale data to clients. I set this
window to 10 minutes; enough to survive a reboot, but not for any
extended downtime. Is there any interest in including this
functionality in the base OS (moved to /etc/rc)?
The purpose of rebooting is to reset the system to a clean state,
so clearing caches looks like a feature rather than a bug. Given
that even "unbound-control reload" flushes the cache, a reboot
should certainly do that, too. So i wouldn't even recommend showing
this to people as something they might add to their local scripts
if they want to. It just seems wrong.

Also note that the unbound-control(8) manual explicitly marks
load_cache as a debugging feature and warns that it may cause wrong
data to be served. On top of that, the version of unbound(8) running
after the reboot might be newer than the version running before,
so compatibility is questionable as well, so your proposal is very
fragile at best.

Besides, even if the goal would be desirable, which it is not, my
feeling is that this code is too specialized for adding to the boot
scripts.

Yours,
Ingo
Post by Maxim Khitrov
--- /var/backups/etc_rc.shutdown.current Mon Aug 4 21:03:16 2014
+++ /etc/rc.shutdown Fri Jan 30 10:06:11 2015
@@ -8,3 +8,17 @@
powerdown=NO # set to YES for powerdown
# Add your local shutdown actions here.
+
+save_unbound_cache() {
+ local db=/var/db/unbound.cache
+ /etc/rc.d/unbound check || return
+ echo -n 'saving unbound cache: '
+ if unbound-control dump_cache > $db; then
+ chmod 0600 $db
+ echo 'done.'
+ else
+ rm -f $db
+ fi
+}
+
+save_unbound_cache
--- /var/backups/etc_rc.local.current Mon Aug 4 21:03:16 2014
+++ /etc/rc.local Fri Jan 30 10:07:00 2015
@@ -4,3 +4,17 @@
# can be done AFTER your system goes into securemode. For actions
# which should be done BEFORE your system has gone into securemode
# please see /etc/rc.securelevel.
+
+restore_unbound_cache() {
+ local db=/var/db/unbound.cache
+ test -s $db && /etc/rc.d/unbound check || return
+ echo -n 'restoring unbound cache: '
+ if [ $(($(date '+%s') - $(stat -qf '%m' $db))) -lt 600 ]; then
+ unbound-control load_cache < $db
+ else
+ echo 'failed (cache expired).'
+ fi
+ rm -f $db
+}
+
+restore_unbound_cache
Maxim Khitrov
2015-01-30 19:21:11 UTC
Permalink
Post by Ingo Schwarze
Hi,
Post by Maxim Khitrov
I wrote two simple functions for rc.shutdown and rc.login that
save/restore unbound cache when the system is restarted. Since each
record has a relative TTL field, the cache can only be restored within
a short time window to avoid serving stale data to clients. I set this
window to 10 minutes; enough to survive a reboot, but not for any
extended downtime. Is there any interest in including this
functionality in the base OS (moved to /etc/rc)?
The purpose of rebooting is to reset the system to a clean state,
so clearing caches looks like a feature rather than a bug. Given
that even "unbound-control reload" flushes the cache, a reboot
should certainly do that, too. So i wouldn't even recommend showing
this to people as something they might add to their local scripts
if they want to. It just seems wrong.
Also note that the unbound-control(8) manual explicitly marks
load_cache as a debugging feature and warns that it may cause wrong
data to be served. On top of that, the version of unbound(8) running
after the reboot might be newer than the version running before,
so compatibility is questionable as well, so your proposal is very
fragile at best.
Besides, even if the goal would be desirable, which it is not, my
feeling is that this code is too specialized for adding to the boot
scripts.
Fair enough, though I would note that this feature is available in
pfSense, which is also using unbound. Some resolvers persist their
cache to disk automatically, so it's not that strange of an idea. I
wanted to share the code anyway for others who might be interested in
doing the same thing.

My thinking on this is that if the cache was valid before the reboot,
there is no good reason to clear it two minutes later just because the
kernel was upgraded. It creates a traffic spike and a noticeable
performance hit for the clients, especially with DNSSEC enabled. An
explicit "reload" is different because you do it when you change the
unbound configuration. Version upgrades are easily handled and I've
now added that to my scripts, so thanks for the suggestion.

Loading...