From aaa4ace72ba1d195bbf436134a336816c33f7bd0 Mon Sep 17 00:00:00 2001 From: Jiri Popelka Date: Fri, 4 Jul 2014 15:50:41 +0200 Subject: iptables: add optional [seconds] argument to -w This patch adds an optional numeric argument to -w option (added with 93587a0) so one can specify how long to wait for an exclusive lock. If the value isn't specified it works as before, i.e. program waits indefinitely. If user specifies it, program exits after the given time interval passes. This patch also adds the -w/--wait to nftables compat code, so the parser doesn't complain. [ In the original patch, iptables-compat -w X was not working, I have fixed by adding the dummy code not to break scripts using the new optional argument --pablo ] Signed-off-by: Jiri Popelka Signed-off-by: Pablo Neira Ayuso --- iptables/xshared.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'iptables/xshared.c') diff --git a/iptables/xshared.c b/iptables/xshared.c index 6c9992ed..b18022ee 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -243,10 +243,11 @@ void xs_init_match(struct xtables_match *match) match->init(match->m); } -bool xtables_lock(bool wait) +bool xtables_lock(int wait) { int i = 0, ret, xt_socket; struct sockaddr_un xt_addr; + int waited = 0; memset(&xt_addr, 0, sizeof(xt_addr)); xt_addr.sun_family = AF_UNIX; @@ -261,11 +262,12 @@ bool xtables_lock(bool wait) offsetof(struct sockaddr_un, sun_path)+XT_SOCKET_LEN); if (ret == 0) return true; - else if (wait == false) + else if (wait >= 0 && waited >= wait) return false; if (++i % 2 == 0) fprintf(stderr, "Another app is currently holding the xtables lock; " - "waiting for it to exit...\n"); + "waiting (%ds) for it to exit...\n", waited); + waited++; sleep(1); } } -- cgit v1.2.3 From aa562a660d1555b13cffbac1e744033e91f82707 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 16 Jan 2015 14:21:57 +0100 Subject: iptables: use flock() instead of abstract unix sockets Abstract unix sockets cannot be used to synchronize several concurrent instances of iptables since an unpriviledged process can create them and prevent the legitimate iptables instance from running. Use flock() and /run instead as suggested by Lennart Poettering. Fixes: 93587a0 ("ip[6]tables: Add locking to prevent concurrent instances") Reported-by: Lennart Poettering Cc: Phil Oester Signed-off-by: Pablo Neira Ayuso --- iptables/xshared.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'iptables/xshared.c') diff --git a/iptables/xshared.c b/iptables/xshared.c index b18022ee..7beb86b4 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -9,11 +9,11 @@ #include #include #include +#include #include #include "xshared.h" -#define XT_SOCKET_NAME "xtables" -#define XT_SOCKET_LEN 8 +#define XT_LOCK_NAME "/run/xtables.lock" /* * Print out any special helps. A user might like to be able to add a --help @@ -245,22 +245,14 @@ void xs_init_match(struct xtables_match *match) bool xtables_lock(int wait) { - int i = 0, ret, xt_socket; - struct sockaddr_un xt_addr; - int waited = 0; - - memset(&xt_addr, 0, sizeof(xt_addr)); - xt_addr.sun_family = AF_UNIX; - strcpy(xt_addr.sun_path+1, XT_SOCKET_NAME); - xt_socket = socket(AF_UNIX, SOCK_STREAM, 0); - /* If we can't even create a socket, fall back to prior (lockless) behavior */ - if (xt_socket < 0) + int fd, waited = 0, i = 0; + + fd = open(XT_LOCK_NAME, O_CREAT, 0600); + if (fd < 0) return true; while (1) { - ret = bind(xt_socket, (struct sockaddr*)&xt_addr, - offsetof(struct sockaddr_un, sun_path)+XT_SOCKET_LEN); - if (ret == 0) + if (flock(fd, LOCK_EX | LOCK_NB) == 0) return true; else if (wait >= 0 && waited >= wait) return false; -- cgit v1.2.3 From 6dc53c514f1e4683e51a877b3a2f3128cfccef28 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 16 Feb 2015 16:57:39 +0100 Subject: xshared: calm down compilation warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xshared.c: In function ‘xtables_lock’: xshared.c:255:3: warning: implicit declaration of function ‘flock’ [-Wimplicit-function-declaration] Signed-off-by: Pablo Neira Ayuso --- iptables/xshared.c | 1 + 1 file changed, 1 insertion(+) (limited to 'iptables/xshared.c') diff --git a/iptables/xshared.c b/iptables/xshared.c index 7beb86b4..81c2581f 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From e8f857a5a1514c3e7d0d8ea0f7d2d571f0e37bd1 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Thu, 23 Jun 2016 18:44:06 -0600 Subject: xtables: Add an interval option for xtables lock wait ip[6]tables currently waits for 1 second for the xtables lock to be freed if the -w option is used. We have seen that the lock is held much less than that resulting in unnecessary delay when trying to acquire the lock. This problem is even severe in case of latency sensitive applications. Introduce a new option 'W' to specify the wait interval in microseconds. If this option is not specified, the command sleeps for 1 second by default. v1->v2: Change behavior to take millisecond sleep as an argument to -w as suggested by Pablo. Also maintain current behavior for -w to sleep for 1 second as mentioned by Liping. v2->v3: Move the millisecond behavior to a new option as suggested by Pablo. v3->v4: Use select instead of usleep. Sleep every iteration for the time specified in the "-W" argument. Update man page. v4->v5: Fix compilation error when enabling nftables v5->v6: Simplify -W so it only takes the interval wait in microseconds. Bail out if -W is specific but -w is not. Joint work with Pablo Neira. Signed-off-by: Subash Abhinov Kasiviswanathan Signed-off-by: Pablo Neira Ayuso --- iptables/xshared.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 8 deletions(-) (limited to 'iptables/xshared.c') diff --git a/iptables/xshared.c b/iptables/xshared.c index 81c2581f..cccb8aec 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -9,12 +9,15 @@ #include #include #include +#include #include #include #include +#include #include "xshared.h" #define XT_LOCK_NAME "/run/xtables.lock" +#define BASE_MICROSECONDS 100000 /* * Print out any special helps. A user might like to be able to add a --help @@ -244,9 +247,15 @@ void xs_init_match(struct xtables_match *match) match->init(match->m); } -bool xtables_lock(int wait) +bool xtables_lock(int wait, struct timeval *wait_interval) { - int fd, waited = 0, i = 0; + struct timeval time_left, wait_time, waited_time; + int fd, i = 0; + + time_left.tv_sec = wait; + time_left.tv_usec = 0; + waited_time.tv_sec = 0; + waited_time.tv_usec = 0; fd = open(XT_LOCK_NAME, O_CREAT, 0600); if (fd < 0) @@ -255,12 +264,43 @@ bool xtables_lock(int wait) while (1) { if (flock(fd, LOCK_EX | LOCK_NB) == 0) return true; - else if (wait >= 0 && waited >= wait) + if (++i % 10 == 0) { + if (wait != -1) + fprintf(stderr, "Another app is currently holding the xtables lock; " + "still %lds %ldus time ahead to have a chance to grab the lock...\n", + time_left.tv_sec, time_left.tv_usec); + else + fprintf(stderr, "Another app is currently holding the xtables lock; " + "waiting for it to exit...\n"); + } + + wait_time = *wait_interval; + select(0, NULL, NULL, NULL, &wait_time); + if (wait == -1) + continue; + + timeradd(&waited_time, wait_interval, &waited_time); + timersub(&time_left, wait_interval, &time_left); + if (!timerisset(&time_left)) return false; - if (++i % 2 == 0) - fprintf(stderr, "Another app is currently holding the xtables lock; " - "waiting (%ds) for it to exit...\n", waited); - waited++; - sleep(1); } } + +void parse_wait_interval(const char *str, struct timeval *wait_interval) +{ + unsigned int usec; + int ret; + + ret = sscanf(str, "%u", &usec); + if (ret == 1) { + if (usec > 999999) + xtables_error(PARAMETER_PROBLEM, + "too long usec wait %u > 999999 usec", + usec); + + wait_interval->tv_sec = 0; + wait_interval->tv_usec = usec; + return; + } + xtables_error(PARAMETER_PROBLEM, "wait interval not numeric"); +} -- cgit v1.2.3 From f9da6abd2eb2ee4d3e20ea49e8d6707c32da32b6 Mon Sep 17 00:00:00 2001 From: Liping Zhang Date: Sun, 5 Feb 2017 21:57:34 +0800 Subject: xshared: do not lock again and again if "-w" option is not specified After running the following commands, some confusing messages was printed out: # while : ; do iptables -A INPUT & iptables -D INPUT & done [...] Another app is currently holding the xtables lock; still -9s 0us time ahead to have a chance to grab the lock... Another app is currently holding the xtables lock; still -29s 0us time ahead to have a chance to grab the lock... If "-w" option is not specified, the "wait" will be zero, so we should check whether the timer_left is less than wait_interval before we call select to sleep. Also remove unused "BASE_MICROSECONDS" and "struct timeval waited_time" introduced by commit e8f857a5a151 ("xtables: Add an interval option for xtables lock wait"). Fixes: e8f857a5a151 ("xtables: Add an interval option for xtables lock wait") Signed-off-by: Liping Zhang Signed-off-by: Pablo Neira Ayuso (cherry picked from commit 24f8174646123c2833bc87967b366796231b04e0) Bug: 36108349 Test: see top of change stack. Change-Id: I54da3f5b1390f4e4cc20523575925aa2a428f39b --- iptables/xshared.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'iptables/xshared.c') diff --git a/iptables/xshared.c b/iptables/xshared.c index cccb8aec..055acf20 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -17,7 +17,6 @@ #include "xshared.h" #define XT_LOCK_NAME "/run/xtables.lock" -#define BASE_MICROSECONDS 100000 /* * Print out any special helps. A user might like to be able to add a --help @@ -249,13 +248,11 @@ void xs_init_match(struct xtables_match *match) bool xtables_lock(int wait, struct timeval *wait_interval) { - struct timeval time_left, wait_time, waited_time; + struct timeval time_left, wait_time; int fd, i = 0; time_left.tv_sec = wait; time_left.tv_usec = 0; - waited_time.tv_sec = 0; - waited_time.tv_usec = 0; fd = open(XT_LOCK_NAME, O_CREAT, 0600); if (fd < 0) @@ -264,6 +261,9 @@ bool xtables_lock(int wait, struct timeval *wait_interval) while (1) { if (flock(fd, LOCK_EX | LOCK_NB) == 0) return true; + else if (wait >= 0 && timercmp(&time_left, wait_interval, <)) + return false; + if (++i % 10 == 0) { if (wait != -1) fprintf(stderr, "Another app is currently holding the xtables lock; " @@ -279,10 +279,7 @@ bool xtables_lock(int wait, struct timeval *wait_interval) if (wait == -1) continue; - timeradd(&waited_time, wait_interval, &waited_time); timersub(&time_left, wait_interval, &time_left); - if (!timerisset(&time_left)) - return false; } } -- cgit v1.2.3 From e493a2243415f8984c5eed132168d0fcfb4fd522 Mon Sep 17 00:00:00 2001 From: Liping Zhang Date: Mon, 6 Feb 2017 19:47:47 +0800 Subject: xshared: using the blocking file lock request when we wait indefinitely When using "-w" to avoid concurrent instances, we try to do flock() every one second until it success. But one second maybe too long in some situations, and it's hard to select a suitable interval time. So when using "iptables -w" to wait indefinitely, it's better to block until it become success. Now do some performance tests. First, flush all the iptables rules in filter table, and run "iptables -w -S" endlessly: # iptables -F # iptables -X # while : ; do iptables -w -S >&- & done Second, after adding and deleting the iptables rules 100 times, measure the time cost: # time for i in $(seq 100); do iptables -w -A INPUT iptables -w -D INPUT done Before this patch: real 1m15.962s user 0m0.224s sys 0m1.475s Apply this patch: real 0m1.830s user 0m0.168s sys 0m1.130s Signed-off-by: Liping Zhang Signed-off-by: Pablo Neira Ayuso (cherry picked from commit 72bb3dbf0ecdf3ec96aee80e5d152c8be4394da1) Bug: 36108349 Test: see top of change stack. Change-Id: I2a522dc9a9cb5f5b2c5bbf6b40da525bb1c4e90f --- iptables/xshared.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'iptables/xshared.c') diff --git a/iptables/xshared.c b/iptables/xshared.c index 055acf20..f0a5ddd0 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -258,27 +259,29 @@ bool xtables_lock(int wait, struct timeval *wait_interval) if (fd < 0) return true; + if (wait == -1) { + if (flock(fd, LOCK_EX) == 0) + return true; + + fprintf(stderr, "Can't lock %s: %s\n", XT_LOCK_NAME, + strerror(errno)); + return false; + } + while (1) { if (flock(fd, LOCK_EX | LOCK_NB) == 0) return true; - else if (wait >= 0 && timercmp(&time_left, wait_interval, <)) + else if (timercmp(&time_left, wait_interval, <)) return false; if (++i % 10 == 0) { - if (wait != -1) - fprintf(stderr, "Another app is currently holding the xtables lock; " - "still %lds %ldus time ahead to have a chance to grab the lock...\n", - time_left.tv_sec, time_left.tv_usec); - else - fprintf(stderr, "Another app is currently holding the xtables lock; " - "waiting for it to exit...\n"); + fprintf(stderr, "Another app is currently holding the xtables lock; " + "still %lds %ldus time ahead to have a chance to grab the lock...\n", + time_left.tv_sec, time_left.tv_usec); } wait_time = *wait_interval; select(0, NULL, NULL, NULL, &wait_time); - if (wait == -1) - continue; - timersub(&time_left, wait_interval, &time_left); } } -- cgit v1.2.3 From e01761f43e50ee40d7c171ed60901dd5b352df1f Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Tue, 14 Mar 2017 17:55:50 +0900 Subject: iptables: set the path of the lock file via a configure option. Currently the iptables lock is hardcoded as "/run/xtables.lock". Allow users to change this path using the --with-xt-lock-name option to ./configure option. This is useful on systems like Android which do not have /run. Tested on Ubuntu, as follows: 1. By default, the lock is placed in /run/xtables.lock: $ make distclean-recursive && ./autogen.sh && ./configure --disable-nftables --prefix /tmp/iptables && make -j64 && make install && sudo strace -e open,flock /tmp/iptables/sbin/iptables -L foo ... open("/run/xtables.lock", O_RDONLY|O_CREAT, 0600) = 3 flock(3, LOCK_EX|LOCK_NB) = 0 iptables: No chain/target/match by that name. 2. Specifying the lock results in the expected location being used: $ make distclean-recursive && ./autogen.sh && \ ./configure --disable-nftables --prefix /tmp/iptables \ --with-xt-lock-name=/tmp/iptables/run/xtables.lock && make -j64 && make install && sudo strace -e open,flock /tmp/iptables/sbin/iptables -L foo ... open("/tmp/iptables/run/xtables.lock", O_RDONLY|O_CREAT, 0600) = 3 flock(3, LOCK_EX|LOCK_NB) = 0 iptables: No chain/target/match by that name. Signed-off-by: Lorenzo Colitti Signed-off-by: Pablo Neira Ayuso (cherry picked from commit b91af533f4da15854893ba5cc082e1df6bcf9a97) Bug: 36108349 Test: see top of change stack. Change-Id: Ia834d3f3043822031220aeaffc5a75cc48c4fa83 --- iptables/xshared.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'iptables/xshared.c') diff --git a/iptables/xshared.c b/iptables/xshared.c index f0a5ddd0..383ecf2c 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -17,8 +17,6 @@ #include #include "xshared.h" -#define XT_LOCK_NAME "/run/xtables.lock" - /* * Print out any special helps. A user might like to be able to add a --help * to the commandline, and see expected results. So we call help for all -- cgit v1.2.3 From 0e96b2160f961dbbdb4b0803a256c11beec1d264 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 16 Mar 2017 12:54:20 +0900 Subject: iptables: move XT_LOCK_NAME from CFLAGS to config.h. This slightly simplifies configure.ac and results in more correct dependencies. Tested by running ./configure with --with-xt-lock-name and without, and using strace to verify that the right lock is used. $ make distclean-recursive && ./autogen.sh && ./configure --disable-nftables --prefix /tmp/iptables && make -j64 && make install && sudo strace -e open,flock /tmp/iptables/sbin/iptables -L foo ... open("/run/xtables.lock", O_RDONLY|O_CREAT, 0600) = 3 flock(3, LOCK_EX|LOCK_NB) = 0 $ make distclean-recursive && ./autogen.sh && \ ./configure --disable-nftables --prefix /tmp/iptables \ --with-xt-lock-name=/tmp/iptables/run/xtables.lock && make -j64 && make install && sudo strace -e open,flock /tmp/iptables/sbin/iptables -L foo ... open("/tmp/iptables/run/xtables.lock", O_RDONLY|O_CREAT, 0600) = 3 flock(3, LOCK_EX|LOCK_NB) = 0 Signed-off-by: Lorenzo Colitti Signed-off-by: Pablo Neira Ayuso (cherry picked from commit 836846f0d747e1be8e37d2d43b215a68b30ea1a9) Bug: 36108349 Test: see top of change stack. Change-Id: I390ab17eadde6d22fa1ad9ce3a7bf4c6b2fb1b8a --- iptables/xshared.c | 1 + 1 file changed, 1 insertion(+) (limited to 'iptables/xshared.c') diff --git a/iptables/xshared.c b/iptables/xshared.c index 383ecf2c..9b8e856e 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -1,3 +1,4 @@ +#include #include #include #include -- cgit v1.2.3 From 097d6bee9cb25c94e288ad72099c51bab7fe113c Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 16 Mar 2017 16:55:01 +0900 Subject: iptables: remove duplicated argument parsing code 1. Factor out repeated code to a new xs_has_arg function. 2. Add a new parse_wait_time option to parse the value of -w. 3. Make parse_wait_interval take argc and argv so its callers can be simpler. Signed-off-by: Lorenzo Colitti Signed-off-by: Pablo Neira Ayuso (cherry picked from commit 6e2e169eb66b63d2991e1c7ada931e3cdb0ced32) Bug: 36108349 Test: see top of change stack. Change-Id: Iae185e267d90806dac2cbfdad2a066a2929947fc --- iptables/xshared.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'iptables/xshared.c') diff --git a/iptables/xshared.c b/iptables/xshared.c index 9b8e856e..06147d18 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -285,12 +285,36 @@ bool xtables_lock(int wait, struct timeval *wait_interval) } } -void parse_wait_interval(const char *str, struct timeval *wait_interval) +int parse_wait_time(int argc, char *argv[]) { + int wait = -1; + + if (optarg) { + if (sscanf(optarg, "%i", &wait) != 1) + xtables_error(PARAMETER_PROBLEM, + "wait seconds not numeric"); + } else if (xs_has_arg(argc, argv)) + if (sscanf(argv[optind++], "%i", &wait) != 1) + xtables_error(PARAMETER_PROBLEM, + "wait seconds not numeric"); + + return wait; +} + +void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval) +{ + const char *arg; unsigned int usec; int ret; - ret = sscanf(str, "%u", &usec); + if (optarg) + arg = optarg; + else if (xs_has_arg(argc, argv)) + arg = argv[optind++]; + else + return; + + ret = sscanf(arg, "%u", &usec); if (ret == 1) { if (usec > 999999) xtables_error(PARAMETER_PROBLEM, @@ -303,3 +327,10 @@ void parse_wait_interval(const char *str, struct timeval *wait_interval) } xtables_error(PARAMETER_PROBLEM, "wait interval not numeric"); } + +inline bool xs_has_arg(int argc, char *argv[]) +{ + return optind < argc && + argv[optind][0] != '-' && + argv[optind][0] != '!'; +} -- cgit v1.2.3 From 1e95b6c9171061d950d0a76a1f39e1be3db6cb09 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 16 Mar 2017 16:55:02 +0900 Subject: iptables-restore: support acquiring the lock. Currently, ip[6]tables-restore does not perform any locking, so it is not safe to use concurrently with ip[6]tables. This patch makes ip[6]tables-restore wait for the lock if -w was specified. Arguments to -w and -W are supported in the same was as they are in ip[6]tables. The lock is not acquired on startup. Instead, it is acquired when a new table handle is created (on encountering '*') and released when the table is committed (COMMIT). This makes it possible to keep long-running iptables-restore processes in the background (for example, reading commands from a pipe opened by a system management daemon) and simultaneously run iptables commands. If -w is not specified, then the command proceeds without taking the lock. Tested as follows: 1. Run iptables-restore -w, and check that iptables commands work with or without -w. 2. Type "*filter" into the iptables-restore input. Verify that a) ip[6]tables commands without -w fail with "another app is currently holding the xtables lock...". b) ip[6]tables commands with "-w 2" fail after 2 seconds. c) ip[6]tables commands with "-w" hang until "COMMIT" is typed into the iptables-restore window. 3. With the lock held by an ip6tables-restore process: strace -e flock /tmp/iptables/sbin/iptables-restore -w 1 -W 100000 shows 11 calls to flock and fails. 4. Run an iptables-restore with -w and one without -w, and check: a) Type "*filter" in the first and then the second, and the second exits with an error. b) Type "*filter" in the second and "*filter" "-S" "COMMIT" into the first. The rules are listed only when the first copy sees "COMMIT". Signed-off-by: Narayan Kamath Signed-off-by: Lorenzo Colitti Signed-off-by: Pablo Neira Ayuso (cherry picked from commit 999eaa241212d3952ddff39a99d0d55a74e3639e) Bug: 36108349 Test: see top of change stack. Change-Id: I2a51fab1c169763db00124641459dde2ed6c4c97 --- iptables/xshared.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'iptables/xshared.c') diff --git a/iptables/xshared.c b/iptables/xshared.c index 06147d18..3fbe3b1a 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -246,7 +246,7 @@ void xs_init_match(struct xtables_match *match) match->init(match->m); } -bool xtables_lock(int wait, struct timeval *wait_interval) +int xtables_lock(int wait, struct timeval *wait_interval) { struct timeval time_left, wait_time; int fd, i = 0; @@ -256,22 +256,22 @@ bool xtables_lock(int wait, struct timeval *wait_interval) fd = open(XT_LOCK_NAME, O_CREAT, 0600); if (fd < 0) - return true; + return XT_LOCK_UNSUPPORTED; if (wait == -1) { if (flock(fd, LOCK_EX) == 0) - return true; + return fd; fprintf(stderr, "Can't lock %s: %s\n", XT_LOCK_NAME, strerror(errno)); - return false; + return XT_LOCK_BUSY; } while (1) { if (flock(fd, LOCK_EX | LOCK_NB) == 0) - return true; + return fd; else if (timercmp(&time_left, wait_interval, <)) - return false; + return XT_LOCK_BUSY; if (++i % 10 == 0) { fprintf(stderr, "Another app is currently holding the xtables lock; " @@ -285,6 +285,12 @@ bool xtables_lock(int wait, struct timeval *wait_interval) } } +void xtables_unlock(int lock) +{ + if (lock >= 0) + close(lock); +} + int parse_wait_time(int argc, char *argv[]) { int wait = -1; -- cgit v1.2.3