Firewalld 报告 ‘python-nftables’ failed 的调试思路

刚刚把软路由从 Ubuntu 20.04 升级到 21.10,升级的时候告诉我会把 FirewallBackendiptables 改成 nftables。我正好想试一试,就让他改了。

结果重启之后 firewall-cmd --reload 会报错

上面的JSON 内容已经给出了出错的 nftables 操作列表,firewalld 在操纵 nftables 的时候,会将多个请求合并为一个发给 nftables,导致并不能知道上面哪一条出了问题。看到bugzilla相关的讨论,可以让firewalld 拆分请求。

https://bugzilla.redhat.com/show_bug.cgi?id=1869451#c6

set IndividualCalls=yes in /etc/firewalld/firewalld.conf. This will give a better indication of what rule fails to apply to nftables.

修复了一些我自己范的简单错误后,神奇的事情发生了,如果 IndividualCalls=no ,那么问题直接消失, reload 的时候直接success 了。经过分析发现,问题还是出在 firewalld 批量操作 nftables 上。

我的推测是:如果一批操作中任何一个指令失败,这批操作就会被回滚。那么如果这批操作中有新建 Chain 之类的操作,就会导致 Chain 没有被创建,然后后面就会出各种莫名其妙的问题,我们看到的错误并非根本原因。

我这个问题的最终原因是 ipset 中 条目有overlap.删除 ipset 并导入正确的ipset之后问题解决。

调试思路

本质上,firewalld 启动的时候是不应该有任何错误才对。那么我们可以在/etc/firewalld/firewalld.conf设置IndividualCalls=yes,然后重启firewalld。

请注意:在这种情况下,ipset 也会一条一条的插入,如果你有上万个IP,那么这个插入速度也会非常慢。导致你可能会觉得 firewalld 根本启动不起来。那你也可以选择不设置IndividualCalls,或者选择清空ipset以提升启动速度。

重启之后可以看看最新一次启动日志,第一个 python-nftables 相关错误是什么。如果你设置了IndividualCalls=yes,那么此时请按从早到晚的顺序依次排查错误并解决。如果你选择保持IndividualCalls=no,也需要查看第一个错误是什么,把 JSON blob:后面那一段Json 保存下来。

我这里提供一个小工具,能把一批操作拆解成一个个操作,然后执行nftables。

将刚才的 JSON 保存到 /tmp/failed-nft.json ,然后执行

就会把失败的指令和错误单独输出出来,方便调试。

NRF51822+MPU6050 蓝牙加速度传感器的功耗控制

上个月(Jul 2019)在公司做一个 Hackathon 项目,想的是给 PC 的屏幕加上重力感应旋转,就和手机平板一样,选择了低功耗蓝牙(BLE)获取加速度信息(可推出重力方向)。在 Windows 上写了后台程序https://github.com/hcwg/ScreenFerris,跑的很成功。演示给整个公司的同事看反响也可以。但是有一个严重的问题,就是一节 CR2032 纽扣电池只能支撑5天左右。续航严重不足。

我用的传感器是淘宝购买的,NRF51822 主控 + MPU6050 加速度计和陀螺仪,还有我用不到的环境光传感器和温度传感器。生产商是讯联电子(infor-link),产品名是 NRF51 Sensor Tag,此为硬件背景。

我显然知道现在低功耗蓝牙有多厉害,大部分设备都能用一节 CR2032 电池续航一年,显然是厂商附带的程序和我的需求不契合,导致续航不够长。于是我决定自己写一下代码,反正 ARM 的程序也不是第一次写,能有多难?在苏州用掉了两周的晚上大概搞出来了,现在续航还在测试,不过看起来电压都不怎么下降的样子。

硬件圈子分享的气氛不太浓,我就大概写下自己的心得,希望能帮助到别人。

Continue reading “NRF51822+MPU6050 蓝牙加速度传感器的功耗控制”

USB低功耗蓝牙(BLE)适配器选购

最近要做一个使用低功耗蓝牙 (Bluetooth LE, BLE) 的项目。大部分笔记本都自带蓝牙,而且蓝牙版本很高,都到5.0了。手机更是不用说,13年以来的手机大部分都支持BLE。奈何大部分台式机都没有蓝牙适配器,必须买一个USB的适配器。

很可惜,去京东上搜索蓝牙适配器,绝大部分都是 4.0 的,而且也不标注是否支持BLE,只能自己找了。

Continue reading “USB低功耗蓝牙(BLE)适配器选购”

解决Driver/library version mismatch

服务器更新nvidia driver 版本之后,经常会出现

这个问题出现的原因是kernel mod 的 Nvidia driver 的版本没有更新,一般情况下,重启机器就能够解决,如果因为某些原因不能够重启的话,也有办法reload kernel mod。

简单来看,就两步

  1. unload nvidia kernel mod
  2. reload nvidia kernel mod

执行起来就是

  1. sudo rmmod nvidia
  2. sudo nvidia-smi

nvidia-smi 发现没有 kernel mod 会将其自动装载。

但是事情远远不是这么简单,一般情况下都会遇到卸载失败。

这时,就要一点一点的卸载整个驱动了,首先要知道现在kernel mod 的依赖情况,首先我们从错误信息中知道,nvidia_modeset nvidia_uvm 这两个 mod 依赖于 nvidia, 所以要先卸载他们

可以看到 nvidia 被使用了152词,我们可以先卸载 nvidia_uvm 和 nvidia_modeset

先查看下有哪些进程使用了 nvidia*

这些进程有个了解,如果一会卸载失败,记得关闭相关进程。

卸载

再 lsof 一遍,如果 nvidia 的使用 Used by 还没有降到 0,kill 相关进程

最后

收工

CheckAC 在Chrome WebStore 上架

2013年暑假集训,我们(@yangz @alwa)发现了一个小众的需求,即在OJ上做题的时候不能确定一道题自己有没有过掉,尤其是在查看别人的提交记录的时候。

下载地址:CheckAC

Github(欢迎提交意见,代码更好):CheckAC

还有,不知道为什么,我们的集训队一直比较关心一个人的过题数量,于是乎我们都在乎了。

(说来惭愧,暑假之后几乎没怎么搞算法,全都是搞应用了,最近虽然考试多,还是要多刷刷题了,太少了看不过去)

于是,我们就决定开发一款Chrome 的扩展程序(插件),能辅助我们在OJ上做题,想法很好,说干就干。

开发速度简直快的惊人(凭记忆):

2013-7-19 14:00 ~ 2013-7-21  2:40 :

36小时速成0.1版,可惜当时还不会用Github ,没有记录下开发过程

Continue reading “CheckAC 在Chrome WebStore 上架”

等比数列求和的二分法

常见问题:给定整数M,等比数列\(\{{a_n}\}\),求其前n项和对M的模

朴素的想法,我们可以用等比数列求和公式\(S_n=\frac {a_1(1-q^n)}{1-q}\)求得和再模除M,但是计算过程中取模导致分母下面的1-q不能直接除,要求1-q的乘法逆元;

这里介绍另一种思路,就是使用二分的思想,很像矩阵快速幂
首先,我们先讨论一个简单的问题:
求\(a^1+a^2+a^3+a^4+a^5+a^6+a^7+a^8\)的和
提取公因式,我们能把原式变为
\((a^1+a^2+a^3+a^4)(1+a^4)\)
进一步变换为\((a^1+a^2)(1+a^2)(1+a^4)\)
\(=a(a+a^1)(1+a^2)(1+a^4)\)
我们把这种等比数列前\(2^k\)项和记为\(S(k)\)有递推式\(S(k)=S(k-1)(1+a^{2^{k-1}})\)
这是二分法的关键,也就是说我们能在log(n)的时间内求出等比数列前\(2^k\)项的和

当我们要求的不是前2的整数次幂的时候,我们将n分解为2的整次幂的和:
比如求前等比数列11项的和,我们将11(二进制表示:1011)分解为1+2+8(二进制表示1+10+1000)
前11项的和可以表示为:
\((a^1)+(a^2+a^3)+(a^4+a^5+a^6+a^7+a^8+a^9+a^{10}+a^{11})\)
可进一步表示为
\(a^0(a^1)+a^1(a^1+a^2)+a^3(a^1+a^2+a^3+a^4+a^5+a^6+a^7+a^8)\)
即:\(a^0S(0)+a^1S(1)+a^3S(3)\)
Well done!我们又把原式分解成了多个\(a^xS(y)\)的和
Continue reading “等比数列求和的二分法”