要说免费使用的防火墙那多了,但都不开源,而我更喜欢开源的,能学到东西。


可下到源代码

IPCop

http://sourceforge.net/projects/ipcop/develop
可以下载源代码。
svn co https://ipcop.svn.sourceforge.net/svnroot/ipcop ipcop


EFW

http://www.endian.com/
这个比较大,600M源码包,非常全。


Vyatta

基于debian
http://www.vyatta.org/downloads
目前这个是我发现的有专门针对虚拟化平台优化的版本。
http://www.vyatta.org/getting-started/how-to-install


Installing Vyatta Core in a Virtualized Environment
If you’re deploying Vyatta Core on a hypervisor such as VMWare ESX/ESXi or Citrix XenServer,
you’ll want to use the Vyatta virtualization ISO (virt-ISO).
Similar to the LiveCD ISO, the virt-ISO provides a bootable ISO,
except it also includes virtual machine tools and other optimizations
to deliver the best possible experience for users running Vyatta on a virtual machine.


Using the vSphere Client, create a new VM

  • Configuration: Custom
  • Name: “vyatta”
  • Datastore: default
  • Virtual Machine Version: 7
  • Guest OS: Linux/Other 2.6x Linux
  • CPU: “1”
  • Memory: “512”
  • Network: “2” / vmxnet3
  • SCSI Controller: default
  • Select a Disk: default
  • Create a Disk: “4”GB (thin provisioning and independent / persistent mode)
  • Advanced Options: Enable “Support VMI Paravirtualization”


使用了
open-vm-tools
ec2-api-tools 是不是可以通过api来管理此虚拟机,或者获得性能等。ec2-api是什么东东?


获取源代码

http://www.vyatta.org/downloads/source-code


git clone http://git.vyatta.com/build-iso.git
cd build-iso
注意要先调整到一个分支或者tag
build-iso$ git branch –track <branch> origin/<branch>
build-iso$ git checkout <branch>
或者
git checkout tagv1


获取子模块的代码
git submodule init
git submodule update pkgs/SUBMODULE


克隆所有模块
git submodule update


install

启动虚拟机,用缺省的用户名/密码 vyatta/vyatta登陆系统
install image 基于image安装,推荐,可以切换image
install system 基于disk安装,传统硬盘安装方式


There are two types of installations that can be performed on a persistent device:
• Image-based install. The simplest, most flexible, and most powerful way to
install a Vyatta system is using a binary system image. With this method, you can
install multiple versions of the Vyatta system as images and switch between the
images simply and easily. You install the image from a LiveCD then you reboot
your system and it runs the image.
• Disk-based install. A disk-based install also installs from a LiveCD onto a
persistent device such as a hard disk partition. However, unlike an image-based
install, a disk-based install uses a traditional layout of files on the disk.
Additional system images may be added at a later time to a system created using
a disk-based install.


nstall-image (is what I would suggest btw) is using squashfs and is capable of booting/running multiple images of versions


真让我好找,找了一天,终于找到安装脚本了,在pkgs/vyatta-cfg-system


debian install

这个貌似比较重要,vyatta之所以看不太明白,应该是对d-i不了解。
看看internal
http://d-i.alioth.debian.org/doc/internals/

配置ip

vyatta@vyatta:~$ configure
vyatta@vyatta# set interfaces ethernet eth0 address 192.168.1.81/24
vyatta@vyatta# commit
vyatta@vyatta# exit


启动webui

vyatta@R1# set service https
不过需要商业版才能使用webui


linux-image

vyatta的内核配置
/home/liwei/work/src_analysis/tag_vyatta_src/pkgs/linux-image/debian/arch/i386/config.586-vyatta-virt



添加上一个命令的最后一个参数

Alt .
反复按会继续向上搜索


字符串比较,注意要用引号

字符串比较说明
大多数时候,虽然可以不使用括起字符串和字符串变量的双引号,但这并不是好主意。为什么呢?因为如果环境变量中恰巧有一个空格或制表键,bash 将无法分辨,从而无法正常工作。这里有一个错误的比较示例:
if [ $myvar = “foo bar oni” ]
then
echo “yes”
fi


在上例中,如果 myvar 等于 “foo”,则代码将按预想工作,不进行打印。但是,如果 myvar 等于 “foo bar oni”,则代码将因以下错误失败:
[: too many arguments


在这种情况下,”$myvar”(等于 “foo bar oni”)中的空格迷惑了 bash。bash 扩展 “$myvar” 之后,代码如下:
[ foo bar oni = “foo bar oni” ]


因为环境变量没放在双引号中,所以 bash 认为方括号中的自变量过多。可以用双引号将字符串自变量括起来消除该问题。请记住,如果养成将所有字符串自变量用双引号括起的习惯,将除去很多类似的编程错误。”foo bar oni” 比较 应该写成:
if [ “$myvar” = “foo bar oni” ]
then
echo “yes”
fi



算术表达式 $(( ))

$ myvar=”56”
$ echo $(( $myvar + 12 ))


名字空间,全局性

在 bash 中,每当在函数内部创建环境变量,就将其添加到 全局名称空间。这意味着,该变量将重写函数之外的全局变量,并在函数退出之后继续存在


捕获脚本的输出 2>&1 | tee T型管道

当显示正在生成的输出时,捕获每个脚本的输出
如果脚本不能自动地将输出发送到文件的话,可以利用 Bash shell 的一些函数来捕获所执行脚本的输出,如:
./test-bucket-1 -s 2>&1 | tee test-bucket-1.out


让我们来分析上面的命令:
“2>&1” 命令:
使用 “2>&1” 将标准错误重定向到标准输出。字符串 “2>&1” 表明任何错误都应送到标准输出,即 UNIX/Linux 下 2 的文件标识代表标准错误,而 1 的文件标识代表标准输出。如果不用此字符串,那么所捕捉到的仅仅是正确的信息,错误信息会被忽略。
管道 “|” 和 “tee” 命令:
UNIX/Linux 进程和简单的管道概念很相似。既然这样,可以做一个管道将期望脚本的输出作为管道的输入。下一个要决定的是如何处理管道所输出的内容。在这种情况下,我们会将它捕获到输出文件中,在此示例中将之称为 “test-bucket-1.out”。
但是,除了要捕获到输出结果外,我们还想监视脚本运行时产生的输出。为达到此目的,我们连接允许两件事同时进行的 “tee” (T- 形管道):将输出结果放在文件中同时将输出结果显示在屏幕上。 其管道类似于:
process –> T —> output file
V
screen


如果 只 想捕获输出结果而不想在屏幕上看到输出结果,那可以忽略多余的管道: ./test-bucket-1 -s 2>&1 > test-bucket-1.out
假若这样,相类似的管道如下:
process –> output file


sudo 输出重定向


当我们使用sudo 进行输出重定向的时候,命令的第二部分无法获得授权


sudo command > outputfile


<>—-root——<>—user—<>


解决方法:


使用’sudo tee’代替”>”;


使用”sudo tee -a”代替”>>”;


sudo command | sudo tee outputfile


<>—–root—–<>——-root——<>


产生随机数

dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -f1 -d” ”


取得一些文件名称中的一部分名称

interfaces=`ls session_* | sed ‘s/^session_//g’ | sed ‘s//.log$//g’`


如何用bash从文件中读一行

while read line
do
echo $line
done < “$filename”


如何用bash发现某些文件中是否没有包含string


jsps=`find . -name “*.jsp”`


for jsp in $jsps; do
havegb=`grep gb2312 $jsp`
[ ! -n “$havegb” ] && echo $jsp
done


cd 替换技巧

cd dir1/abc
使用cd old new实现替换
如:
cd dir1 dir2
等效于
cd dir2/abc


上一条命令替换

^foo^bar
将上一条命令中的foo替换为bar,然后执行


centos kdump


介绍

通过kexec和kdump当内核crash的时候可以显示堆栈信息。方便调试。


安装

sudo yum install kexec-tools
sudo yum install kernel-debug kernel-debug-devel
yum install crash gdb


为了让内核都统一,不妨内核也升级一下
yum install kernel kernel-devel


添加内核启动参数

crashkernel=128M@16M
在/etc/grub.cfg中添加,表示启动的时候从16M的位置开始,预留128M内存用于crashkernel
注意centos6.2我发现可能已经默认支持了kdump,只是没有启动而已,grub.cfg中已经添加了crashkernel=auto


配置文件

/etc/kdump.conf
配置coredump的位置,默认是 /var/crash


测试

reboot后
这会创建/boot/initrd-kdump.img用于capture coredump,这非常重要,否则kdump就会启动失败。
该文件就是kdump加载的内核的 initrd文件,收集dump信息的工作就是在该initrd的启动环境下进行的。
查看/etc/init.d/kdump脚本的代码,你可看到其中会调用mkdumprd命令创建用于dump的initrd文件。


service kdump status


触发crash
echo 1 > /proc/sys/kernel/sysrq
echo “c” > /proc/sysrq-trigger


等待时间比较长,大概5分钟,系统又重新进入了桌面。


用crash 工具分析vmcore 文件


用crash 命令分析vmcore 的命令行格式如下所示.
用crash打开vmcore后,主要是用dmesg及 bt 命令打印出问题的执行路径的call trace,
用dis 反汇编出代码,最终确认call trace对应的C源码中的位置,再进行逻辑分析.



遗留问题

用crash需要vmlinux,到哪里获得?
可能需要安装kernel-debuginfo
但标准库里可能没有,需要另外添加。
http://www.dedoimedo.com/computers/centos-debug.html


http://wiki.centos.org/AdditionalResources/Repositories
已经说得很清楚了,需要额外添加debuginfo的库
不过看到centos6.2中自带了
/etc/yum.repos.d/CentOS-Debuginfo.repo
注意把其中的enabled改为1,然后就可以安装了
kernel-debuginfo 将近300M


先不下了,速度太慢了,10k。


还有个问题,就算能看vmcore了,那模块coredump也能看吗?


systemtap

有空再研究一下kprobe和systemtap
http://hi.baidu.com/donglix/item/13052275911e7a5f0c0a07f8

Table of Contents

gcov


分支覆盖的作用

所有单元测试跑完后,统计分支覆盖率,统计测试的是否全面。一个程序如果每个分支都执行过了,也不能保证程序就是正确的。
毕竟还有很多逻辑错误,但至少能从某种程度上显示出,这些代码测试的是否完善,不完善就还需要补充测试用例。
可以显示出每行被执行了多少次,哪行没有被执行。



参考

GCOV 实现原理
<深入浅出Linux平台代码覆盖率测试.pdf>





特性

c的单元测试见的多了,cutter有什么看家本领吗?

  1. 框平台性好
    这个貌似意义不大,单元测试框架一般本身都很小巧,移植难度很小。


  2. 自动探测用例
    这个功能不错,只要开头是test_ 开头的函数,自动认为是testcase。
    其实他是把testcase编译成了库,然后进行符号查找。


  3. 显示友好
    尽量精确的提出错误在哪里,有个expect和real,貌似还可以diff。


  4. 支持数据驱动测试
    这个功能还有点不明白,貌似应该是测试前准备数据集的功能,不知道是否是mock功能。


  5. 支持代码的分支覆盖率攻击。


  6. 针对ubuntu特别优化。



后续待添加功能

从他的TODO中可以看到一些,不过我最期望的是:

  1. 测试用例的search
  2. 内存泄漏测试,最好集成memwatch的功能。mem_limit很好。
  3. 是否有mock功能?


memwatch


Memwatch简介

在三种检测工具当中,设置最简单的算是memwatch,和dmalloc一样,
它能检测未释放的内存、同一段内存被释放多次、位址存取错误及不当使用未分配之内存区域。
请往
http://www.linkdata.se/sourcecode.html
下载最新版本的Memwatch。


MemWatch的内存处理

MemWatch将所有分配的内存用0xFE填充,所以,如果你看到错误的数据是用0xFE填充的,那就是你没有初始化数据。
例外是calloc(),它会直接把分配的内存用0填充。


MemWatch将所有已释放的内存用0xFD填充(zapped with 0xFD).
如果你发现你使用的数据是用0xFD填充的,那你就使用的是已释放的内存。
在这种情况,注意MemWatch会立即把一个”释放了的块信息” 填在释放了的数据前。
这个块包括关于内存在哪儿释放的信息,以可读的文本形式存放,格式 为”FBI<counter>filename(line)”。
如:”FBI<267>test.c(12)”.使用FBI会降 低free()的速度,所以默认是关闭的。使用mwFreeBufferInfo(1)开启。


初始化和结束处理

一般来说,在程序中使用MemWatch的功能,可以手动添加mwInit()进行初始化,并用对应的mwTerm ()进行结束处理。
一般不需要手动添加,memwatch会在第一个malloc的时候自动初始化,并在atexit中添加mwTerm。


如果自动初始化不合适或者程序比较特殊,请显式调用mwInit()和mwTerm().
比如,有的时候明明程序没有问题,而memwatch显示内存泄漏,这时就需要手动调用初始化和结束。


涉及的函数主要有:
mwInit() mwTerm() mwAbort()


MemWatch的I/O 操作

对于一般的操作,MemWatch创建memwatch.log文件。有时,该文件不能被创建;
MemWatch会试图创建memwatNN.log文件,NN在01~99之间。


如果你不能使用日志,或者不想使用,也没有问题。
只要使用类型为”void func(int c)”的参数调用mwSetOutFunc(),然后所有的输出都会按字节定向到该函数.


当ASSERT或者VERIFY失败时,MemWatch也有Abort/Retry/Ignore处理机制。
默认的处理机制没有I/O操作,但是会自动中断程序。
你可以使用任何其他Abort/Retry/Ignore的处理机制,只要以参数”void func(int c)”调用mwSetAriFunc()。


涉及的函数主要有:
mwTrace() mwPuts() mwSetOutFunc() mwSetAriFunc()
mwSetAriAction() mwAriHandler() mwBreakOut()


使用

在要使用MemWatch的.c文件中包含头文件”memwatch.h”


使用GCC编译(注意:不是链接)自己的程序时,加入-DMEMWATCH -DMW_STDIO
如:gcc -DMEMWATCH -DMW_STDIO –o test.o –c test1.c memwatch.c


使用MemWatch提供的功能

  1. mwTRACE,mwASSERT,mwVERIFY和mwPuts
  2. ARI机制即程序设置的“Abort, Retry, Ignore选择陷阱
  3. mwSetOutFunc
    将输出转向调用者给出的函数(参数即函数地址)。参数为NULL,表示把输出写入日志文件memwatch.log.
  4. mwIsReadAddr
    检查内存是否有读取的权限
  5. mwIsSafeAddr
    检查内存是否有读、写的权限
  6. mwStatistics
    设置状态搜集器的行为。对应的参数采用宏定义。


    #define MW_STAT_GLOBAL 0 * 仅搜集全局状态信息 *
    #define MW_STAT_MODULE 1 * 搜集模块级的状态信息 *
    #define MW_STAT_LINE 2 * 搜集代码行级的状态信息 *
    #define MW_STAT_DEFAULT 0 * 默认状态设置 *


Memwatch使用注意

Memwatch 的优点是无需特別配置,不需安装便能使用,但缺点是它会拖慢程序的运行速度,尤其是释放内存时它会作大量检查。
但它比mtrace和dmalloc多了 一项功能,就是能模拟系统内存不足的情況,
使用者只需用mwLimit(long num_of_byte)函数来限制程式的heap memory大小(以byte单位)。


最详细的使用说明(包括优点缺点,运行原理等)已在README中列出,本人强烈建议各位读者参考该文件。



CUnit


CUnit交叉编译

我更换到ubuntu12.04上编译CUnit已经编译不过去了,错误原因是:
libtool : X–tag=CC: command not found 编译报错
原因据说是因为在项目目录下生成的libtool脚本中定义了$ECHO变量,但是在脚本文件ltmain.sh中,使用的却是$echo(生成的libtool版本太旧)
可通过以下方法解决:


  1. 直接复制系统自带的libtool到项目目录,应该在/usr/bin目录下,覆盖代码文件目录下的libtool,再执行make

(没装就apt-get install libtool 或者 yum install libtool 安装一下吧)
但是这有个问题,不能用于交叉编译,系统的libtool会使用系统的ld等,而应该使用交叉工具连的ld。


  1. 修改aclocal.m4文件,将上面的LIBTOOL=’$(SHELL) $(top_builddir)/libtool’改成

LIBTOOL=’$(SHELL) /usr/bin/libtool’后重新执行./configure


  1. 将源码目录下libtool脚本中所有的$ECHO替换成$echo. 或者将脚本文件ltmain.sh里的$echo替换成$ECHO,

都一样,重新执行./configure


另一种解决方案
export echo=echo 回车后 make 正常


使用bootstrap而不是configure

没有了上边的libtool的问题,直接修改bootstrap,添加CC就ok了。
CC=/workspace26/i386-env/cross-tools/bin/i686-unknown-linux-gnu-gcc
或者采用–host的形式:
PATH=/workspace26/i386-env/cross-tools/bin/:$PATH LD_LIBRARY_PATH=/workspace26/env-x86-lib
./configure –host=i686-unknown-linux-gnu –enable-shared=no –disable-dependency-tracking

svn使用


svn libneon的问题

ubuntu安装的svn要使用https时,默认使用的libneon-gnutls有点兼容性问题。所以导致的错误是:
SSL handshake failed: SSL 错误:在证书中检测到违规的密钥用法。
解决办法:
http://www.yeap.de/blog2.0/archives/260-Subversion-Certificate-Problems-with-Ubuntu-Precise-Pangolin.html


自己编译,真的不容易啊

cd openssl
由于是64bit系统,所以需要添加fPIC
./config -fPIC
但是cropt目录不好添加fPIC,难道生成的.a难道也需要fPIC吗?,所以无奈,只能先安装系统的openssl
apt-get install openssl-dev openssl


cd subversion
./configure –with-ssl=openssl –with-neon=./neon –with-openssl=/usr
出现warnning无用理会直接make


分支管理

一般svn版本库目录建议创建trunk、branches和tags三个目录。
trunk主干版本要时刻保持干净,即随时可以基于这个版本进行修改并将应用部署上线。
branches是分支目录,存放并行开发的项目代码,因为分支是主干的廉价拷贝,所以你可以放心建立很多分支版本。
不过Subversion不支持跨版本库的拷贝,当使用svn copy时你只能在同一个版本库内操作。
tags目录存放trunk某个的快照。


  1. svn copy 创建分支


svn copy -m "1.7.2 - theme" svn://localhost/www/trunk svn://localhost/www/branches/branch1.7.2-theme
svn co svn://localhost/www/branches/branch1.7.2-theme
注意,如果想更换其他用户,可以使用:
svn –username john –password pass


2) 开发了一段实现,要先把trunk版本merge过来


#branch1.7.2-theme是分支目录,注意不可以进到分支子目录
cd branch1.7.2-theme
#前面的12972是开分支之前trunk的版本号,后面的12991是merge时trunk的版本号
svn merge -r 12972:12991 svn://localhost/www/trunk
解决冲突后,提交


svn ci -m 'svn merge -r 12972:12991 svn://localhost/www/trunk'
3) 从分支merge到trunk。上线测试完毕,你很幸运,一切都如预期正常,这时就要将分支回归trunk,将trunk更新到最新。


#先从trunk checkout一份新鲜的代码,然后cd到该版本目录下
svn co svn://localhost/www/trunk
cd trunk
#12973是分支开始的版本号,13006是分支结束的版本号
svn merge -r 12973:13006 svn://localhost/www/branches/branch1.7.2-theme

svn-commit.tmp

看看 svn help commit, 发现有 -F 可以用, 平常都只有用 -m ‘message’ 而已.
-m: 在于只有一行打完, 可以快速 commit 用.


ex: svn ci -m 'log message'
-F: 会把档案内容读进来, 然后直接 commit, 想当然就用 -F 直接取 svn-commit.tmp 来 commit.


ex: svn ci -F svn-commit.tmp
PS: commit 完后, 还是要手动 rm svn-commit.tmp


删除文件

svn delete path -m “delete test fle“
例如:
svn delete svn://192.168.1.1/pro/domain/test.php -m “delete test file”
或者直接


svn delete test.php
svn ci -m ‘delete test file‘
推荐使用这种简写:svn (del, remove, rm)


merge

svn merge -r m:n path
例如:
svn merge -r 200:205 test.php
(将版本200与205之间的差异合并到当前文件,但是一般都会产生冲突,需要处理一下)


代码回滚

撤销一个已提交的版本,修改有误,不应该提交,需要回滚到上一个版本
执行命令
$svn merge -r 20:19 $URL
检查工作拷贝结果
$svn status
提交拷贝结果
=$svn ci -m “undo change commited in r20”=


cat

svn cat -r 2 filename 显示文件指定版本内容


status -u

与版本库最新版本比较,*提示文件需要更新


ignore

添加ignore
svn propedit svn:ignore calc


被svn坑了,原来默认是忽略.o,.a,.so之类的。
svn add –no-ignore .


查看某次提交忽略的文件:svn status –no-ignore xxxroot
设置忽略文件列表svn pe svn:ignore xxxx
设置全局忽略文件列表
编辑~/.subversion/config文件,修改此文件中的global-ignores,
例如,想让subversion忽略vim的交换文件文件,可以这样设置:
global-ignores = *.o *.swp


root用户的配置是 /etc/subversion/config


svn st –no-ignore 查看所有
遇到的问题,添加的时候
svn add –no-ignore *


add * –force

并没有把剩余的添加上,只能通过一个一个目录来添加,不知道为什么?
解决:
通常情况下,命令svn add *会忽略所有已经在版本控制之下的目录,
有时候,你会希望添加所有工作拷贝的未版本化文件,包括那些隐藏在深处的文件,可以使用svn add的–force递归到版本化的目录下:
$ svn add * --force


svn服务器IP修改后,本地怎么跟新svn同步,svn relocate 操作

svn switch –relocate URL1 URL2


svn -v log

查看每次提交修改的文件列表。
svn -v log
svn -v -r 35 log dir/




参考资料

FAQ