Blame SOURCES/iptables-use_the_blocking_file_lock_request.patch

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