Tag Archives: Linux

经典错误——使用/etc/security/limits.conf配置文件 和 ulimit -n命令

很多以讹传讹的半桶水文章,都教人修改/etc/security/limits.conf配置文件来放宽“打开的文件数量”限制,如果可以再多一滴水的话,还会加一句“重启后生效”。 其实,使用这个配置文件,和使用ulimit -n命令一样,属于很经典的错误。 设置或放宽“打开的文件数量“限制,其本质是调用了setrlimit()函数,设置了RLIMIT_NOFILE资源。在有特权的程序中调用这个函数,可以提高上限(放宽限制),而普通权限的程序只能自己勒死自己和新生的子进程。 而/etc/security/limits.conf这个配置文件是怎么生效的呢?其实用dpkg -S或rpm -qf查一下就很容易知道,这个文件是pam_limits.so的配置文件,而pam_limits.so是在/etc/pam.d/中被login和sshd等多个配置文件声明将要被调用的。 系统开机的时候,1号进程init“自然而然”是root身份运行,其下属的getty/login和sshd进程,也都是root身份。这些程序都可以随意调用setrlimit。当身份认证(部分工作由PAM来做,所以可以读shadow文件)完成之后,login和sshd的子进程会为用户准备好session(网络登录调用pam_mkhomdir建设HOME目录、pam_limits模块设置rlimit、pam_env模块读取/etc/environment设置环境变量,甚至显示motd这种功能也是PAM模块实现的)并将自己降级到登录的用户身份,再启动一个shell给用户使用。 /etc/security/limits.conf 只对“调用过pam_limits.so“的登录过程有效。但并不是所有场景都经过这个过程的。而ulimit命令呢,它本身只是shell是一个内部命令而已,只对“该shell进程”及随后新产生的子进程有效。 但是需要放宽rlimit的程序,往往不是在shell中由用户手工运行的程序,而是提供大规模网络服务的后台进程。它们所需的rlimit,要在init脚本、service unit文件中设置;支持从root身份启动的服务,一般都有自行设置rlimit的能力。 如果不理解上面的内容,就容易引发一些莫名其妙的故障。比如之前我在FreeWheel工作的时候,前辈为后台服务写的的init脚本里没有调用ulimit -n命令,而在root用户的~/.bash_profile里有这个命令。造成的后果,就是开机自动启动该服务的时候,启动的是一个打开文件数量受限,以至于无法保持很多socket的网络服务,而当运维人员登录进去手工重启服务之后,又莫名其妙变好了,以至于没法检查这个故障到底是怎么发生的。

Posted in 默认分类 | Tagged , | Leave a comment

在嵌入式开发板上使用蓝牙耳机

简单记录一下: 安装 bluez pulseaudio-module-bluetooth 软件包 pulseaudio是用户级后台服务,视情况可能需要手工-D启动之 bluetoothctl命令进入交互式界面,先scan on 等看到蓝牙耳机之后,pair和connect到蓝牙耳机的MAC地址,看到连接成功之后scan off并退出bluetoothctl pactl list sinks查看设备,看看它支持哪些profile,有可能需要通过pactl set-card-profile将其切换到a2dp aplay -Dpulse 指定pulse虚拟设备播放文件 还没搞定录音。看起来话务耳机在handfree等模式似乎需要特殊步骤激活录音模式?

Posted in 默认分类 | Tagged , | Comments Off on 在嵌入式开发板上使用蓝牙耳机

hostname和dnsdomainname命令

先讲结论: 忽略已经过时的NIS/YP相关内容(/sbin/sysctl kernel.domainname、/bin/domainname、/bin/nisdomainname、/bin/ypdomainname等) /bin/hostname、/sbin/sysctl kernel.hostname 和 /bin/uname -n 是一码事,都是本机的主机名 /bin/dnsdomainname 命令会把上述主机名按“第一个点”分成两端,输出后一段。这是简单的字符串处理的结果,在内核和DNS层面均无正式意义。 /etc/resolv.conf文件里的search或domain指令,用于从本机访问外部短主机名时,补充域名的后缀部分。   hostname命令: 通过gethostname(2)函数读到本机的主机名。在glibc的情况下,gethostname(2)不是syscall而是标准库函数,转而调用uname(2) (我不太确认调用的是glibc uname还是syscall uname)。根据 https://github.com/torvalds/linux/blob/master/Documentation/sysctl/kernel.txt#L285 的说法,/proc/sys/kernel/hostname、sysctl hostname 和hostname命令应该是功能相同的。 hostname -d 或者 dnsdomainname 命令: 根据/etc/host.conf指定的顺序,先尝试/etc/hosts然后尝试DNS,查找自己的主机名。如果能找到,把第一段去掉之后,输出剩下的部分。这个输出不具备内核意义,只是主机名经过字符串处理之后的派生结果 hostname –fqdn命令: getaddrinfo()函数查询到的ai_canonname strace观察到的行为是去DNS查一下主机名(如果主机名是短形式,按需补充/etc/resolv.conf里声明的search/domain后缀)对应的A记录,只要能查到,即使返回的IP地址不是本机的也不管,就以这个主机名作为结果。 hostname –all-fqdn命令: 拿自己的IP地址们循环调用getnameinfo()函数(strace/tcpdump观察到的具体行为是去DNS查PTR记录),并全部输出

Posted in 默认分类 | Tagged , | Leave a comment

墨菲定律之多处保存必然会出现不一致——谈Linux上的时区问题

技术部的工作日报,原本是早晨9点发,脚本换了一台服务器运行之后变成17点了。算算时差也知道是时区问题。 检查了一下, /etc/timezone 内容误为 Etc/UTC,而 /etc/localtime 是从 /usr/share/zoneinfo/Asia/Shanghai 复制过来的,二者不一致。date命令使用 /etc/localtime 而 cron 按 /etc/timezone 文件执行,于是造成了执行时间不对的问题 另外需要注意的是,cron 只在开始运行时读取一次该文件,而每分钟唤醒时不再读取,所以改过文件之后还得重启该服务;又得注意的是,service cron stop 似乎并不会终止cron进程,所以……你懂的 以上就是墨菲定律之:多处保存,必然会出现不一致

Posted in 默认分类 | Tagged , | Leave a comment

不能念叨啊,一念叨就出事——兼谈xen的network-bridge脚本问题

昨晚还说呢,如果今天一天没事,这周就算安全过去了,@sgub 和@chifeng 都告诫我说不能念叨这事,今天果然! 下午,同事远程关闭错了机器。重新开机之后,发现 xenbr0 网桥没有了。看了一下,是 /etc/xen/scripts/network-bridge 没成功运行造成的。这个脚本用默认路由所在的网卡做一个网桥,然后把虚拟机接在这个网桥上,以便使虚拟机能直接上网。但我们的服务器却有俩公网IP和俩默认路由,就把那个脚本搞糊涂了。 其实这俩默认路由是路由器上的同一个接口的两个 IP 地址,连 MAC 都一样的。我删除掉其中一个默认路由,再运行network-bridge 脚本,就成功了。

Posted in 默认分类 | Tagged , , , | Leave a comment

其实SYSOP手段也不是万能的,今天被迫动了一下dnsmasq的源码

今天发现电信通拦截DNS请求,把热门流量导向其内部 squid 缓存服务器。今天主要发现有两个,一个是新浪微博的 css 文件所在的域名 timg.sjs.sinajs.cn 被指向了 124.207.162.88 ,另一个是……查看某个视频的时候,浏览器状态栏提示从 124.207.162.83 下载数据,跟新浪微博被拦截的域名指向同一个 IP 段。但是页面里并没有写是从哪个域名下载视频的。于是乎,我想从公司网关的 dnsmasq 上取得数据,却意外的发现 –log-queries 参数无效,开启该参数后,按文档说明发 USR1 信号给 dnsmasq ,syslog 里却没看到 cache dump。 找了一台 Debian 看了看,是可以的。于是我立即习惯性的阴暗的认为是 RedHat 的软件质量问题。找了一套原装正品源码,编译后发现行为也是一样的。无奈了,SYSOP 手段也不是万能的,只好开始看源码。 源码里搜索 log-queries 找到 getopt 这个步骤,找到其内部名字 OPT_LOG。然后在源码文件里找这个,发现了 cache.c 文件里的 cache_dump 函数中,关于 … Continue reading

Posted in 默认分类 | Tagged , , , , | 3 Comments

有人忘记在 ifcfg 里写 NETMASK 了,结果……

我的好兄弟、大学同学谢某人,在虚拟机里玩 RHEL+Oracle 的时候,遇到一个诡异的事情,就是 RHEL 开机后 IP 地址会自动变化。我原以为是他装 Oracle 的时候某个开机自动执行的命令更改了地址,所以就在开机的各 rc 脚本之间夹带执行一次 ifconfig 命令,发现在开机过程中 IP 地址始终都是没有变化的。持续 ping 该机器,发现在出现登录提示符后才 ping 不通,并且提示符后还出现了 iscsi-initiator 关于断开和 target 的网络连接的错误提示信息。 没办法,看日志吧。/var/log/messages 日志明明白白的写着:NetworkManger 认为长度为零的 IP prefix 是无效的,因此接管了该网卡,并按 Auto eth0 设置了该网卡。看了看 ifcfg 文件,里面果然是没写掩码。此时谢同学不服气的嚷嚷,说另一个虚拟机也是这么写的,就不会自动变 IP。过去看了一下,发现那边没启动 NetworkManager 服务。哈哈…… 不过有个问题,ifconfig 命令对于不带掩码的 IP … Continue reading

Posted in 默认分类 | Tagged , , , , | Leave a comment

用 SYSOP 风格的方法研究 spawn-fcgi

不怕大家笑话,以前我一直不明白为啥会有 spawn-fcgi 这个东西。因为以前都是用 PHP 啊,PHP 本身就是可以并发处理多个请求的 fastcgi server 啊,要 spawn-fcgi 干啥用呢?更有意思的是有人用 spawn-fcgi 启动多个 php-cgi ,然后这个 php-cgi 再启动多个子进程,不知道有什么好处。 前几天,我读了一下代码,还是没太明白这个东西存在的必要性,于是就用我们 SYSOP 的方法研究了一下 spawn-fcgi: fakefcgi.sh脚本文件 #!/bin/sh ls -l /proc/self/fd/ >/var/log/$$.txt sleep 600s 执行 spawn-fcgi -p 3333 -F 5 — ./fakefcgi.sh 得到结果 spawn-fcgi: child … Continue reading

Posted in 默认分类 | Tagged , , | 1 Comment

RHEL6 作为 xen domU 虚拟机,启用 hvc0 的方法

今天在 xen  虚拟机里安装了 RHEL6 beta,发现因为 sysvinit 被换成 upstart 之后,竟然不知道在哪里启用 hvc0 上的 getty 了。尝试改变 /etc/sysconfig/init 把 hvc0加到 ACTIVE_CONSOLES 里,但是开机时提示 hvc0 permission denied 之类的提示信息。 最后还是在内核上加 console= 参数了。不过注意:必须写成 console=tty console=hvc0 这样,其中 tty 那一项可以用 console=tty 也可以用 console=tty1。 如果只加console=hvc0 则用VNC查看虚拟机的时候看不到开机时的 dmesg 和服务脚本启动信息 如果顺序反了,最后不会启动 agetty 在 … Continue reading

Posted in 默认分类 | Tagged , , , | 4 Comments

bind + mydns 大容量智能 DNS 的方案简述

大体上就是 bind 上启用 view 功能,然后把请求转发给后端的多个 mydns。不过遇到的问题是,如果用 zone {type “forward”;} 的话,会导致  bind 给出的解析结果里缺少 AA 标志位,而且还会带上 ADDITIONAL SECTION,而这个 ADDITIONAL SECTION 指向的恰恰是 bind 自己,于是有时会造成循环。 怎么让 bind 认同自己事实上的权威地位,成了方案的关键。想了几个小时,终于明白了只有 master 和 slave 才能给出带 AA 标志位的应答。master试过了肯定是不行的,因为必须有 file 参数。后来试了试 slave,竟然只需要 masters 参数即可。 最终方案是两横两纵的: 1 一个域有两个 NS 服务器 … Continue reading

Posted in 默认分类 | Tagged , , , , , | 2 Comments