linux提示Another app is currently holding the xtables lock. Perhaps you want to use the -w option?
Posted 格格巫 MMQ!!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux提示Another app is currently holding the xtables lock. Perhaps you want to use the -w option?相关的知识,希望对你有一定的参考价值。
多年来,我一直在使用bash shell脚本来设置复杂的iptables规则。但是,Debian Stretch当我尝试使用脚本时,它变得缓慢并且使iptables处于不良状态。
当我尝试执行操作时,iptables -L -v它返回了一个错误…
Another app is currently holding the xtables lock; still -9s 0us time ahead to have a chance to grab the lock…
Googleing使我发现了此错误,该错误建议使用“ -w”开关。手册页并没有真正弄清楚此开关如何影响问题。
我的脚本使用循环为管理员提供便利,这导致它对iptables进行了大量调用。
This actually sets the allowed incoming iptables lines
setincoming()
for port in $2; do
for ip in
1
;
d
o
i
f
[
‘
e
c
h
o
"
1; do if [ `echo "
1;doif[‘echo"ip" | grep -P “(^|\\s)[0-9]1,3.[0-9]1,3.[0-9]1,3.[0-9]1,3(/[0-9])(\\s*)$”` ]; then
iptables -I INPUT -p tcp -s $ip --dport $port -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
else
ip6tables -I INPUT -p tcp -s $ip --dport $port -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
fi
done
done
APIs
setincoming “123.123.123.10 123.123.123.11 fe80::xxxx:xxx:xxxx:xxxx” “4200 4300”
解决方案:
该-w选项只是使iptables等待xtables锁定,而不是在最初获取它时失败而退出。该选项可以解决多个进程竞争获取和释放xtables锁的竞争条件。如果另一个进程没有释放该锁,或者有太多进程在争夺该锁,则此选项可能无济于事。
如Tomek的建议,我将修改你的脚本以利用ipset。由于它依赖于哈希表,而不是顺序地通过iptables规则,因此它肯定会得到更好的优化。它也可能会解决你的锁定问题。类似于以下内容:
Create ipset and connect it with iptables
ipset create foo hash:ip,port
iptables -I INPUT -m set --match-set foo src -j ACCEPT
Add allowances as needed
ipset add foo 123.123.123.10,4200
ipset add foo 123.123.123.11,tcp:4300 # Specify protocol
ipset add foo 123.123.123.12,4400 timeout 600 # Set a timeout for this to disappear
ipset add foo 123.123.123.13,4500 -exist # Do not error if this already exists
由于示例中同时包含了IPv4和IPv6,因此我还将提到family在创建ipset时可以使用该参数来特别支持IPv6。
查看虚拟机里面的iptables版本为1.4.21, 板子里面的iptables版本为1.4.4,然后下载了1.4.21的源码下来
1.4.21的锁机制
通过创建unix域套接字然后bind来实现,但是我本地测试这段代码却有问题。原因在于:域套接字在进程退出后不会销毁该套接字对应的文件,下次bind就会失败,如果调用unlink来处理,套接字文件又会里面被清掉,bind总是成功,无法起到锁的作用。(所以这里不懂1.4.21这一版的原理究竟是啥)
想来想去,没什么好办法,又下载了最新的iptables源码
1.6.1的锁机制
通过flock实现。查了下flock,发现这就是我需要的。flock锁的销毁会随着文件描述符销毁而销毁,所以即便进程意外退出了,也不用担心会有锁残留的问题。于是可以写出iptables应用层加锁的代码来:
void xtables_try_lock(void)
int fd;
int i = 0;
int sleep_time_ms = 50;
int wait_time_sec = 10;
int wait_cnt = wait_time_sec*1000 / sleep_time_ms;
fd = open(XT_LOCK_NAME, O_CREAT, 0600);
if (fd < 0)
return;
for(i = 0; i < wait_cnt; i++)
if(!flock(fd, LOCK_EX | LOCK_NB))
return;
usleep(sleep_time_ms * 1000);
printf("## BUG! Another app is currently holding the xtables lock long time!\\n");
return;
把这个锁放在iptables就ok了。
以上是关于linux提示Another app is currently holding the xtables lock. Perhaps you want to use the -w option?的主要内容,如果未能解决你的问题,请参考以下文章