分类:
2010-05-25 16:04:03
今天 VPN 突然连不上了,到终端启动 xl2tpd ,发现启动报错,说是无法读取配置文件:
$ sudo xl2tpd -D xl2tpd[4344]: parse_config: line 13: data 'l parameters:' occurs with no context xl2tpd[4344]: init: Unable to load config file
真是奇怪,我打开 /etc/xl2tpd/xl2tpd.conf
看了一下,十三行好好的嘛,只是注释而已。我甚至怀疑它打开的是什么文件,于是用 strace 跟踪了一下:
$ sudo strace xl2tpd -D execve("/usr/sbin/xl2tpd", ["xl2tpd", "-D"], [/* 14 vars */]) = 0 brk(0) = 0x8063000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fd9000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=76622, ...}) = 0 mmap2(NULL, 76622, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fc6000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/i686/cmov/libc.so.6", O_RDONLY) = 3 read(3, "\\177ELF\\1\\1\\1\\0\\0\\0\\0\\0\\0\\0\\0\\0\\3\\0\\3\\0\\1\\0\\0\\0\\260a\\1"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0644, st_size=1336100, ...}) = 0 mmap2(NULL, 1340944, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e7e000 mmap2(0xb7fc0000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x142) = 0xb7fc0000 mmap2(0xb7fc3000, 9744, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7fc3000 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e7d000 set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e7d6b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0 mprotect(0xb7fc0000, 4096, PROT_READ) = 0 munmap(0xb7fc6000, 76622) = 0 time(NULL) = 1189503420 brk(0) = 0x8063000 brk(0x8084000) = 0x8084000 open("/etc/xl2tpd/xl2tpd.conf", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=5749, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fd8000 read(3, ";\n; Sample l2tpd configuration f"..., 1024) = 1024 getpid() = 4346 write(2, "xl2tpd[4346]: parse_config: line"..., 81xl2tpd[4346]: parse_config: line 13: data 'l parameters:' occurs with no context ) = 81 close(3) = 0 munmap(0xb7fd8000, 4096) = 0 write(2, "xl2tpd[4346]: init: Unable to lo"..., 47xl2tpd[4346]: init: Unable to load config file ) = 47 exit_group(1) = ? Process 4346 detached
可以看到它打开的确实是
/etc/xl2tpd/xl2tpd.conf
。半天都摸不着头脑,只好去 Google ,搜索出来唯一有点用的只有 了。l2tpd 和 xl2tpd 应该大体上差不多吧。我找到那一行打印出错的地方,大致看了一下 这个函数,发现它是自己手工在解析 ini 的配置文件格式,并且用 fgets
来读取一行的内容,而它的一行是多少呢?
992 |
char buf[STRLEN]; |
而 STRLEN
的定义是 80 。再看打印出错代码的那句代码:
1150 1151 1152 |
log (LOG_WARN, "parse_config: line %d: data '%s' occurs with no context\n", linenum, s); |
而 s
是读取的那一行去掉注释以后的内容。于是我再去搜索配置文件,发现确实有 “l parameters”,其实是一行注释(当然,并不是它说的那样在第 13 行):
11 |
; [global] ; Global parameters: |
这下一切都明了了,它用 fgets
来读取一行,读到 “Global” 的 “l” 那里为止,下一次读的时候又读了一个尾巴,当然那不是什么有效的配置,所以就报错了,还因此把报错的行号都搞错了,因为它所谓的“一行”根本不是一行嘛。把那些超过 80 个字符的行编辑一下就可以了。
但是我比较奇怪的是这配置文件前面的一大段注释是它安装好就有的,而且我以前用都没有问题,怎么今天有好多行都就超过 80 个字符了。我今天只是用 Emacs 打开把一个 “a” 改成 “c” 了而已。要说也只有是 Emacs 自动把 tab 变成 8 个空格了,但是也没道理啊,我以前一直都是用 Emacs 改这个文件的,太奇怪了。
不过,l2tpd 那个代码也确实太不健壮了。。。 -.-bb