Skip to content

Commit cdd7bc1

Browse files
committed
fix(dnsmasq): make --conf-poll actually wake the loop periodically
poll_dynamic_dirs() was only ever invoked opportunistically, whenever something else (a DNS/DHCP packet, an inotify event, a signal) already woke up dnsmasq's main loop. With no such activity, the loop's do_poll() blocks indefinitely, so on a quiet dnsmasq instance the poller never actually ran on its own, no matter how long --conf-poll-interval was set to. conf-poll.patch now also clamps the loop's wait timeout to --conf-poll-interval when --conf-poll is set, the same way TFTP/DBus/ DAD already force more frequent wake-ups. Reproduced against a live pod (dhcp-hostsdir file created from a different host, dnsmasq never picked it up despite --conf-poll being set) and verified the fix by running dnsmasq with --conf-poll, no upstream DNS servers and no DHCP traffic (so nothing else would ever wake the loop), then confirming a new dhcp-hostsdir file is picked up within ~1s with zero other interaction with the process.
1 parent f62f217 commit cdd7bc1

1 file changed

Lines changed: 27 additions & 2 deletions

File tree

containers/dnsmasq/dnsmasq/conf-poll.patch

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ SIGHUP or restart. --conf-poll (with --conf-poll-interval, default 1s)
77
adds an opt-in stat-based poll of these directories, running alongside
88
inotify and reusing the same reload path.
99

10+
Also forces the main loop to wake up at least once every
11+
--conf-poll-interval seconds when --conf-poll is set (the same way
12+
TFTP/DBus/DAD already force more frequent wake-ups): without any other
13+
DNS/DHCP/inotify activity, the loop's do_poll() would otherwise block
14+
indefinitely and the poller would never actually run, no matter how
15+
long the process had been up.
16+
1017
Rebased against dnsmasq 2.93 (as packaged in Debian forky).
1118
---
1219
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
@@ -54,7 +61,7 @@ index 099c65f..ea835bb 100644
5461
.B --dhcp-optsdir=<path>
5562
This is equivalent to \fB--dhcp-optsfile\fP, with the differences noted for \fB--dhcp-hostsdir\fP.
5663
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
57-
index adaa692..f9be116 100644
64+
index adaa692..4bf4d2c 100644
5865
--- a/src/dnsmasq.c
5966
+++ b/src/dnsmasq.c
6067
@@ -184,8 +184,11 @@ int main (int argc, char **argv)
@@ -70,7 +77,25 @@ index adaa692..f9be116 100644
7077
if (option_bool(OPT_DNSSEC_VALID))
7178
{
7279
#ifdef HAVE_DNSSEC
73-
@@ -1248,7 +1251,19 @@ int main (int argc, char **argv)
80+
@@ -1117,7 +1120,16 @@ int main (int argc, char **argv)
81+
else if (is_dad_listeners() &&
82+
(timeout == -1 || timeout > 1000))
83+
timeout = 1000;
84+
-
85+
+
86+
+ /* --conf-poll: with nothing else to wake the loop (no DNS/DHCP traffic,
87+
+ no inotify event), do_poll() below would otherwise block indefinitely
88+
+ and poll_dynamic_dirs(), below, would never get a chance to run. Force
89+
+ a periodic wake-up so it's actually polled every conf_poll_interval
90+
+ seconds, not just opportunistically when something else wakes us. */
91+
+ if (option_bool(OPT_CONF_POLL) &&
92+
+ (timeout == -1 || timeout > daemon->conf_poll_interval * 1000))
93+
+ timeout = daemon->conf_poll_interval * 1000;
94+
+
95+
if (daemon->port != 0)
96+
set_dns_listeners();
97+
98+
@@ -1248,7 +1260,19 @@ int main (int argc, char **argv)
7499
{
75100
if (daemon->port != 0 && !option_bool(OPT_NO_POLL))
76101
poll_resolv(1, 1, now);

0 commit comments

Comments
 (0)