1. 程式人生 > >系統技術非業餘研究 » ulimit限制之nproc問題

系統技術非業餘研究 » ulimit限制之nproc問題

前兩天微博上的@王關勝同學問了個問題:

#ulimit問題# 關於nproc設定:centos6,核心版本是2.6.32. 預設情況下,ulimit -u的值為1024,是/etc/security/limits.d/90-nproc.conf的值限制;註釋掉這個限制後,值為95044;手工設定90-nproc.conf檔案,值為新設定的值。想請 問這個95044是怎麼來的?

這個問題挺有意思的,這裡面有二個資訊點:

1. 為什麼limit配置檔案是 /etc/security/limits.d/90-nproc.conf 而不是其他?
2. 為什麼是nproc的值95044,而不是其他。

之前我也寫了些ulimit的問題的解決,參見

這裡

我們來簡單的做下實驗:

$ cat /etc/security/limits.d/90-nproc.conf          
*      soft    nproc   8933
$ ulimit -u
8933

$ cat /etc/security/limits.d/90-nproc.conf      #註釋掉
#*      soft    nproc   8933
$ ulimit -u
385962

我們可以看出就是說當註釋掉限制的話,不同的機器值是不同的。

我們先來回答第一個問題:為什麼limit配置檔案是 /etc/security/limits.d/90-nproc.conf 而不是其他
這個問題早些時候 楊德華 同學碰到了,也寫了篇

博文 來解釋redhat6下面如何破解nproc的限制,但是文章沒提到這個問題。

我們一步步來看這個問題,首先看下 誰在使用 90-nproc.conf 這個檔案:

$ cat t.stp
probe syscall.open.return {
  filename = user_string($filename)
  if (!isinstr(filename, "90-nproc.conf")) next;
  printf("%s %d\n", execname(), pid());
}
$ sudo stap t.stp
sshd 24844

執行指令碼後,開個ssh終端上去,就馬上知道sshd在使用這個檔案, 同時也驗證了配置是即刻生效的。

我們都知道linux下這個limit限制是由pam_limits來執行的。
那麼什麼是PAM以及它的架構,參考 這裡

$ grep -rin pam_limit /etc/pam.d
/etc/pam.d/sudo-i:6:session    required     pam_limits.so
/etc/pam.d/smartcard-auth-ac:16:session     required      pam_limits.so
/etc/pam.d/smartcard-auth:16:session     required      pam_limits.so
/etc/pam.d/system-auth-ac:20:session     required      pam_limits.so
/etc/pam.d/fingerprint-auth:16:session     required      pam_limits.so
/etc/pam.d/sudo:6:session    required     pam_limits.so
/etc/pam.d/runuser:4:session            required        pam_limits.so
/etc/pam.d/password-auth-ac:19:session     required      pam_limits.so
/etc/pam.d/password-auth:19:session     required      pam_limits.so
/etc/pam.d/system-auth:20:session     required      pam_limits.so
/etc/pam.d/fingerprint-auth-ac:16:session     required      pam_limits.so

那很自然,我們就會去找pam_limits的程式碼來看, 程式碼在 這裡 可以下載,目前的版本是 Linux-PAM-1.1.6。

瞄幾下modules/pam_limits/pam_limits.c就知道 限制如何執行的:

/* now the session stuff */
PAM_EXTERN int
pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
                     int argc, const char **argv)
{
[...]
   retval = init_limits(pamh, pl, ctrl);
    if (retval != PAM_SUCCESS) {
        pam_syslog(pamh, LOG_WARNING, "cannot initialize");
        return PAM_ABORT;
    } 

    retval = parse_config_file(pamh, pwd->pw_name, pwd->pw_uid, pwd->pw_gid, ctrl, pl);
    if (retval == PAM_IGNORE) {
        D(("the configuration file ('%s') has an applicable '<domain> -' entry", CONF_FILE));
        return PAM_SUCCESS;
    }
    if (retval != PAM_SUCCESS || pl->conf_file != NULL)
        /* skip reading limits.d if config file explicitely specified */
        goto out;

    /* Read subsequent *.conf files, if they exist. */

    /* set the LC_COLLATE so the sorting order doesn't depend                                                             
        on system locale */

    oldlocale = setlocale(LC_COLLATE, "C");
    glob_rc = glob(LIMITS_CONF_GLOB, GLOB_ERR, NULL, &globbuf);

    if (oldlocale != NULL)
        setlocale (LC_COLLATE, oldlocale);

    if (!glob_rc) {
        /* Parse the *.conf files. */
        for (i = 0; globbuf.gl_pathv[i] != NULL; i++) {
            pl->conf_file = globbuf.gl_pathv[i];
            retval = parse_config_file(pamh, pwd->pw_name, pwd->pw_uid, pwd->pw_gid, ctrl, pl);
          if (retval == PAM_IGNORE) {
                D(("the configuration file ('%s') has an applicable '<domain> -' entry", pl->conf_file));
                globfree(&globbuf);
                return PAM_SUCCESS;
            }
            if (retval != PAM_SUCCESS)
                goto out;
        }
    }

out:
[...]
}

分析這段程式碼可以知道先讀/etc/security/limits.conf,如果/etc/security/limits.d/目錄下還有配置檔案的話,也讀進來,一起分析。
這就意味/etc/security/limits.d/裡面的檔案裡面的配置會覆蓋/etc/security/limits.conf的配置。

我們看下這行:glob_rc = glob(LIMITS_CONF_GLOB, GLOB_ERR, NULL, &globbuf);
讀取/etc/security/limits.d/目錄下檔案的函式,從名字就可以猜出,是遍歷,檔名的數字起到順序的作用。

到此就解釋了檔名90-nproc.conf的作用。

接著看第二個問題: 為什麼是nproc的值95044, 而不是其他。
通過閱讀process_limit函式只是看到 nproc的最大值限制,沒有看到其他的,那我們就很容易聯想,如果使用者不設定nproc的話,那麼這個值應該是由核心自己來決定。

我們看下核心程式碼 2.6.18:

$ pwd
/home/chuba/linux-2.6.18.x86_64/kernel
$ grep -rin nproc .
./sys.c:896:                            current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
./fork.c:176:   init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
./fork.c:177:   init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
./fork.c:179:           init_task.signal->rlim[RLIMIT_NPROC];
./fork.c:1130:                  p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
./cpuset.c:69:  int cnt;                /* unprocessed events count */
./cpuset.c:1140: * Limit the count of unprocessed events to FM_MAXCNT, so as to avoid
./user.c:181:    * new uid over his NPROC rlimit?  We can check this now

一下子就看出來了 預設值是 max_threads/2. 開啟fork.c分析下:

//fork_init(num_physpages);
//void __init fork_init(unsigned long mempages)
/*
* The default maximum number of threads is set to a safe
* value: the thread structures can take up at most half
* of memory.
*/
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);

其中mempages是機器的物理頁面個數, THREAD_SIZE=8K, 也就是說:

default_nproc = max_threads / 2 = (mempages * PAGE_SIZE) / ( 2 * 8 *THREAD_SIZE ) = total_memory/128K;

我們來驗證下:

$ cat /proc/meminfo |grep MemTotal
MemTotal:       49421024 kB
$ echo "49421024 / 128"| bc  
386101
$ ulimit -u
385962

算出來default_nproc =386101 是不是和實際的很接近?
因為物理頁面會記憶體用作一些關鍵資料,所以實際的比計算出來的要小點。

小結: 原始碼說話!

祝玩的開心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

相關推薦

系統技術業餘研究 » ulimit限制nproc問題

前兩天微博上的@王關勝同學問了個問題: #ulimit問題# 關於nproc設定:centos6,核心版本是2.6.32. 預設情況下,ulimit -u的值為1024,是/etc/security/limits.d/90-nproc.conf的值限制;註釋掉這個限制後,值為95044;手工設定

系統技術業餘研究 » ulimit

今天在核心群裡印風同學問了個問題: 某臺機器的ulimit -t 不知道為啥是300, 這是不是意味著程式佔用CPU 300秒後會收到SIGKILL ? 我用gdb跑mysqld 跑了一會,收到SIGKILL訊號,沒有配置cgroup,也沒啥後臺指令碼,看了下,就ulimit -t 比較詭異,其他

系統技術業餘研究 » 瞭解系列

您好!我看了您寫的瞭解CPU和了解記憶體,但是發現兩者在cpu訪問快取的速度上資料不一致,瞭解記憶體裡面您的資料二級快取的時間大概是一級快取的10倍了,但是瞭解CPU裡面只有3倍的樣子。我記得之前在微博裡面見你們討論過,好像應該是3倍左右才對。然後我在i7的機器上實測了一下,大概是4倍 Rep

系統技術業餘研究 » Erlang如何限制節點對叢集的訪問net_kernel:allow

預設情況下Erlang的叢集訪問是全授權的,只要cookie認證過了後,新加入的節點可以訪問叢集裡面的任何機器,這給運維帶來很大風險。目前erlang有二種方法可以限制 1. IP網段限制,參看這裡 2. 節點名稱限制。這個是通過net_kernel:allow來實現的,參看: allow/1 L

系統技術業餘研究 » 老生常談: ulimit問題及其影響

ulimit最初設計是用來限制程序對資源的使用情況的,因為早期的系統系統資源包括記憶體,CPU都是非常有限的,系統要保持公平,就要限制大家的使用,以達到一個相對公平的環境。以下是典型的機器預設的限制情況: $ ulimit -a core file size (blocks,

系統技術業餘研究 » 突破systemtap指令碼對資源使用的限制

我們在使用指令碼收集系統資訊的時候經常會用到map這樣的資料結構存放結果,但是stap指令碼在使用過程中經常會提升說”ERROR: Array overflow, check MAXMAPENTRIES near identifier ‘a’ at test.stp:6:5″ 類似這樣的資訊,然後

系統技術業餘研究 » 很容易忽略的ETS表個數限制問題

最近經常碰到ets表使用的數目超過系統的限制導致Erlang應用異常的案例。 比如說神鋒同學報告說在ssh模組裡面,最多隻能開啟500個左右連結,系統空閒的很,但是無法繼續加大連結。 浩庭同學報告說mnesia的事務只能開1千多,多了就上不去了。這些問題看起來沒有關聯。但是其實和ets都有很大的關

系統技術業餘研究 » dets在64位系統還是有可恥的2G限制

原本以為在 64位作業系統下 檔案的讀寫指標都改成64位的 避免了2G的限制。經過測試 disk_log和file都支援超過2G的資料檔案,但是 dets還是可恥的失敗了。 經過檢視原始碼 有2個問題: 1. key segment的問題。 dets在設計的時候 是針對32位的 那麼它的空間限

系統技術業餘研究 » Erlang叢集未公開特性:IP網段限制

Erlang叢集二個節點之間的通訊是通過一個tcp長連線進行的,而且是全聯通的,一旦cookie論證通過了,任何一個節點就獲得全叢集的訪問權,可以參考Erlang分佈的核心技術淺析 。erlang的這個授權模式特定搞的這麼簡單,但是在實際使用中還是有安全性的問題。我們退而求其次,來個IP網段限制,

系統技術業餘研究 » gen_tcp如何限制封包大小

我們在做tcp伺服器的時候,通常會從安全考慮,限制封包的大小,預防被無端攻擊或者避免極端的請求對業務造成損害。 我們的tcp伺服器通常是erlang做的,那麼就涉及到gen_tcp如何限制封包的大小. gen_tcp對封包的獲取有2種方式: 1. {active, false} 封包透過gen_

系統技術業餘研究

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼

系統技術業餘研究 » MySQL資料庫架構的演化觀察

MySQL資料庫架構的演化觀察 December 14th, 2017 Categories: 資料庫 Tags: mysql

系統技術業餘研究 » inet_dist_connect_options

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 推薦工作機會

最後更新時間:2014/11/28 請賜簡歷至:[email protected], 感謝您對加入我們公司有興趣,我們希望能早日和您共事。 以下幾個職位1年內有效,歡迎內部轉崗:
 資深資料工程師 公司:阿里(核心系統資料庫組) 工作地點:杭州(西溪園區) 崗位描述: 分析雲服務產生的海

系統技術業餘研究 » 新的工作和研究方向

和大家更新下: 做了將近8年資料庫後,我的工作和研究方向將會延伸到虛擬化和計算相關的雲服務,希望能夠和大家一起進步,Happy New Year! 預祝大家玩得開心! Post Footer automatically generated by wp-posturl plugin for w

系統技術業餘研究 » 叢集引入inet_dist_{listen,connect}_options更精細引數微調

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 2017升的最快的幾個資料庫無責任點評

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼

系統技術業餘研究 » Erlang 17.5引入+hpds命令列控制程序預設字典大小

Erlang 17.5釋出引入控制程序預設字典大小的命令列引數: Erlang/OTP 17.5 has been released Written by Henrik, 01 Apr 2015 Some highlights of the release are: ERTS: Added co

系統技術業餘研究 » inet_dist_listen_options

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 求賢帖

原創文章,轉載請註明: 轉載自系統技術非業餘研究 本文連結地址: 求賢帖 作為一個優秀的工程師,你其實不缺少才華,你缺少的是神一樣的隊友、充滿挑戰的世界級技術難題,和一個可以施展自己才華的大舞臺。加入阿里核心系統資料庫開發團隊吧,你缺的這裡都有。來吧,戳這裡,給我們見識你的機會:http://b