diff options
author | Narayan Kamath <narayan@google.com> | 2017-01-23 17:04:19 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-01-23 17:04:19 +0000 |
commit | 850b49ca1f9c6913a9e8abf17f0b063ef438dc45 (patch) | |
tree | 2867e9a1db9cdefc87350cc09015c00579312118 | |
parent | 199fce01185992c5ec923505836647ee2ca63019 (diff) | |
parent | 7ce69df55d5a599246b39b28188a6f70e4d25f31 (diff) | |
download | iptables-850b49ca1f9c6913a9e8abf17f0b063ef438dc45.tar.gz |
Merge "iptables: Change locking semantics."
am: 7ce69df55d
Change-Id: I6d6398e84499f12408d83aad715ae7d14c53f13e
-rw-r--r-- | iptables/ip6tables-restore.c | 22 | ||||
-rw-r--r-- | iptables/ip6tables.c | 2 | ||||
-rw-r--r-- | iptables/iptables-restore.c | 22 | ||||
-rw-r--r-- | iptables/iptables.c | 2 | ||||
-rw-r--r-- | iptables/xshared.c | 16 | ||||
-rw-r--r-- | iptables/xshared.h | 24 |
6 files changed, 67 insertions, 21 deletions
diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c index e17ad9d2..8d097984 100644 --- a/iptables/ip6tables-restore.c +++ b/iptables/ip6tables-restore.c @@ -185,7 +185,7 @@ int ip6tables_restore_main(int argc, char *argv[]) { struct xtc_handle *handle = NULL; char buffer[10240]; - int c; + int c, lock; char curtable[XT_TABLE_MAXNAMELEN + 1]; FILE *in; int in_table = 0, testing = 0; @@ -193,6 +193,7 @@ int ip6tables_restore_main(int argc, char *argv[]) const struct xtc_ops *ops = &ip6tc_ops; line = 0; + lock = XT_LOCK_NOT_ACQUIRED; ip6tables_globals.program_name = "ip6tables-restore"; c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6); @@ -254,12 +255,6 @@ int ip6tables_restore_main(int argc, char *argv[]) } else in = stdin; - if (!xtables_lock(wait)) { - fprintf(stderr, "Another app is currently holding the xtables lock. " - "Perhaps you want to use the -w option?\n"); - exit(RESOURCE_PROBLEM); - } - /* Grab standard input. */ while (fgets(buffer, sizeof(buffer), in)) { int ret = 0; @@ -283,8 +278,21 @@ int ip6tables_restore_main(int argc, char *argv[]) DEBUGP("Not calling commit, testing\n"); ret = 1; } + + /* Release the lock since we're done with the current table. */ + if (lock >= 0) { + xtables_unlock(lock); + } in_table = 0; } else if ((buffer[0] == '*') && (!in_table)) { + /* Acquire a lock before we create a new table handle */ + lock = xtables_lock(wait); + if (lock == XT_LOCK_BUSY) { + fprintf(stderr, "Another app is currently holding the xtables lock. " + "Perhaps you want to use the -w option?\n"); + exit(RESOURCE_PROBLEM); + } + /* New table */ char *table; diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c index 1fb33f6d..8eefb826 100644 --- a/iptables/ip6tables.c +++ b/iptables/ip6tables.c @@ -1738,7 +1738,7 @@ int do_command6(int argc, char *argv[], char **table, chain, XT_EXTENSION_MAXNAMELEN); /* Attempt to acquire the xtables lock */ - if (!restore && !xtables_lock(wait)) { + if (!restore && (xtables_lock(wait) == XT_LOCK_BUSY)) { fprintf(stderr, "Another app is currently holding the xtables lock. " "Perhaps you want to use the -w option?\n"); xtables_free_opts(1); diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c index 4d49b3c9..a41a46d3 100644 --- a/iptables/iptables-restore.c +++ b/iptables/iptables-restore.c @@ -185,7 +185,7 @@ iptables_restore_main(int argc, char *argv[]) { struct xtc_handle *handle = NULL; char buffer[10240]; - int c; + int c, lock; char curtable[XT_TABLE_MAXNAMELEN + 1]; FILE *in; int in_table = 0, testing = 0; @@ -193,6 +193,7 @@ iptables_restore_main(int argc, char *argv[]) const struct xtc_ops *ops = &iptc_ops; line = 0; + lock = XT_LOCK_NOT_ACQUIRED; iptables_globals.program_name = "iptables-restore"; c = xtables_init_all(&iptables_globals, NFPROTO_IPV4); @@ -254,12 +255,6 @@ iptables_restore_main(int argc, char *argv[]) } else in = stdin; - if (!xtables_lock(wait)) { - fprintf(stderr, "Another app is currently holding the xtables lock. " - "Perhaps you want to use the -w option?\n"); - exit(RESOURCE_PROBLEM); - } - /* Grab standard input. */ while (fgets(buffer, sizeof(buffer), in)) { int ret = 0; @@ -283,8 +278,21 @@ iptables_restore_main(int argc, char *argv[]) DEBUGP("Not calling commit, testing\n"); ret = 1; } + + /* Release the lock since we're done with the current table. */ + if (lock >= 0) { + xtables_unlock(lock); + } in_table = 0; } else if ((buffer[0] == '*') && (!in_table)) { + /* Acquire a lock before we create a new table handle */ + lock = xtables_lock(wait); + if (lock == XT_LOCK_BUSY) { + fprintf(stderr, "Another app is currently holding the xtables lock. " + "Perhaps you want to use the -w option?\n"); + exit(RESOURCE_PROBLEM); + } + /* New table */ char *table; diff --git a/iptables/iptables.c b/iptables/iptables.c index fe18e1cc..1ace4cc3 100644 --- a/iptables/iptables.c +++ b/iptables/iptables.c @@ -1735,7 +1735,7 @@ int do_command4(int argc, char *argv[], char **table, chain, XT_EXTENSION_MAXNAMELEN); /* Attempt to acquire the xtables lock */ - if (!restore && !xtables_lock(wait)) { + if (!restore && (xtables_lock(wait) == XT_LOCK_BUSY)) { fprintf(stderr, "Another app is currently holding the xtables lock. " "Perhaps you want to use the -w option?\n"); xtables_free_opts(1); diff --git a/iptables/xshared.c b/iptables/xshared.c index 6c9992ed..c144b485 100644 --- a/iptables/xshared.c +++ b/iptables/xshared.c @@ -243,7 +243,7 @@ void xs_init_match(struct xtables_match *match) match->init(match->m); } -bool xtables_lock(bool wait) +int xtables_lock(bool wait) { int i = 0, ret, xt_socket; struct sockaddr_un xt_addr; @@ -254,18 +254,26 @@ bool xtables_lock(bool wait) 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) - return true; + return XT_LOCK_UNSUPPORTED; while (1) { ret = bind(xt_socket, (struct sockaddr*)&xt_addr, offsetof(struct sockaddr_un, sun_path)+XT_SOCKET_LEN); if (ret == 0) - return true; + return xt_socket; else if (wait == false) - return false; + return XT_LOCK_BUSY; if (++i % 2 == 0) fprintf(stderr, "Another app is currently holding the xtables lock; " "waiting for it to exit...\n"); sleep(1); } } + +void xtables_unlock(int lock) { + if (lock < 0) { + return; + } + + close(lock); +} diff --git a/iptables/xshared.h b/iptables/xshared.h index 1e2b9b8e..9f9e8031 100644 --- a/iptables/xshared.h +++ b/iptables/xshared.h @@ -84,7 +84,29 @@ extern struct xtables_match *load_proto(struct iptables_command_state *); extern int subcmd_main(int, char **, const struct subcommand *); extern void xs_init_target(struct xtables_target *); extern void xs_init_match(struct xtables_match *); -extern bool xtables_lock(bool wait); + +/** + * Values for the iptables lock. + * + * A value >= 0 indicates the lock filedescriptor. Other values are: + * + * XT_LOCK_UNSUPPORTED : The system does not support locking, execution will + * proceed lockless. + * + * XT_LOCK_BUSY : The lock was held by another process. xtables_lock only + * returns this value when |wait| == false. If |wait| == true, xtables_lock + * will not return unless the lock has been acquired. + * + * XT_LOCK_NOT_ACQUIRED : We have not yet attempted to acquire the lock. + */ +enum { + XT_LOCK_BUSY = -1, + XT_LOCK_UNSUPPORTED = -2, + XT_LOCK_NOT_ACQUIRED = -3, +}; +extern int xtables_lock(bool wait); + +extern void xtables_unlock(int lock); extern const struct xtables_afinfo *afinfo; |