源码解读Linux的limits.conf文件

1. 前言

本文不一定适合比较老版本的Linux,如果只关心使用,请直接看“总结”,本文主要针对CentOS,其它Linux发行版本类似,但细节可能有出入,比如重启服务可能不是用systemctl,而是service等。

当需要调整一个进程可打开的最多文件数或SOCKET连接数等,以CentOS为例,通常的做法是修改文件/etc/security/limits.conf,比如将最多可打开数调整为10万:

# vi /etc/security/limits.conf

* soft nofile 100000

* hard nofile 100000 

读取limit.conf文件的并不是Linux内核,而是一个内核模块PAM,对应的模块文件为:

/usr/lib64/security/pam_limits.so

/usr/lib/security/pam_limits.so 

而/etc/pam.d目录下的配置文件,则由libpam.so读取,实际上所有的模块均由libpam.so加载,可将libpam.so看成是所有PAM模块的框架或容器,而且libpam.so本身也不是内核的组成部分。

多个不同Linux版本上查看,并没有叫libpam.so的文件名,均是libpam.so.0(不清楚是否所有都这样),但是编译Linux-PAM-1.3.1源代码有名为libpam.so软链接,指向libpam.so.0.84.2。

/usr/lib64/libpam.so.0 -> libpam.so.0.83.1

/usr/lib64/libpam.so.0.83.1

/usr/lib64/libpam_misc.so.0.82.0

/usr/lib/libpam.so.0 -> libpam.so.0.83.1

/usr/lib/libpam.so.0.83.1

/usr/lib/libpam_misc.so.0.82.0 

libpam.so会被加载到crond等进程空间(那当然也可以不加载),如果没有加载libpam.so,则limits.conf不会生效。crond等不会主动加载libpam.so,那么是谁让libpam.so进入crond等进程空间的了?(执行“grep libpam /proc/`pidof crond`/maps”可查看libpam是否在crond的进程空间)。

在CentOS,可用service来启动或重启crond,所以跟它应当是相关的,而service实际调用的是systemctl这一系统工具(非Shell脚本,service为老版本使用方式,使用systemctl启动和重启服务,使用方式和service相同)。

# service crond restart

Redirecting to /bin/systemctl restart  crond.service

# file /bin/systemctl    

/bin/systemctl: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV)

# systemctl crond restart # 重启crontab服务进程crond

2. PAM

PAM的全称为“Pluggable Authentication Modules”,即可插入认证模块。最初由太阳微系统公司(Sun Microsystems,已于2009年被甲骨文收购)于1995年在Solaris开发。PAM代码不包含在Linux内核中,并有专门的网站:http://linux-pam.org/,源代码托管在Github上(https://github.com/linux-pam/linux-pam/releases)。

3. pam_limits

pam_limits是PAM其中的一个模块(模块文件名为pam_limits.so),也是程序员接触较多的模型之一,对应的源代码文件为pam_limits.c,代码规模为几百行,加上所有注释和空格有1100多行:

#if !defined(linux) && !defined(__linux)

#warning THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!

#endif

源代码提供autoconf编译,尝试在Linux-3.10上可编译成功:

~/Linux-PAM-1.3.1]$ ./configure --prefix=/usr/local/Linux-PAM-1.3.1

make

4. limits.conf的由来

确定模块pam_limits的配置文件,由宏CONF_FILE决定:

// pam_limits.c

#define CONF_FILE (pl->conf_file != NULL)?pl->conf_file:LIMITS_FILE 

使用的地方:

// pam_limits.c

static int

parse_config_file(pam_handle_t *pamh, const char *uname, uid_t uid, gid_t gid,  int ctrl, struct pam_limit_s *pl)

{

    FILE *fil;

    char buf[LINE_LENGTH];

    /* check for the LIMITS_FILE */

    if (ctrl & PAM_DEBUG_ARG)

        pam_syslog(pamh, LOG_DEBUG, "reading settings from '%s'", CONF_FILE);

    fil = fopen(CONF_FILE, "r"); // 打开配置文件,跟参数“pl”有关系

    if (fil == NULL) {

        pam_syslog (pamh, LOG_WARNING,

    "cannot read settings from %s: %m", CONF_FILE);

        return PAM_SERVICE_ERR;

    }

如果函数parse_config_file的参数“pl”值为NULL,则配置文件名在编译时决定,这种情况下,配置文件名被固定为limits.conf:

# Makefile.am

modules/pam_limits/Makefile.am: -DLIMITS_FILE_DIR=\"$(limits_conf_dir)/*.conf\" \

modules/pam_limits/Makefile.am: -DLIMITS_FILE=\"$(SCONFIGDIR)/limits.conf\"

只是limits.conf所在目录可由编译时决定,也就是看SCONFIGDIR,决定在automake的configure.ac文件:

# co

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值