GFW
今天发现VPS(linode) 无法访问,ssh 和 http 同时罢工.
逐步检查问题:
dns 没有问题
ping 不通
traceroute 失败
通过 Ajax Console 可以正常访问。 之前有利用 VPS 通过 ssh 翻墙,但发现 ssh server 使用的端口很快就不能使用; 又换了两个端口利用 ssh 翻墙, 新端口很快就又不能使用了; 早上发现 VPS 完全不能访问,无论是 ssh 还是 http.
网上搜索发现, 早就用同学遇到这种情况了; GFW 可以探测到 走 ssh 的 http, 先封端口,再封IP.
从不传谣, 不信谣的我,真的很愤怒!
伟大的GFW 开发者, 你们真牛!!
方校长, 一路走好!!!
ftok 陷阱
最近手上的项目出现了一个很严重的bug, 系统的message queue 资源被消耗完毕; 在创建 message queue 时提示已超出系统的资源限制(ENOSPC); 通过msgctl 查看系统上的 message queue 数目, 的确超出了系统的 限制(/proc/sys/kernel/msgmni).
System IPC (message queue, share memory 等等) 在创建时, 必须指定一个 KEY 值, 这个 KEY 来自于 ftok.
debug 发现, 调用ftok产生的 KEY, 每次都不一样.
查看fotk的 source code(glibc 2.20)
key_t ftok (const char *pathname, int proj_id) { struct stat64 st; key_t key; if (__xstat64 (_STAT_VER, pathname, &st) < 0) return (key_t) -1; key = ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((proj_id & 0xff) << 24)); return key; }
这样看, KEY 值与文件系统所在的 device id 和 文件节点号 有关, 如果 pathname 没有被删除, 则key值应该维持不变.
最终发现, pathname 在出错处理时被删除, 从而导致 KEY 值不固定.
实验发现, 如果 pathname 位于真实的文件系统, 比如EXT4, 删除后重新创建 pathname , st_ino 和 st_dev 不一定发生变化; 但如果 pathname 位于 ramfs 或者 tmpfs, 删除后重新创建, st_ino 一定会改变. 所以, pathname 所在的文件系统可能会影响 KEY 的产生. (笔者所在的项目中, pathname 位于 ramfs)
另外, 在 glibc 2.20 的 ftok 实现中, 只是使用了inode number 的低 16 位, 如果文件系统中包含大量的文件, 就会存在两个文件的 inode_number 低 16 位 相同; 此时, 这两个文件对应的 KEY 值 就会相同, 违背了 不同的文件产生不同的 KEY 的原则.
Linux programmer's Manual 是这样说的:
Of course no guarantee can be given that the resulting key_t is unique. Typically, a best effort attempt combines the given proj_id byte, the lower 16 bits of the inode number, and the lower 8 bits of the device number into a 32-bit result. Collisions may easily happen, for example between files on /dev/hda1 and files on /dev/sda1.
gcc 常用实例
前言
GCC (the GNU Compiler Collection) 是由GNU组织开发的编译器套件, 可以执行预处理,编译,汇编和链接动作. 这篇文章首先向大家介绍如何生成C语言的可执行文件, 共享库(动态库) 以及静态库, 然后介绍一下gcc常用的选项.
例子
-
以下的例子都在Ubuntu13.10 上使用gcc 4.8.1 测试通过. 假设有三个文件
main.c 定义main函数
a.c 定义add 函数
b.c 定义sub 函数
- 可执行文件
-
gcc -o test main.c a.c b.c
-
共享库
- 生成共享库
-
gcc -shared -o libmymath.so a.c b.c
- 使用共享库
-
gcc -o test main.c -L. -lmymath
-
静态库
- 生成静态库
gcc -c a.c b.c
ar crv libmymath.a a.o b.o
- 使用静态库
-
gcc -o test main.c -static -L. -lmymath
注意: 当ld的搜索默认搜索路径即包含共享库又包含静态库时, 默认选择链接共享库;若需要链接静态库, 则需要加上-static选项
选项
-
-I(大写的i) 添加路径到预处理器的搜索目录
-
使用方法 -IPATH
gcc -I. -o test main.c a.c b.c
gcc -I/home/tony/work/myheaer -o test main.c
注意: 在搜索头文件时, 通过-I添加的目录会优先与系统默认的搜索目录
-
- -D 预定义宏
-
使用方法 -DNAME
- gcc -DCONFIG_GATE -o test main.c
-
等同于: #define CONFIG_GATE=1
- gcc -DCONFIG_GATE_VALUE=128 -o test main.c
-
等同于: #define CONFIG_GATE_VALU=128
-
-
-c 执行编译和汇编, 但不执行链接动作, 生成中间文件
gcc -c main.c a.c b.c
生成 main.o, a.o, b.o
gcc -c main.s a.s b.s
生成 main.o, a.o, b.o
-
-S 执行编译动作, 但不执行汇编, 生成汇编文件, 通常文件后缀为.s
gcc -S main.c a.c b.c
生成 main.s, a.s, b.s
- -L 添加路径到链接器的搜索目录
-
gcc -o test main.c -L.
- -l(小写的L) 在指定的library中查找符号表
-
gcc -o test main.c -L. -lmypath
- -Wall 打开所有的编译警告
-
gcc -Wall -o test main.c
- -static 优先选择链接静态库
-
gcc -o test main.c -static -L. -lmymath
- -shared 生成的目标为共享库
-
gcc -shared -o libmymath.so a.c b.c
-o 指定生成目标的名字
-
-Wl 传递参数给链接器
gcc -o test main.c -Wl,-Map=out.map -L. -lmymath
gcc -o test main.c -Wl,-rpath=/media/code/exercise/gcc -L. -lmymath
rpath 的作用是添加目录到运行时共享库搜索路径
- -g 生成debugging信息, 在使用debug工具比如GCB的时候需要
-
gcc -g -o test main.c a.c .bc
结束语
虽然gcc是一个非常强大的工具, 但当一个工程比较庞大是, 直接使用gcc是不明智的选择.
git 常用实例
Clone and Checkout
-
clone远程仓库
-
匿名clone
-
git 协议克隆
git clone git@github.com:TonyNie/multiplication.git
-
https协议克隆
git clone https://tony_nie@bitbucket.org/tony_nie/open-stunclient.git
-
-
删除远程分支
git push origin --delete branchname
Tag
-
创建轻量级TAG
git tag v-0.1
-
创建有附注的标签
git tag -a v3.8rc -m "RC 3.8"
-
创建带签名的标签
git tag -s v3.8rc -m "RC 3.8"
-
将标签v3.8rc推送到远程仓库orgin
git push origin v3.8rc
-
将本地所有的标签都推送到远程仓库origin
git push origin --tags
-
将标签v3.8rc 检出
git checkcout -b NEWBRANCH v3.8rc
-
删除本地标签v0.1
git tag -d v0.1
-
删除远程仓库上的标签k1.2.0
git push origin --delete tag k1.2.0
Revert
我们家的宝贝女儿出生了
蓁蓁都出生一个月了, 还没为女儿说点什么.
宝贝, 对不起了. 不是爸爸懒, 是爸爸最近太忙了.
工作忙, 还有新房子的装修; 当然, 还有你哦, 宝贝.
ssh 基本用法
-
本地代理
ssh -qTfnN -D 7070 -p SSHD_PORT yourname@server
ssh -A
小咪的奇怪行为
听到人咳嗽或者打喷嚏, 总是会低低的叫一声, 好像是回应什么
优先选择高处的水, 比如经常喝餐桌或者茶几上水杯中的水
_IOC定义的不严谨性
C语言中默认类型转换绝对是一个坑. 最近项目中有以下一段code, 隐藏了一个很严重的BUG.
实际执行过程发现, UVCIOC_CTRL_QUERY == request 永远为false, 即使request == UVCIOC_CTRL_QUERY.
- 运行环境:
-
Ubuntu12.04 x86_64
写了一段测试code: .. sourcecode:
int main(int argc, char **argv) { int request = UVCIOC_CTRL_QUERY; if (UVCIOC_CTRL_QUERY == request) fprintf(stdout, "equal\n"); else fprintf(stdout, "different\n"); return 0; }
编译, 运行, 得到的结果是 different, 应该是默认转换出了问题. 查看UVCIOC_CTRL_QUERY的定义, 所用到的宏主要定义在 <linux/uvcvideo.h> 和 <sys/ioctl.h>.
#define _IOC_TYPECHECK(t) (sizeof(t)) # define _IOC_WRITE 1U # define _IOC_READ 2U #define _IOC(dir,type,nr,size) \ (((dir) << _IOC_DIRSHIFT) | \ ((type) << _IOC_TYPESHIFT) | \ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) #define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query)
将UVCIOC_CTRL_QUERY 展开, 得到的定义是:
(3U << 30) | ((sizeof(struct uvc_xu_control_query)) << 16) | ('u' << 8) | (0x21)
计算得到的结果为 0xC0107521
在64位机器上, sizeof的返回类型为 long unsigned int. 所以UVCIOC_CTRL_QUERY的类型为 long unsigned int. 所以UVCIOC_CTRL_QUERY的实际值为 0x00000000C0107521
在上述code发生了两次默认转换:
-
requet = UVCIOC_CTRL_QUERY
long unsigned int 转换为int
long unsigned int 的长度为64 bits, int 为32 bits, 直接截断
转换后 request=-1072663263(0xC0107521) , 小于 0
-
UVCIOC_CTRL_QUERY == request
requet 转换为 long unsigned int
转换后为 0xFFFFFFFFC0107521
UVCIOC_CTRL_QUERY != 0xFFFFFFFFC0107521
request 参数是传给系统调用ioctl的第二个参数, 而ioctl的定义为:
int ioctl(int d, int request, ...)
所以将 requet 定义为unsigned int 也不合适.
无论在64位还是32位的机器上, _IOC的定义应该为uint32_t, 所以_IOC的定义应该加强制类型转换.
使用nikola生成静态博客
创建静态博客
使用WrodPress管理和编辑博客, 总觉得不顺手.
有点大, 不利用备份
不方便做版本控制
没有找到合适的编辑工具
后来有同事介绍用sphinx编辑spec. sphinx采用reStructuredText作为标记语言, 可以生成PDF, html等多种格式. 开始考虑是否可以用reStructuredText编辑内容, 然后利用sphinx生成html.尝试几个theme, 都不是太理想.
学习sphinx的过程中, 偶尔发现一个网站介绍pelican和nikola. 尝试了nikola, 发现基本满足需求. nikola提供了一个脚本可以将wordpress中的内容转换为reStructuredText格式, 随将博客迁移过来.
中国拥有的IPV4 地址数目
中国拥有的IPV4 地址数目
从APNIC统计了一下中国拥有的IPV4数量.
总的数目为377938176, 其中:
大陆: 330437120
台湾: 35418880
香港: 11757312
澳门: 324864