samba3のtestparmで出る「rlimit_max」を無視する理由

■「testparm」で以下のエラーが出るようになった。
 実際、私一人がユーザなので、「1024」も同時にファイルを開くことは無い。

 rlimit_max: rlimit_max (1024) below minimum Windows limit (16384)

■Samba3.5.6での症状。

$ sudo smbd -V
Version 3.5.6

■以下を参照し、「ulimit -n 16384」を実行しても変わらない。
 「ulimit」は変更不可かつ、廃止予定のようだ。

 sambaの設定
 http://kfujio.blog78.fc2.com/blog-entry-87.html

$ sudo ulimit -n 16384
sudo: ulimit: command not found
# ulimit -n 16384
# ulimit -a | grep "\-n"
open files                      (-n) 1024

# man ulimit | grep "\-n *オープン" | sed s/"  *"/"\n"/g
-n
オープンできるファイル・ディスクリプターの最大数
(ほとんどのシステムでは、この値を設定することはできません)
# man 3 ulimit | grep -A 1 "準"
準
       SVr4, POSIX.1-2001.  POSIX.1-2008ulimit() を廃止予定としている。

■WindowsXPで以下を実行。「16384」の根拠はこれか。。。

> net config server | find "オープン"
各セッションのオープン ファイルの最大数     16384

■ちなみに「16*1024」の値。。。

$ echo "16 1024" | awk '{print $1*$2}'
16384

■Linuxのオープンファイル数の確認

$  cat /proc/sys/fs/file-nr | \
   awk '{print "過去オープン最大数:\t\t"$1"\n現在のオープン数:\t\t"$2"\nオープン可能なファイル数:\t"$3}'
過去オープン最大数:             1600
現在のオープン数:               0
オープン可能なファイル数:       198463

$ cat /proc/sys/fs/file-max
198463

■上記はsysctlに紐付く。

# sysctl -a 2>&1 | grep file
fs.file-nr = 1664       0       198463
fs.file-max = 198463

■samba3のtestparmについて
 以下のように「testparm.samba3」にシンボリックリンクされている。

$ whereis testparm
testparm: /usr/bin/testparm.samba3 /usr/bin/testparm /usr/share/man/man1/testparm.1.gz

$ ls -l /usr/bin/testparm
lrwxrwxrwx 1 root root 26 2012-06-17 13:04 /usr/bin/testparm -> /etc/alternatives/testparm

$ ls -l /etc/alternatives/testparm
lrwxrwxrwx 1 root root 24 2012-06-17 13:04 /etc/alternatives/testparm -> /usr/bin/testparm.samba3

■以下のように強引に検索してみる。
 方針はどちらも間違っていないようだ。

$ sudo strings /usr/bin/testparm.samba3 | grep -i rlimit
setrlimit64
getrlimit64
rlimit_max: rlimit_max (%d) below minimum Windows limit (%d)
set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s
set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s
set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s
set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s

■sambaにもオープンファイルの最大値は設定可能だが、変化なし。

$ man smb.conf | grep -A 9 "max open files .*G"
       max open files (G)

           This parameter limits the maximum number of open files that one
           smbd(8) file serving process may have open for a client at any one
           time. The This parameter can be set very high (16404) as Samba uses
           only one bit per unopened file. Setting this parameter lower than
           16404 will cause Samba to complain and set this value back to the
           minimum of 16404, as Windows 7 depends on this number of open file
           handles being available.

$ sudo testparm -v -s 2>&1 | grep max | grep 16384
rlimit_max: rlimit_max (1024) below minimum Windows limit (16384)
        max open files = 16384

■以下を参照し、「/etc/security/limits.conf」に
 「* - nofile 16384」を追加しても改善しない。
 soft/hardを指定せず、「open files」に最大値を設定するのだが、
 sysctlにもulimitにも影響しない。

 Setting up SMB on Ubuntu is pretty easy
 http://www.jfamiglietti.com/john/?p=142

$ grep open /etc/security/limits.conf
#        - nofile - max number of open files
$ grep "\<type" /etc/security/limits.conf  |head -1
#<domain>        <type>  <item>  <value>

■デバッグの確認
 別のコマンドを取得するだけのようなのでパス。

$ apt-file search testparm | grep bin
samba-common-bin: /usr/bin/testparm.samba3
samba-common-bin: /usr/share/man/man1/testparm.samba3.1.gz
samba-dbg: /usr/lib/debug/usr/bin/testparm.samba3

$ apt-file show samba-dbg
gadmin-samba-dbg: /usr/lib/debug/usr/sbin/gadmin-samba
gadmin-samba-dbg: /usr/share/doc/gadmin-samba-dbg/changelog.Debian.gz
gadmin-samba-dbg: /usr/share/doc/gadmin-samba-dbg/changelog.gz
gadmin-samba-dbg: /usr/share/doc/gadmin-samba-dbg/copyright
samba-dbg: /usr/lib/debug/lib/libnss_winbind.so.2
samba-dbg: /usr/lib/debug/lib/libnss_wins.so.2
samba-dbg: /usr/lib/debug/lib/security/pam_winbind.so
samba-dbg: /usr/lib/debug/usr/bin/eventlogadm
samba-dbg: /usr/lib/debug/usr/bin/net.samba3
samba-dbg: /usr/lib/debug/usr/bin/nmblookup.samba3
samba-dbg: /usr/lib/debug/usr/bin/ntlm_auth
samba-dbg: /usr/lib/debug/usr/bin/pdbedit
samba-dbg: /usr/lib/debug/usr/bin/profiles
samba-dbg: /usr/lib/debug/usr/bin/rpcclient
samba-dbg: /usr/lib/debug/usr/bin/smbcacls
samba-dbg: /usr/lib/debug/usr/bin/smbclient
samba-dbg: /usr/lib/debug/usr/bin/smbcontrol
samba-dbg: /usr/lib/debug/usr/bin/smbcquotas
samba-dbg: /usr/lib/debug/usr/bin/smbget
samba-dbg: /usr/lib/debug/usr/bin/smbpasswd
samba-dbg: /usr/lib/debug/usr/bin/smbspool
samba-dbg: /usr/lib/debug/usr/bin/smbstatus.samba3
samba-dbg: /usr/lib/debug/usr/bin/smbtree
samba-dbg: /usr/lib/debug/usr/bin/tdbbackup
samba-dbg: /usr/lib/debug/usr/bin/testparm.samba3
samba-dbg: /usr/lib/debug/usr/bin/wbinfo
samba-dbg: /usr/lib/debug/usr/lib/samba/idmap/ad.so
samba-dbg: /usr/lib/debug/usr/lib/samba/idmap/adex.so
samba-dbg: /usr/lib/debug/usr/lib/samba/idmap/hash.so
samba-dbg: /usr/lib/debug/usr/lib/samba/idmap/ldap.so
samba-dbg: /usr/lib/debug/usr/lib/samba/idmap/rid.so
samba-dbg: /usr/lib/debug/usr/lib/samba/idmap/tdb2.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/acl_tdb.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/acl_xattr.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/audit.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/cap.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/catia.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/default_quota.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/dirsort.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/expand_msdfs.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/extd_audit.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/fake_perms.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/fileid.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/full_audit.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/netatalk.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/preopen.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/readahead.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/readonly.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/recycle.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/scannedonly.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/shadow_copy.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/shadow_copy2.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/smb_traffic_analyzer.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/streams_depot.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/streams_xattr.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/syncops.so
samba-dbg: /usr/lib/debug/usr/lib/samba/vfs/xattr_tdb.so
samba-dbg: /usr/lib/debug/usr/sbin/nmbd
samba-dbg: /usr/lib/debug/usr/sbin/smbd
samba-dbg: /usr/lib/debug/usr/sbin/winbindd
samba-dbg: /usr/share/doc/samba-dbg/NEWS.Debian.gz
samba-dbg: /usr/share/doc/samba-dbg/README.build.gz
samba-dbg: /usr/share/doc/samba-dbg/changelog.Debian.gz
samba-dbg: /usr/share/doc/samba-dbg/copyright

■ソースの取得

$ dpkg -L samba-common-bin | grep testparm
/usr/bin/testparm.samba3
/usr/share/man/man1/testparm.samba3.1.gz

$ mkdir samba-source && cd samba-source
$ sudo apt-get source --download-only samba-common-bin
$ tar ztvf samba_3.5.6~dfsg-3squeeze8.debian.tar.gz | grep testparm
$ tar jttf samba_3.5.6~dfsg.orig.tar.bz2  | grep testparm
-rw-r--r-- bubulle/bubulle   14026 2010-10-08 01:41 samba-3.5.6/source3/utils/testparm.c
-rwxr-xr-x bubulle/bubulle    1822 2010-10-08 01:41 samba-3.5.6/source3/script/tests/test_testparm_s3.sh
-rw-r--r-- bubulle/bubulle    8327 2010-10-08 01:41 samba-3.5.6/source4/utils/testparm.c
-rw-r--r-- bubulle/bubulle    8029 2010-06-18 17:11 samba-3.5.6/docs/manpages/testparm.1
-rw-r--r-- bubulle/bubulle    7079 2010-06-18 17:11 samba-3.5.6/docs/htmldocs/manpages/testparm.1.html
-rw-r--r-- bubulle/bubulle    6898 2010-10-08 01:41 samba-3.5.6/docs-xml/manpages-3/testparm.1.xml
$ tar jxvf samba_3.5.6~dfsg.orig.tar.bz2

$ find . -type f -iname "*.c" -print | grep . `xargs` | grep rlimit
./samba-3.5.6/source4/heimdal/lib/roken/getdtablesize.c:  struct rlimit res;
./samba-3.5.6/source4/heimdal/lib/roken/getdtablesize.c:  if (getrlimit(RLIMIT_NOFILE, &res) == 0)
./samba-3.5.6/source3/lib/fault.c:              struct rlimit rlp;
./samba-3.5.6/source3/lib/fault.c:              getrlimit(RLIMIT_CORE, &rlp);
./samba-3.5.6/source3/lib/fault.c:              setrlimit(RLIMIT_CORE, &rlp);
./samba-3.5.6/source3/lib/fault.c:              getrlimit(RLIMIT_CORE, &rlp);
./samba-3.5.6/source3/lib/util.c:       struct rlimit rlp;
./samba-3.5.6/source3/lib/util.c:       if(getrlimit(RLIMIT_NOFILE, &rlp)) {
./samba-3.5.6/source3/lib/util.c:               DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
./samba-3.5.6/source3/lib/util.c:               if(setrlimit(RLIMIT_NOFILE, &rlp)) {
./samba-3.5.6/source3/lib/util.c:                       DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
./samba-3.5.6/source3/lib/util.c:       if(setrlimit(RLIMIT_NOFILE, &rlp)) {
./samba-3.5.6/source3/lib/util.c:               DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
./samba-3.5.6/source3/lib/util.c:       if(getrlimit(RLIMIT_NOFILE, &rlp)) {
./samba-3.5.6/source3/lib/util.c:               DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
./samba-3.5.6/source3/param/loadparm.c: *  kernel-level (sysctl) and ulimit (getrlimit()) values and goes
./samba-3.5.6/source3/param/loadparm.c: int rlimit_max = MAX_OPEN_FILES;
./samba-3.5.6/source3/param/loadparm.c:         struct rlimit rl;
./samba-3.5.6/source3/param/loadparm.c:         if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
./samba-3.5.6/source3/param/loadparm.c:                 rlimit_max = rl.rlim_cur;
./samba-3.5.6/source3/param/loadparm.c:                 rlimit_max = MAX_OPEN_FILES;
./samba-3.5.6/source3/param/loadparm.c: if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
./samba-3.5.6/source3/param/loadparm.c:         DEBUG(2,("rlimit_max: rlimit_max (%d) below "
./samba-3.5.6/source3/param/loadparm.c:                 rlimit_max,
./samba-3.5.6/source3/param/loadparm.c:         rlimit_max = MIN_OPEN_FILES_WINDOWS;
./samba-3.5.6/source3/param/loadparm.c: return MIN(sysctl_max, rlimit_max);


■sysctlかulimitのどちらか小さい方を取得するとある。。。
 ちなみに、「『10,000』にしたいけど、多くのOS(Linux)がサポートしてないから。」という前提らしい。

   /* This failing is not an error - many systems (Linux) don’t
       support our default request of 10,000 open files. JRA. */

 実際、ulimitの1024を取得している。そしてこれは変えられない。。。
 手詰まり。
 「最大値をより小さな方を取得する」ことや、「変更不可な値を参照する」のって仕様としてどうなのだろう。。。
 ということで無視することにした。
 一応sysctl側を参照するならば、設定は可能なのだが。。。

$ grep -A 4 -B 6 "static int max_open_files" ./samba-3.5.6/source3/param/loadparm.c
/**
 *  Function to return the default value for the maximum number of open
 *  file descriptors permitted.  This function tries to consult the
 *  kernel-level (sysctl) and ulimit (getrlimit()) values and goes
 *  the smaller of those.
 */
static int max_open_files(void)
{
        int sysctl_max = MAX_OPEN_FILES;
        int rlimit_max = MAX_OPEN_FILES;

$ sudo sysctl -a 2>&1 | grep "file-max ="
fs.file-max = 198463
sudo sysctl -w "fs.file-max=16384"
fs.file-max = 16384
$ sudo sysctl -a 2>&1 | grep "open ="
fs.nr_open = 16384
$ su root -c 'ulimit -a' | grep open
パスワード:
open files                      (-n) 1024

$ sudo testparm -s 2>&1 | grep rlimit
rlimit_max: rlimit_max (1024) below minimum Windows limit (16384)