-->

2011-05-16

nfsのマウントは成功するがflockが失敗する

nfs-utils-1.2はそのままにした。バージョンを下げない。
カーネルの設定をnfs4のサーバーが使えるように変えた。
/etc/exportsの設定をnfs4になるように変えた。

追記: /etc/exportsではなく/etc/fstab。(もしくは手動の場合 mount -t nfs4 ...)
/etc/exportsのfsid=0はmountする際に便利になるnfs4の機能。
http://www.turbolinux.com/products/server/11s/user_guide/nfspseudofs.html

参考URL。
http://www.gentoo.gr.jp/jpmain/tips.xml
http://murasakimania.dip.jp/wordpress/?p=76
http://linuxjf.sourceforge.jp/
http://linuxjf.sourceforge.jp/JFdocs/JFhtml.tar.bz2
http://forums.gentoo.org/viewtopic.php?t=77748
http://www.turbolinux.com/support/document/knowledge/632.html
http://oshiete.goo.ne.jp/qa/4954031.html
http://linux.kororo.jp/cont/server/nfs.php
http://www.asahi-net.or.jp/~aa4t-nngk/nfsv4.html
http://www.turbolinux.com/products/server/11s/user_guide/nfspseudofs.html



下記は詳細です。

原因はnfs3でマウントしているがrpc.lockdが無い。
nfs4ではrpc.lockdは必要なくなったらしくnfs-utils-1.2.3-r1には無い。
nfs-utils-1.0系にはあるようだがパッケージのバージョンにはない。1.1.4-r1が一番古い。
nfsサーバー側でmake oldconfigで設定を更新していたせいでnfs4のサーバーの機能が無効だった。
マウントの設定もnfs4になるようになっていなかった。

対応としてはnfs4にした。
nfsサーバー側のカーネルの設定にnfs4のサーバーを入れた。マウントの設定を変更した。

結果としてnfs経由でemerge xxxでソフトの再インストールに成功した。そのソフトも動作した。
テストはwget,phpとphpの関連パッケージで行った。apacheの再起動後でもphpは使えた。
nfs3のままマウント時に-o nolockの追加で問題ないかもしれない。カーネルのコンパイルでは大丈夫だった。
(/usr/src/linux/でmake vmlinuxなどを行う。出来上がったバイナリで起動できた。)
(成功するのはnfsサーバーがpentium4でnfsクライアントがphenomで同じx86系のため。)



作業の例。
nfsサーバー側がnfs3サーバー対応のカーネルで、nfsクライアント側はnfs3,nfs4クライアント機能対応のカーネルで、それぞれにツールをインストールしnfs3でマウント後にflockできないのでrpc.lockdを起動しようとしたところ、マニュアルは存在するがコマンドはないという状況になり、ツールがnfs4向けと判断したのでnfs4サーバーの機能をnfsサーバー側に追加しflockを含めた動作テストまで行う。

nfsサーバーにnfsのツールをインストールする。
$ sudo emerge --oneshot -avt nfs-utils

nfsサーバー設定。(nfs4になっていない)
$ rcsdiff -r1.1 exports,v /etc/exports
===================================================================
RCS file: exports,v
retrieving revision 1.1
diff -r1.1 /etc/exports
1a2,3
>
> / 192.168.0.100/255.255.255.255(rw,sync,no_root_squash)

nfsサーバーを起動する。
$ sudo /etc/init.d/nfs start
$ sudo rc-update add nfs default

nfsクライアントにnfsのツールをインストールする。
$ sudo emerge --oneshot -avt nfs-utils
$ sudo /etc/init.d/rpc.statd start など

nfsサーバーにchrootする。
$ sudo mount -t nfs 192.168.0.200:/ /mnt/cogentoo-1/
$ cd /mnt/cogentoo-1/
$ sudo chroot . /bin/bash
$ ll /proc/
合計 0
$ source /etc/profile
$ export PS1="(chroot.nfs.cogentoo-1) $PS1"

/procをmountするため終了する。
$ emerge --oneshot -avt wget
!!! It seems that /proc is not mounted. You have been warned.
emergelog(): [Errno 9] Bad file descriptor
emergelog(): [Errno 9] Bad file descriptor

These are the packages that would be merged, in reverse order:
...
^C <= 止めた。
$ exit

/procをmountする。
$ sudo mount -t proc none proc/

再度chrootする。
$ sudo chroot . /bin/bash
$ source /etc/profile
$ export PS1="(chroot.nfs.cogentoo-1) $PS1"

chroot後のnfsクライアント側で実行するとflockできないという警告が出る。
nfsサーバー側でエラーが出ている。
$ emerge --oneshot -avt wget

nfsサーバー側の/vat/log/message
May 15 18:56:52 cogentoo-1 rpc.statd[483]: STAT_FAIL to cogentoo-1 for SM_MON of 192.168.0.100
May 15 18:56:52 cogentoo-1 kernel: lockd: cannot monitor amdgentoo
...

lock関連のデーモンを起動できない。
rpc.lockdが無い。
$ man lockd
$ sudo find / -name rpc.lockd
$

1.0系にあり。
$ e-file rpc.lockd
[I] net-fs/nfs-utils
        Available Versions:     1.0.12-r2 1.0.12-r0 1.0.10-r0 1.0.7-r2 1.0.7-r1 1.0.6-r6 1.0.12-r3
        Last Installed Ver:     1.2.3-r1(2011年05月15日 17時22分26秒)
        Homepage:               http://linux-nfs.org/
        Description:            NFS client and server daemons
        Matched Files:          /sbin/rpc.lockd;
...

1.1から先しか無い。
$ eix ^nfs-utils$
[I] net-fs/nfs-utils
     Available versions:  1.1.4-r1 ~1.1.5 ~1.1.6-r1 ~1.2.0 ~1.2.1 ~1.2.2-r2!t ~1.2.3!t 1.2.3-r1!t {caps elibc_glibc ipv6 kerberos +nfsv3 +nfsv4 nonfsv4 tcpd}
     Installed versions:  1.2.3-r1!t(17時22分22秒 2011年05月15日)(elibc_glibc nfsv3 nfsv4 tcpd -caps -ipv6 -kerberos)
     Homepage:            http://linux-nfs.org/
     Description:         NFS client and server daemons

gentooの場合、設定の変更で古いパッケージの情報も取得できるらしいが、やめておく。

nfsクライアント側のカーネル設定。
$ grep -i nfs /etc/kernels/kernel-config-x86_64-2.6.36-hardened-r9
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
# CONFIG_NFS_V4_1 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFS_USE_LEGACY_DNS is not set
CONFIG_NFS_USE_KERNEL_DNS=y
# CONFIG_NFSD is not set
CONFIG_NFS_ACL_SUPPORT=y
CONFIG_NFS_COMMON=y

nfsサーバー側のカーネル設定。
$ grep -i nfs /usr/src/linux/.config
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_V4_1=y
CONFIG_NFSD=m
CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3=y
CONFIG_NFSD_V3_ACL=y
# CONFIG_NFSD_V4 is not set
CONFIG_NFS_ACL_SUPPORT=m
CONFIG_NFS_COMMON=y
# CONFIG_NCPFS_NFS_NS is not set

colinuxの方のカーネルを再作成する。

flockのエラーが出る。
$ sudo mount -t nfs 192.168.0.200:/ /mnt/cogentoo-1/
$ nfsstat -m
/mnt/cogentoo-1 from 192.168.0.200:/
 Flags: rw,relatime,vers=3,rsize=32768,wsize=32768,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.200,mountvers=3,mountport=37363,mountproto=udp,addr=192.168.0.200

-o nolock追加。
$ sudo mount -t nfs -o nolock 192.168.0.200:/ /mnt/cogentoo-1/
$ nfsstat -m
/mnt/cogentoo-1 from 192.168.0.200:/
 Flags: rw,relatime,vers=3,rsize=8192,wsize=8192,namlen=255,hard,nolock,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.0.200,mountvers=3,mountport=52092,mountproto=udp,addr=192.168.0.200

flockテスト。
$ date >> test.txt
$ php -r '$fp=fopen("test.txt","r+");$res=flock($fp, LOCK_EX); var_dump($res); print fread($fp, 4096);'

テスト。v3でnolockでカーネルコンパイル。ARCH必須。CFLAGSは関係ある?他はない。
CROSS_COMPILEはi686-pc-linux-gccでコンパイルする場合。nfsでアクセスしているので、そのファイルは無い。
export CHOST="i686-pc-linux-gnu"
export CFLAGS="-march=prescott --param l1-cache-size=16 --param l1-cache-line-size=64 -mtune=prescott -fomit-frame-pointer -Os"
export CXXFLAGS="${CFLAGS}"
export ARCH=i386
#export CROSS_COMPILE="i686-pc-linux-"
cp -i /usr/src/colinux/coLinux-0.7.9-src/coLinux-0.7.9/conf/linux-2.6.33.7-config .config
# make menuconfig
# cpuの所をpentimu4に変えた。元のサーバーで実行する。
make vmlinux && make modules && make modules_install

古いのをmake oldconfigしていたのでv4が無かっただけで2.6.33のデフォルトでは設定済みだった。

特にエラーがなく立ち上がったのでflockなくてもカーネルのコンパイルはnfs上でいけるっぽい。
$ uname -a
Linux cogentoo-1 2.6.33.7-co-0.7.9 #1 PREEMPT Sun May 15 23:14:41 JST 2011 i686 Intel(R) Pentium(R) 4 CPU 3.00GHz GenuineIntel GNU/Linux

コンパイル中に秒数が0.7秒ずれている、とか出ていたがそれはntpサーバーのズレが大きいだけなので、大丈夫っぽい。
ntpの大本が10分に1回一気に時計合わせする、ざっくりとしたルーターの機能なのでそれに合わせると結構ずれるからだと思う。

その後クライアント側で -t nfs はOK -t nfs4 はエラー。
$ sudo mount -t nfs4 192.168.0.200:/ /mnt/cogentoo-1/
mount.nfs4: mounting 192.168.0.200:/ failed, reason given by server:
  No such file or directory
### サーバーを修正した。
$ sudo mount -t nfs4 192.168.0.200:/ /mnt/cogentoo-1/
$

サーバー側の修正。危険な設定に変更する。asyncは問題ありかもしれない。
$ rcsdiff exports,v /etc/exports
===================================================================
RCS file: exports,v
retrieving revision 1.2
diff -r1.2 /etc/exports
3c3
< / 192.168.0.100/255.255.255.255(rw,sync,no_root_squash)
---
> / 192.168.0.100/255.255.255.255(rw,async,no_root_squash,fsid=0,no_subtree_check)

クライアントのマウント状態。
$ nfsstat -m
/mnt/cogentoo-1 from 192.168.0.200:/
 Flags: rw,relatime,vers=4,rsize=8192,wsize=8192,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.0.100,minorversion=0,addr=192.168.0.200

chroot後に実行する。flock成功。
# cd
# pwd
/root
# date > date.txt
(chroot.nfs.cogentoo-1) amdgentoo ~ # php -r '$fp=fopen("date.txt","r+");$res=flock($fp, LOCK_EX); var_dump($res); print fread($fp, 4096);'
bool(true)
2011年  5月 16日 月曜日 00:51:36 JST

成功。/tmpがtmpfs=>マウント前の/tmpになっている。そのままにする。
# ll -A /tmp/
合計 8
drwxrwxrwt 2 root root 4096  1月 29  2010 .ICE-unix/
drwxrwxrwt 2 root root 4096  1月 29  2010 .X11-unix/

これが別のディレクトリの場合/etc/exportsに追加+fsid=0=>nohideなどにするらしい。

サーバー側。
$ sudo tail -f /var/log/messages

クライアント側。
# emerge --oneshot -avt wget

These are the packages that would be merged, in reverse order:

Calculating dependencies... done!
[ebuild   R   ] net-misc/wget-1.12-r3  USE="nls ssl -debug -idn -ipv6 -ntlm -static" 0 kB

Total: 1 package (1 reinstall), Size of downloads: 0 kB

Would you like to merge these packages? [Yes/No] no

Quitting.

サーバー側にnfs関連のエラーが出ない。
nfs4のflock成功。
エラーの場合、下記のようなものが出る。
May 15 17:33:03 cogentoo-1 rpc.statd[483]: STAT_FAIL to cogentoo-1 for SM_MON of 192.168.0.100
May 15 17:33:03 cogentoo-1 kernel: lockd: cannot monitor amdgentoo

コンパイル前。
$ wget www.example.com
...
$ ll
合計 4
-rw-r--r-- 1 usui usui 2945 2011-02-10 02:13:15 index.html
$ ll `which wget`
-rwxr-xr-x 1 root root 259356 2011-03-30 13:42:05 /usr/bin/wget*

クライアント側でコンパイルする。成功。
# emerge --oneshot -avt wget
...
yes
...
>>> Original instance of package unmerged safely.

* Messages for package net-misc/wget-1.12-r3:

* The /etc/wget/wgetrc file has been relocated to /etc/wgetrc
>>> Auto-cleaning packages...

>>> No outdated packages were found on your system.

* Regenerating GNU info directory index...
* Processed 106 info files.

コンパイル後。成功。
$ wget www.example.com
...
$ ll
合計 8
-rw-r--r-- 1 usui usui 2945 2011-02-10 02:13:15 index.html
-rw-r--r-- 1 usui usui 2945 2011-02-10 02:13:15 index.html.1
usui@cogentoo-1 /tmp/wget $ ll `which wget`
-rwxr-xr-x 1 root root 259356 2011-05-16 01:00:52 /usr/bin/wget*

結果として、distccで任せられるサーバーが1台の場合はnfsでまるごとマウントは効果的。
コンパイル時のchecking ... のあたりのdistccを使わない部分も扱えるので有利?
代わりにディスク性能+ネットワーク性能がボトルネックになる?
コンパイル時にcolinuxのmemをある程度上げないと、ものすごく遅いというのを回避できるかもしれない。
gccのコンパイルの場合300以上にしとかないとswapしすぎて遅い、など。
distccはもともと単体でも早いやつを更に早くする、のが得意。
元が遅いとdistccに処理を渡せる部分以外がすごく長い場合、体感できない、かもしれない。
cpuとコンパイルするソフトの種類によっては実際にcpuごとの独自の命令を要求するらしいので失敗するらしい。
インストール中に出来上がったバイナリで、なにかする、など。
それは元のほうでコンパイルするなどの対応。

なにかエラーが出ている。問題ない?
>>>> Emerging (1 of 1) net-misc/wget-1.12-r3
> openpty failed: 'out of pty devices'
>  * wget-1.12.tar.bz2 RMD160 SHA1 SHA256 size ;-) ...                     [ ok ]

クライアント側の利用メモリ結構増えたように思う。キャッシュ?

テスト。
distccで実行。nfsを止めていない。他のサービスも止めていない。
$ time sudo emerge --oneshot -vt wget
...
* Regenerating GNU info directory index...
* Processed 106 info files.

real    5m53.493s
user    1m39.190s
sys     2m44.820s

使っている。
$ sudo DISTCC_DIR=/var/tmp/portage/.distcc distccmon-text 1|grep 192.168.0.100
642  Preprocess  c-ctype.c                                 192.168.0.100[0]
650  Preprocess  xmalloc.c                                 192.168.0.100[1]
645  Preprocess  xalloc-die.c                              192.168.0.100[2]
647  Preprocess  getpass.c                                 192.168.0.100[3]
647  Preprocess  getpass.c                                 192.168.0.100[3]
...
796  Compile     url.c                                     192.168.0.100[1]
802  Preprocess  utils.c                                   192.168.0.100[2]
753  Preprocess  init.c                                    192.168.0.100[3]
804  Preprocess  exits.c                                   192.168.0.100[0]
802  Compile     utils.c                                   192.168.0.100[2]

実行後のメモリ。
$ free
total       used       free     shared    buffers     cached
Mem:         60584      37476      23108          0       9744      10872
-/+ buffers/cache:      16860      43724
Swap:      1048568      31704    1016864

nfsの場合。早くなった。cpuの能力が問題ない場合ディスクがネットワーク経由なので逆転するはず。
# time emerge --oneshot -vt wget
...
* Regenerating GNU info directory index...
* Processed 106 info files.

real    3m0.287s
user    0m29.970s
sys     0m7.570s

distccは動かない。なにかを判定しているとか?
$ sudo DISTCC_DIR=/var/tmp/portage/.distcc distccmon-text 1|grep -v ^$
^C
$

メモリはたぶん/procをマウントしているせいでクライアント側になっている。
# free
total       used       free     shared    buffers     cached
Mem:       8065896    7880360     185536          0    1072260     456600
-/+ buffers/cache:    6351500    1714396
Swap:     15631164          0   15631164

別にディスクの性能がいいわけではないので、場合にもよるだろうが早くなりそう。
distccの場合より問題が発生する事が多そう。
distccが関われない部分でcpuがボトルネックの場合には効果あり。
ホストのcpuが低性能で、distccのサーバーが1台の場合は、distccより確実に早くなる。
設定なしでdistcc自体が動いていないがこれは正常か?この場合、動いても意味はないが。

本当に成功かどうかは emerge -e world などをやってみないとわからない。
なにか問題がでるとおもう。
kvmなどで同じ設定にしたゲストOS上でbinpkg的なことをやってそれを入れたほうが良いかもしれない。

クライアント側。
nfs4の場合で手動の場合、rpcbind, rpc.idmapdだけでいいかもしれない。
init xxxで影響が出るかもしれないので全部登録した方がいい?
$ rc-update show | grep -iP "nfs|rpc"
            rpc.statd |                                   default # rpc.lockd関連?必要なし?nfsmountで必要?
              rpcbind |                                   default # rpc関連全般で必要?
           rpc.pipefs |                                   default # rpc.idmapdで必要?
             nfsmount |                                   default # /etc/fstab関連。
           rpc.idmapd |                                   default # ファイルのユーザー、グループ。

サーバー側。
$ rc-update show | grep -iP "nfs|rpc"
                  nfs |        default

0 件のコメント: