PERL单元测试简易框架

本来是写个测试脚本来测试函数是否正确,写着写着就把输出写的漂亮了些,于是将代码抽出来,做成一个公共框架。

说是框架,非常王婆卖瓜,因为就一百五十行SHELL脚本,PERL本是有单元测试的,但是我认为几行代码用那单元测试有点小题大做,最关键是,我的需求非常少,就是要跑几句代码,检测一下返回值,并且匹配一下预期数据,然后列出测试结果而已。

我之前喜欢这样简单测试PERL函数代码:

这样跑一遍,或者加-d调试一下,函数是否有问题,一下就能看出来,唯一的问题是,测试多组输入参数和输出的时候,每次都要靠双眼来对比结果是否符合预期。
继续阅读

代码上库前的自动review实现

perlcritic是一款PERL的静态代码检测工具,官网为:http://www.perlcritic.org
源码下载:https://github.com/Perl-Critic/Perl-Critic,可以参考http://search.cpan.org/dist/Perl-Critic/使用,可以使用CPAN安装:

本日志自动扫描工具建立在Critic基础上,为我们的日志检测规则写了一插件,名为RequireLogStatment,安装文件覆盖/usr/local/share/perl/5.14.2/Perl/Critic/Policy/CodeLayout/RequireLogStatment.pm 即可使用。

检测规则

针对部门使用大量PERL代码做日志规范,当前主要检查该打日志的地方未打日志的行为,该打日志的检查点为:
EXITWORD:return, exit, _exit, die

打日志的函数为:
LOGWORD:ldie lemerg lalert lcrit lerror lwarn lnotice linfo ldebug dbg1 dbg2 dbg3 dbgv

不是所有EXITWORD前都要打日志,且日志级别不一定是lerror,例如一个函数运行最后一条return语句作为合法出口不要求打日志,为了避免日志过多,建议大家按照“先处理错误,最后处理正确原则”书写代码,例如:

如果某些语句真不需要日志,可以添加annotation,规则是在语句前一条注释处加:

继续阅读

QEMU CORE分析之死锁

main线程8003

QEMU出CORE,死在pthread_mutex_lock里:

查看一下,是在等待qemu_global_mutex锁:

通过__owner看出,qemu_global_mutex 已经被人加锁了,线程ID为8417。 继续阅读

利用日志做监控

利用日志做监控,适用于不便修改源码或不便破坏现有环境时,可以通过日志内容采取不同动作,通过对日志本身的实时监控并分析,提取有效信息并采取对应行动。

应用场景可随意想象:例如,之前发现aSV的ssh密码被暴力破解,我们可以通过日志监控暴力破解行为,然后做出阻止。

这并不是一个新技术,也不困难,fail2ban http://www.fail2ban.org/ 做的挺不错,使用起来效果如图: 继续阅读

大页内存在虚拟化中的应用

原理

虚拟内存

简单说,没有虚拟内存的概念,那么COPY ON WRITE,SWAP等技术都不是必要的,但是系统的弹性和容量会大打折扣。
对比物理内存,我们可以认为虚拟内存比物理内存多许多,这个优点依赖于一个重要实现手段叫做page fault,我们将进程“分配内存”和“访问内存”概念分开,分配了内存不访问,是可以不占物理内存的(未初始化未置零等),分配了内存访问,也不一定占用更多的物理内存(COPY ON WRITE)。假设某一虚拟内存已经分配给进程A,当进程A去访问所在内存页时,可能出现:
1. 内存页已经存在于CPU Cache或物理内存,并且进程A有访问权限。这是正常情况。
2. 内存页已经存在于CPU Cache或物理内存,但是进程A还没有访问权限或者第一次访问前并没有实际载入,例如,进程A要访问libc.so的代码段,这段虚拟内存其实已经被其他进程加载到物理内存了,但是还没有赋给进程A访问权限,此时发生page fault,我们称之为minor page fault.
3. 内存页不存在于CPU Cache和物理内存。可能原因是内存已经被交换到交换分区,此时我们需要通过IO将内存页读入物理内存再给进程A访问,此过程我们称之为major page fault.

想要证明min_flt和maj_flt的发生,我们可以使用 /usr/bin/time -v CMD 来执行命令,例如,我们运行一个记事本,第一次运行的时候,会从磁盘载入共享库,所以会有Major (requiring I/O) page faults,第二次,我们先运行一个记事本程序,再使用/usr/bin/time –v运行记事本,由于使用到的共享库已经加载到内存了,我们会看到Major (requiring I/O) page faults会减少甚至为0。
继续阅读

QEMU虚拟存储的几种访问形式

存储相关命令

查看是否有FC存储:

其中ID为81:00.0 的 vendor & device ID 为 1657: 0013(上面中括号内),通过device ID,可以查找是否已经有设备驱动存在:

上面命令最后的bfa为此HBA的驱动名称,查看是否已经加载驱动:

继续阅读

oVirt安装体验(CentOS 7.2)

ovirt是redhat支持的QEMU管理UI,本次安装主要是想体验不同的管理软件。 主要根据文章http://jensd.be/550/linux/install-ovirt-on-centos-7来安装,安装结果基本能用,但是错误比较多。

安装软件

本机节点IP是200.200.103.61,我设置本机的hostname为cent7。

然后安装软件

继续阅读

自制Office Web插件导出BLOG

写文章还是WORD比较适合,但是发布到BLOG网站却是HTML,每次转换格式都是件麻烦的事情,于是写了个简单的转换插件,能自动将部分内容按BLOG格式转换,减少人为参与。

Office的WEB插件非常简单,就是简单的js和html即可,工程名字取名为CleanHtmlExport,于是先写入口配置文件CleanHtmlExport.xml:

其中最重要的一条就是SourceLocation用于指定了入口html,这里的位置选择网络位置,例如我的是共享本地目录。 入口html就是普通的html,唯一需要的是引入office的辅助脚本:https://appsforoffice.microsoft.com/lib/1/hosted/office.js 继续阅读

Redis做内容缓存改善大集群性能问题

启动虚拟机前,需要选择运行节点,运行节点的选择主要是评估每个节点的内存和CPU使用,之前的PERL端是通过datareport向所有节点发送请求,走NFS通道,收集结果后打包回复PERL,大集群是48个节点,最开始尝试批量启动1000台虚拟机一天都没能启动完成。

评估每个节点的内存和CPU很必要,但是过中消耗时间太久,平均每台机器启动消耗2分钟,1000台需要33小时。

小打小闹优化效果并不明显,对比了几种优化手段,最后选择了使用Redis内存数据做缓存。

为什么选择Redis?

首先,不用引入新组件,因为我们的系统一直有它,但被忽视了很久。

其次,Redis的代码写的不错,短小精悍,运行稳定,效率非常高。
我测试从48个节点并发1600个链接不停读写主控的数据库,消耗资源为4.7% CPU, RSS内存消耗22MB,读写时间在毫秒级别:

继续阅读

Perl运行时调试工具

Perl这个语言没有现成的运行时调试工具,网上罗列的办法有:
1. strace只能看系统调用的函数,而且是perl解释器执行的流程。
2. gdb,只能调试perl解释器。
3. gdbperl,bulkdbg,没有用过。
4. perl-stacktrace,inspect-perl-proc两款在我们的虚拟化平台都没能正确运行。

13年的时候,写过一个运行时给Perl注入Enbugger库,使其能调试的脚本,为运行时调试而生。今天想查看某些阻塞进程究竟在做啥,于是加一个新技能,打印运行时的Perl脚本堆栈,是Perl脚本堆栈,不是Perl解释器堆栈。
注意:如果Perl处于阻塞状态,是无法interrupt的,例如下面进程处于等待锁状态,无法插入代码:

处于加锁等待,不返回无法注入代码。
继续阅读