From efce764f0e60fa9602ac12039371cdad7e3e7237 Mon Sep 17 00:00:00 2001
From: Jo-Philipp Wich <jow@openwrt.org>
Date: Sat, 21 Dec 2013 13:31:28 +0000
Subject: [PATCH] dnsmasq: rework init procedure

	- cache udhcp check results to speed up subsequent reloads
	- enable procd file tracking for /var/etc/dnsmasq.conf to only reload service if needed
	- implement reload action to only restart dnsmasq if /var/etc/dnsmasq.conf actually changed
	- launch dnsmasq from interface hotplug to avoid race conditions with network bringup

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>

SVN-Revision: 39152
---
 package/network/services/dnsmasq/Makefile     |  2 +
 .../services/dnsmasq/files/dnsmasq.hotplug    |  5 ++
 .../services/dnsmasq/files/dnsmasq.init       | 50 +++++++++++++++----
 3 files changed, 46 insertions(+), 11 deletions(-)
 create mode 100644 package/network/services/dnsmasq/files/dnsmasq.hotplug

diff --git a/package/network/services/dnsmasq/Makefile b/package/network/services/dnsmasq/Makefile
index 02712bdc7d..06734651e2 100644
--- a/package/network/services/dnsmasq/Makefile
+++ b/package/network/services/dnsmasq/Makefile
@@ -83,6 +83,8 @@ define Package/dnsmasq/install
 	$(INSTALL_DATA) ./files/dnsmasq.conf $(1)/etc/dnsmasq.conf
 	$(INSTALL_DIR) $(1)/etc/init.d
 	$(INSTALL_BIN) ./files/dnsmasq.init $(1)/etc/init.d/dnsmasq
+	$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
+	$(INSTALL_DATA) ./files/dnsmasq.hotplug $(1)/etc/hotplug.d/iface/25-dnsmasq
 endef
 
 Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install)
diff --git a/package/network/services/dnsmasq/files/dnsmasq.hotplug b/package/network/services/dnsmasq/files/dnsmasq.hotplug
new file mode 100644
index 0000000000..ca5d10c2ed
--- /dev/null
+++ b/package/network/services/dnsmasq/files/dnsmasq.hotplug
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+[ "$ACTION" = ifup ] || exit 0
+
+/etc/init.d/dnsmasq enabled && /etc/init.d/dnsmasq start
diff --git a/package/network/services/dnsmasq/files/dnsmasq.init b/package/network/services/dnsmasq/files/dnsmasq.init
index 045fc7eb4c..0ff987f69c 100644
--- a/package/network/services/dnsmasq/files/dnsmasq.init
+++ b/package/network/services/dnsmasq/files/dnsmasq.init
@@ -33,6 +33,29 @@ dhcp_calc() {
 	echo "$res"
 }
 
+dhcp_check() {
+	local ifname="$1"
+	local stamp="/var/run/dnsmasq.$ifname.dhcp"
+	local rv=0
+
+	[ -s "$stamp" ] && return $(cat "$stamp")
+
+	udhcpc -n -q -s /bin/true -t 1 -i "$ifname" >&- && rv=1 || rv=0
+
+	[ $rv -eq 1 ] && \
+		logger -t dnsmasq \
+			"found already running DHCP-server on interface '$ifname'" \
+			"refusing to start, use 'option force 1' to override"
+
+	echo $rv > "$stamp"
+	return $rv
+}
+
+log_once() {
+	pidof dnsmasq >/dev/null || \
+		logger -t dnsmasq "$@"
+}
+
 append_bool() {
 	local section="$1"
 	local option="$2"
@@ -141,7 +164,7 @@ dnsmasq() {
 	local rebind
 	config_get_bool rebind "$cfg" rebind_protection 1
 	[ $rebind -gt 0 ] && {
-		logger -t dnsmasq \
+		log_once \
 			"DNS rebinding protection is active," \
 			"will discard upstream RFC1918 responses!"
 		xappend "--stop-dns-rebind"
@@ -149,12 +172,12 @@ dnsmasq() {
 		local rebind_localhost
 		config_get_bool rebind_localhost "$cfg" rebind_localhost 0
 		[ $rebind_localhost -gt 0 ] && {
-			logger -t dnsmasq "Allowing 127.0.0.0/8 responses"
+			log_once "Allowing 127.0.0.0/8 responses"
 			xappend "--rebind-localhost-ok"
 		}
 
 		append_rebind_domain() {
-			logger -t dnsmasq "Allowing RFC1918 responses for domain $1"
+			log_once "Allowing RFC1918 responses for domain $1"
 			xappend "--rebind-domain-ok=$1"
 		}
 
@@ -356,14 +379,7 @@ dhcp_add() {
 
 	#check for an already active dhcp server on the interface, unless 'force' is set
 	config_get_bool force "$cfg" force 0
-	[ $force -gt 0 ] || {
-		udhcpc -n -q -s /bin/true -t 1 -i $ifname >&- && {
-			logger -t dnsmasq \
-				"found already running DHCP-server on interface '$ifname'" \
-				"refusing to start, use 'option force 1' to override"
-			return 0
-		}
-	}
+	[ $force -gt 0 ] || dhcp_check "$ifname" || return 0
 
 	config_get start "$cfg" start
 	config_get limit "$cfg" limit
@@ -492,6 +508,11 @@ service_triggers()
 	procd_add_reload_trigger "dhcp"
 }
 
+boot() {
+	# Will be launched through hotplug
+	return 0
+}
+
 start_service() {
 	include /lib/functions
 
@@ -499,6 +520,7 @@ start_service() {
 
 	procd_open_instance
 	procd_set_param command $PROG -C $CONFIGFILE -k
+	procd_set_param file $CONFIGFILE
 	procd_close_instance
 
 	# before we can call xappend
@@ -552,9 +574,15 @@ start_service() {
 	done
 }
 
+reload_service() {
+	rc_procd start_service "$@"
+	return 0
+}
+
 stop_service() {
 	[ -f /tmp/resolv.conf ] && {
 		rm -f /tmp/resolv.conf
 		ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
 	}
+	rm -f /var/run/dnsmasq.*.dhcp
 }
-- 
GitLab