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