systemtap 进阶

执行hello word命令出错:

从错误来看,只是比较时间上有差异,而且差别不大,如果能不比较该时间,或许问题就解决了(其实我们前面犯过一个不大不小的错误)

通过stap -v 选项 (可以多些几个v的,v越多信息越详细),如下:

然后打开文件: /tmp/stapjbY7L4/stap_19453_src.c ,错误位置如下:

从上图来看:

如果不去定义 常量 STAPCONF_GENERATED_COMPILE 就不会走到该逻辑,问题或许可以解决,那么 STAPCONF_GENERATED_COMPILE 是在哪里定义的呢?

其实就在旁边的一个 .h 中定义的,而该 .h 和该 .c 一样都是该目录下的Makefile 动态生成的,Makefile里面有如下逻辑:

不幸的是 Makefile本身也是动态生成的:

  1. 要么通过修改上述if逻辑中相关的某个文件,让返回值为“假”
    我用到的是文件: /usr/share/systemtap/runtime/linux/autoconf-generated-compile.c 内容很简单:

    问题就来了, <generated/compile.h>  是哪个目录下的?
  2. 要么找到生成Makefile的地方,去掉该逻辑
    我简单找了一下,没找到

 

还有别的办法没?

 

因为systemtap依赖不多,其中一个rpm包就是kernel-devel,怀疑问题出现在kernel-devel ,那么去kernel-devel的文件中搜索 UTS_VERSION 这个常量试试,果然,发现文件: /usr/src/kernels/3.10.0-229.14.1.el7.x86_64/include/generated/compile.h (这不就是上面提到的 <generated/compile.h>嘛?)内容如下:

终于找到了 UTS_VERSION ,直接修改下这里的UTS_VERSION ,问题解决。

 

据说,这个常量信息是编译内核的时候自动生成的(从文件第一行也能看出来),所以,每次编译时间都会不一样,如果自己编译的内核,而去使用别人提供的kernel-devel,必然会遇到我这里出现的问题

上面提到说,我犯过一次错误,是这样的:

我的kernel-devel 是从 http://rpm.pbone.net/ 下载的,这里的rpm包有一个distribution的属性,由于rpm包大小相同,我就随便下载了一个,其实是有区别的,至少上面的时间是不同的,重新选择centos7的下载,重新安装,问题解决

新下载的rpm包中文件/usr/src/kernels/3.10.0-229.14.1.el7.x86_64/include/generated/compile.h 如下:

总结: systemtap 之所以入门较难,和苛刻 的内核版本号 以及yum安装的时候只安装最新的rpm包有极大关系,yum源中可能找不到自己内核版本的kernel-devel

 

参考资料:

http://blog.yufeng.info/archives/1098

http://blog.csdn.net/zhangskd/article/details/25708441

 

安装正确的debuginfo版本是非常重要的,对于fedora系统来将,yum中找不到的,可以直接去build系统中找,如,我的fedora的kernel相关rpm包: https://koji.fedoraproject.org/koji/buildinfo?buildID=1426588 其它版本的也能找到,在这里 如果搜索不到的话,可以按照字母顺序找找,可能搜索不好使

 

 

vagrant 配置windows虚拟机

相比较在vagrant中配置centos来讲,配置windows会比较麻烦而且特殊一些,下面记录一些自己的经历。

第一步:创建虚拟机

由于windows的vbox不多,能找到一个适合自己的也不太容易,倒不如自己在virtualbox中直接用iso文件安装一个,安装完成后直接: vagrant package –base the_virtualbox_vm_name –output my_windows.box

由于windows不比centos可以使用ssh登录,而是有自己的管理方式,叫做wrm,这个必须在安装windows的时候都设置好,参考资料:

下面是我遇到过的一些问题:

  1. 为了避免忘记密码,干脆没给用户设置密码;然而,wrm要求管理员用户必须设置密码,否则,无法配置wrm;就因为这个浪费了不少时间
  2. 网络连接类型不能是公共网络,否则wrm不允许使用
  3. 为了不必要的麻烦,干脆把防火墙给关掉了

重要配置:

曾经因为没有设置@{AllowUnencrypted=”true” }  和 @{Basic=”true”} 浪费了很多时间

关闭UAC: http://jingyan.baidu.com/article/09ea3ede241689c0afde3972.html

第二步: 配置vagrantfile

vagrant默认使用ssh,而windows要使用wrm,那么,总得有个方式说明一下吧?vagrant官网文档查看了一大片,没找到,最后还是在 http://huestones.co.uk/node/305  找到的,如下:

windows中很可能会出现未识别的网络或者是“公用网络”,在这种情况下,winrm是不能正常使用的,所以,保险起见,vagrantfile中添加如下设置:

确保不会出现公用网络,曾经因为这个浪费了不少时间

 

附:一个windows的vagrantfile

 

附:

如何给设置的ip指定掩码(默认24位)? 如下指定22位掩码:

windows的“未识别网络”是什么意思?

当本地连接设置为“自动获取IP地址”,同时网络中又没有dhcp服务器,则该本地连接会被标识为“未识别网络”;如果在所在网络提供一个dhcp服务器,就会避免此种问题的出现

 

 

Docker存储扩容

 

脚本:

参考:

https://docs.docker.com/engine/userguide/storagedriver/device-mapper-driver/

http://jpetazzo.github.io/2014/01/29/docker-device-mapper-resize/  翻译版: https://segmentfault.com/a/1190000002931564

https://segmentfault.com/a/1190000004302467  这里的扩容方式比较低级,是丢失数据的扩容方式

https://docs.docker.com/engine/userguide/

https://developerblog.redhat.com/2014/09/30/overview-storage-scalability-docker/

http://blog.opskumu.com/docker-storage-setup.html

http://coolshell.cn/articles/17200.html   这篇文章非常不错

关于最近我的blog经常没有响应的问题

最近,经常出现我的blog不能响应的问题,起初怀疑网络问题,因为我是部署在阿里云的。后来,忍无可忍,查了一下:

  1. 首先,浏览器中不能响应的时候,curl还是能正常访问的
  2. 其次,通过tcpdump抓包发现,确实是请求发送到了server,而server没有回应
  3. strace跟踪server端进程,发现大量进程在试图flock 一个文件,lsof查看,发现确实在试图lock我的session文件
  4. 肯定有一个进程lock住session文件后,在干别的耗时的事情,一直也没干完
  5. 继续strace打开session文件的每一个进程,必然会有一个文件打开了session文件,但是没有处于flock系统调用阶段,果然,是进程15822
  6. pstack 15822, 结果如下:

     
  7. 显然,该进程正在试图通过curl访问一个外部资源,应该是连接不上,lsof 查看部分结果如下:
  8. 一切不出所料,但是,至此,我根据上面信息还无法知道究竟是哪个逻辑要访问该资源
  9.  借助php源码中提供的 .gdbinit 通过zbacktrace来看,不过忙了一会儿,进程不在了,下次再说吧
  10. N 天后,相同问题再次出现,本次进程id: 826
  11. 直接 gdb -p 816 然后zbacktrace
    最后发现由于插件: /data1/www/htdocs/phpor.net/blog/wp-content/plugins/google-analytics-dashboard/ga-lib.php 导致,相关域名: www.googleapis.com ; 域名解析发现果然和上述IP契合
  12. 解决办法,直接禁用该插件

cobbler 配置镜像源

对于一个公司来讲,为了安装软件方便,最好有一个自己的yum源镜像,下面介绍用cobbler配置镜像源。

  1. 下载安装cobbler 《略》
  2. 配置cobbler 《略》
  3. 添加镜像源,如:
  4. 编辑已添加的镜像源
    把 add 换作 edit,其余的需要修改哪项就该对应参数即可
  5. 删除镜像源 《略》

注:

  1. cobbler只同步每个rpm的最新版本,就的版本就不见了《如何保留旧版本呢?》
  2. 每个镜像源对应一个目录,该目录下会有repodata子目录,如果没有这个目录就不是一个有效的yum源
  3. 每个镜像源目录下有一个config.repo 文件,用于写在 /etc/yum.repos.d/ 下面的,只是需要修改一下里面的地址
  4. 对于多个镜像源使用多个文件的话,使用起来也不方面,下面有一个脚本可以将多个config.repo 合并为一个

    注意: 或许你会去每个目录下find config.repo ,因为rpm包非常多,find的效率会非常低,而使用 */config.repo 将是瞬间完成的

Docker 都依赖哪些东西

下面是docker安装的一个过程:

 

Centos6上单个多个进程listen同一个端口的问题

原来有文章提到过,Centos7上多个进程可以同时listen同一个端口,起到负载均衡的效果,也方便实现服务的无缝升级; 但是Centos6上多个进程同时listen同一个端口的情况怎么理解呢?

首先,这事儿并不新鲜,正常情况下php-fpm的每个子进程都在listen中父进程集成下来的9000端口的,这个并不冲突;但是下图有显示ssh和fpm同时listen 9000端口:

何故?会有问题吗?

进程说明: web server通过fpm提供了一个命令执行的功能,通过shell_exec()执行的,命令执行的是一个ssh命令,执行时间比较长;该ssh进程继承了父进程的文件描述符 *:9000 就被listen了,显然,该ssh进程其实是不会去accept该 *:9000 端口的,所以正常请求不会被ssh意外处理的。

似乎没啥问题,但是确实有问题:

fpm master派生新的子进程后,新的子进程不能正常accept该文件描述符,strace跟踪部分输出如下:

我们发现,fpm子进程accept(0,…) 报“资源临时不可用”,然后直接退出,然后fpm-master继续派生新的子进程,然后再退出,迅速重复该过程,结果:

  1. 机器负载飙升
  2. fpm-master几乎无法立即给每个退出的子进程收尸,于是出现大量fpm子进程处于 僵尸状态

问题:

  1. web shell曾经也做过,为啥没见过这个问题?
  2. 为啥会出现这种情况?

 

附:

服务器版本信息:

C语言中的可变参数

参考: http://www.tutorialspoint.com/c_standard_library/c_macro_va_start.htm  (这的代码可以执行的哦)

 

指南站: http://www.tutorialspoint.com