From: Phil Oester <kernel@linuxace.com>
To: netfilter-devel@vger.kernel.org
Cc: pablo@netfilter.org, kaber@trash.net
Subject: [PATCH] xtables: Add locking to prevent concurrent instances
Date: Wed, 22 May 2013 13:35:11 -0400 [thread overview]
Message-ID: <20130522173511.GB860@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1615 bytes --]
There have been numerous complaints and bug reports over the years when admins
attempt to run more than one instance of iptables simultaneously. Currently
open bug reports which are related:
325: Parallel execution of the iptables is impossible
758: Retry iptables command on transient failure
764: Doing -Z twice in parallel breaks counters
822: iptables shows negative or other bad packet/byte counts
As Patrick notes in 325: "Since this has been a problem people keep running
into, I'd suggest to simply add some locking to iptables to catch the most
common case."
I started looking into alternatives to add locking, and of course the most
common/obvious solution is to use a pidfile. But this has various downsides,
such as if the application is terminated abnormally and the pidfile isn't
cleaned up. And this also requires a writable filesystem. Using a UNIX domain
socket file (e.g. in /var/run) has similar issues.
Starting in 2.2, Linux added support for abstract sockets. These sockets
require no filesystem, and automatically disappear once the application
terminates. This is the locking solution I chose to implement in xtables-multi.
As an added bonus, since each network namespace has its own socket pool, an
iptables instance running in one namespace will not lock out an iptables
instance running in another namespace. A filesystem approach would have
to recognize and handle multiple network namespaces.
As long as I was adding locking, I also chose to add a retry loop, with 3
attempts made to grab the lock before giving up.
Phil
Signed-off-by: Phil Oester <kernel@linuxace.com>
[-- Attachment #2: patch-xtables-lock --]
[-- Type: text/plain, Size: 1399 bytes --]
diff --git a/iptables/xtables-multi.c b/iptables/xtables-multi.c
index 8014d5f..9c22a82 100644
--- a/iptables/xtables-multi.c
+++ b/iptables/xtables-multi.c
@@ -1,8 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
#include "xshared.h"
+#include "xtables.h"
#include "xtables-multi.h"
#ifdef ENABLE_IPV4
@@ -35,7 +39,31 @@ static const struct subcommand multi_subcommands[] = {
{NULL},
};
+#define XTMSOCKET_NAME "xtables_multi"
+#define XTMSOCKET_LEN 14
+
int main(int argc, char **argv)
{
- return subcmd_main(argc, argv, multi_subcommands);
+ int i = 0, ret, xtm_socket;
+ struct sockaddr_un xtm_addr;
+
+ memset(&xtm_addr, 0, sizeof(xtm_addr));
+ xtm_addr.sun_family = AF_UNIX;
+ strcpy(xtm_addr.sun_path+1, XTMSOCKET_NAME);
+ xtm_socket = socket(AF_UNIX, SOCK_STREAM, 0);
+ /* If we can't even create a socket, just revert to prior (lockless) behavior */
+ if (xtm_socket < 0)
+ return subcmd_main(argc, argv, multi_subcommands);
+
+ do {
+ ret = bind(xtm_socket, (struct sockaddr*)&xtm_addr,
+ offsetof(struct sockaddr_un, sun_path)+XTMSOCKET_LEN);
+ if (ret == 0)
+ return subcmd_main(argc, argv, multi_subcommands);
+ i++;
+ sleep(1);
+ } while (i <= 2);
+
+ fprintf(stderr, "ERROR: unable to obtain lock - another instance is already running\n");
+ exit(RESOURCE_PROBLEM);
}
next reply other threads:[~2013-05-22 17:35 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-22 17:35 Phil Oester [this message]
2013-05-22 19:29 ` [PATCH] xtables: Add locking to prevent concurrent instances Patrick McHardy
2013-05-22 20:04 ` Phil Oester
2013-05-22 20:11 ` Patrick McHardy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130522173511.GB860@gmail.com \
--to=kernel@linuxace.com \
--cc=kaber@trash.net \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.