Blame SOURCES/ebtables-2.0.10-flock.patch

6e3d83
From 03df255180677b86eb058866be668063fcc6f598 Mon Sep 17 00:00:00 2001
6e3d83
From: Phil Sutter <phil@nwl.cc>
6e3d83
Date: Fri, 6 Oct 2017 12:48:50 +0200
6e3d83
Subject: [PATCH] Use flock() for --concurrent option
6e3d83
6e3d83
The previous locking mechanism was not atomic, hence it was possible
6e3d83
that a killed ebtables process would leave the lock file in place which
6e3d83
in turn made future ebtables processes wait indefinitely for the lock to
6e3d83
become free.
6e3d83
6e3d83
Fix this by using flock(). This also simplifies code quite a bit because
6e3d83
there is no need for a custom signal handler or an __exit routine
6e3d83
anymore.
6e3d83
6e3d83
Signed-off-by: Phil Sutter <phil@nwl.cc>
6e3d83
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
6e3d83
Signed-off-by: Phil Sutter <psutter@redhat.com>
6e3d83
---
6e3d83
 ebtables.c |  8 --------
6e3d83
 libebtc.c  | 49 +++++--------------------------------------------
6e3d83
 2 files changed, 5 insertions(+), 52 deletions(-)
6e3d83
6e3d83
diff --git a/ebtables.c b/ebtables.c
6e3d83
index 62f1ba80063d8..f7dfccf4b2f31 100644
6e3d83
--- a/ebtables.c
6e3d83
+++ b/ebtables.c
6e3d83
@@ -528,12 +528,6 @@ void ebt_early_init_once()
6e3d83
 	ebt_iterate_targets(merge_target);
6e3d83
 }
6e3d83
 
6e3d83
-/* signal handler, installed when the option --concurrent is specified. */
6e3d83
-static void sighandler(int signum)
6e3d83
-{
6e3d83
-	exit(-1);
6e3d83
-}
6e3d83
-
6e3d83
 /* We use exec_style instead of #ifdef's because ebtables.so is a shared object. */
6e3d83
 int do_command(int argc, char *argv[], int exec_style,
6e3d83
                struct ebt_u_replace *replace_)
6e3d83
@@ -1047,8 +1041,6 @@ big_iface_length:
6e3d83
 			strcpy(replace->filename, optarg);
6e3d83
 			break;
6e3d83
 		case 13 : /* concurrent */
6e3d83
-			signal(SIGINT, sighandler);
6e3d83
-			signal(SIGTERM, sighandler);
6e3d83
 			use_lockfd = 1;
6e3d83
 			break;
6e3d83
 		case 1 :
6e3d83
diff --git a/libebtc.c b/libebtc.c
6e3d83
index b0814213b6b06..ab3429577a1f1 100644
6e3d83
--- a/libebtc.c
6e3d83
+++ b/libebtc.c
6e3d83
@@ -31,6 +31,7 @@
6e3d83
 #include "include/ethernetdb.h"
6e3d83
 #include <unistd.h>
6e3d83
 #include <fcntl.h>
6e3d83
+#include <sys/file.h>
6e3d83
 #include <sys/wait.h>
6e3d83
 #include <sys/stat.h>
6e3d83
 #include <sys/types.h>
6e3d83
@@ -137,58 +138,18 @@ void ebt_list_extensions()
6e3d83
 #define LOCKDIR "/run"
6e3d83
 #define LOCKFILE LOCKDIR"/ebtables.lock"
6e3d83
 #endif
6e3d83
-static int lockfd = -1, locked;
6e3d83
 int use_lockfd;
6e3d83
 /* Returns 0 on success, -1 when the file is locked by another process
6e3d83
  * or -2 on any other error. */
6e3d83
 static int lock_file()
6e3d83
 {
6e3d83
-	int try = 0;
6e3d83
-	int ret = 0;
6e3d83
-	sigset_t sigset;
6e3d83
-
6e3d83
-tryagain:
6e3d83
-	/* the SIGINT handler will call unlock_file. To make sure the state
6e3d83
-	 * of the variable locked is correct, we need to temporarily mask the
6e3d83
-	 * SIGINT interrupt. */
6e3d83
-	sigemptyset(&sigset);
6e3d83
-	sigaddset(&sigset, SIGINT);
6e3d83
-	sigprocmask(SIG_BLOCK, &sigset, NULL);
6e3d83
-	lockfd = open(LOCKFILE, O_CREAT | O_EXCL | O_WRONLY, 00600);
6e3d83
-	if (lockfd < 0) {
6e3d83
-		if (errno == EEXIST)
6e3d83
-			ret = -1;
6e3d83
-		else if (try == 1)
6e3d83
-			ret = -2;
6e3d83
-		else {
6e3d83
-			if (mkdir(LOCKDIR, 00700))
6e3d83
-				ret = -2;
6e3d83
-			else {
6e3d83
-				try = 1;
6e3d83
-				goto tryagain;
6e3d83
-			}
6e3d83
-		}
6e3d83
-	} else {
6e3d83
-		close(lockfd);
6e3d83
-		locked = 1;
6e3d83
-	}
6e3d83
-	sigprocmask(SIG_UNBLOCK, &sigset, NULL);
6e3d83
-	return ret;
6e3d83
-}
6e3d83
+	int fd = open(LOCKFILE, O_CREAT, 00600);
6e3d83
 
6e3d83
-void unlock_file()
6e3d83
-{
6e3d83
-	if (locked) {
6e3d83
-		remove(LOCKFILE);
6e3d83
-		locked = 0;
6e3d83
-	}
6e3d83
+	if (fd < 0)
6e3d83
+		return -2;
6e3d83
+	return flock(fd, LOCK_EX);
6e3d83
 }
6e3d83
 
6e3d83
-void __attribute__ ((destructor)) onexit()
6e3d83
-{
6e3d83
-	if (use_lockfd)
6e3d83
-		unlock_file();
6e3d83
-}
6e3d83
 /* Get the table from the kernel or from a binary file
6e3d83
  * init: 1 = ask the kernel for the initial contents of a table, i.e. the
6e3d83
  *           way it looks when the table is insmod'ed
6e3d83
-- 
6e3d83
2.13.1
6e3d83