Blame SOURCES/iptables-use_the_blocking_file_lock_request.patch

26b15f
commit 72bb3dbf0ecdf3ec96aee80e5d152c8be4394da1
26b15f
Author: Liping Zhang <zlpnobody@gmail.com>
26b15f
Date:   Mon Feb 6 19:47:47 2017 +0800
26b15f
26b15f
    xshared: using the blocking file lock request when we wait indefinitely
26b15f
    
26b15f
    When using "-w" to avoid concurrent instances, we try to do flock() every
26b15f
    one second until it success. But one second maybe too long in some
26b15f
    situations, and it's hard to select a suitable interval time. So when
26b15f
    using "iptables -w" to wait indefinitely, it's better to block until
26b15f
    it become success.
26b15f
    
26b15f
    Now do some performance tests. First, flush all the iptables rules in
26b15f
    filter table, and run "iptables -w -S" endlessly:
26b15f
      # iptables -F
26b15f
      # iptables -X
26b15f
      # while : ; do
26b15f
      iptables -w -S >&- &
26b15f
      done
26b15f
    
26b15f
    Second, after adding and deleting the iptables rules 100 times, measure
26b15f
    the time cost:
26b15f
      # time for i in $(seq 100); do
26b15f
      iptables -w -A INPUT
26b15f
      iptables -w -D INPUT
26b15f
      done
26b15f
    
26b15f
    Before this patch:
26b15f
      real  1m15.962s
26b15f
      user  0m0.224s
26b15f
      sys   0m1.475s
26b15f
    
26b15f
    Apply this patch:
26b15f
      real  0m1.830s
26b15f
      user  0m0.168s
26b15f
      sys   0m1.130s
26b15f
    
26b15f
    Signed-off-by: Liping Zhang <zlpnobody@gmail.com>
26b15f
    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
26b15f
26b15f
diff --git a/iptables/xshared.c b/iptables/xshared.c
26b15f
index 055acf2..f0a5ddd 100644
26b15f
--- a/iptables/xshared.c
26b15f
+++ b/iptables/xshared.c
26b15f
@@ -1,4 +1,5 @@
26b15f
 #include <getopt.h>
26b15f
+#include <errno.h>
26b15f
 #include <libgen.h>
26b15f
 #include <netdb.h>
26b15f
 #include <stdbool.h>
26b15f
@@ -258,27 +259,29 @@ bool xtables_lock(int wait, struct timeval *wait_interval)
26b15f
 	if (fd < 0)
26b15f
 		return true;
26b15f
 
26b15f
+	if (wait == -1) {
26b15f
+		if (flock(fd, LOCK_EX) == 0)
26b15f
+			return true;
26b15f
+
26b15f
+		fprintf(stderr, "Can't lock %s: %s\n", XT_LOCK_NAME,
26b15f
+			strerror(errno));
26b15f
+		return false;
26b15f
+	}
26b15f
+
26b15f
 	while (1) {
26b15f
 		if (flock(fd, LOCK_EX | LOCK_NB) == 0)
26b15f
 			return true;
26b15f
-		else if (wait >= 0 && timercmp(&time_left, wait_interval, <))
26b15f
+		else if (timercmp(&time_left, wait_interval, <))
26b15f
 			return false;
26b15f
 
26b15f
 		if (++i % 10 == 0) {
26b15f
-			if (wait != -1)
26b15f
-				fprintf(stderr, "Another app is currently holding the xtables lock; "
26b15f
-					"still %lds %ldus time ahead to have a chance to grab the lock...\n",
26b15f
-					time_left.tv_sec, time_left.tv_usec);
26b15f
-			else
26b15f
-				fprintf(stderr, "Another app is currently holding the xtables lock; "
26b15f
-						"waiting for it to exit...\n");
26b15f
+			fprintf(stderr, "Another app is currently holding the xtables lock; "
26b15f
+				"still %lds %ldus time ahead to have a chance to grab the lock...\n",
26b15f
+				time_left.tv_sec, time_left.tv_usec);
26b15f
 		}
26b15f
 
26b15f
 		wait_time = *wait_interval;
26b15f
 		select(0, NULL, NULL, NULL, &wait_time);
26b15f
-		if (wait == -1)
26b15f
-			continue;
26b15f
-
26b15f
 		timersub(&time_left, wait_interval, &time_left);
26b15f
 	}
26b15f
 }