pynfs 介绍
05 Mar 2018简介
http://wiki.linux-nfs.org/wiki/index.php/Pynfs
pynfs 是一款用来测试 NFSv4.0 和 NFSv4.1 的测试工具,跟 Connectathon 测试套件不同,它知道如何解析和生成协议报文,可以直接跟 client 和 server 交互来进行测试。 这些特性使得它特别适合用来做下列测试:
- 错误或恶意的协议响应报文
- 对异常错误的响应
- 协议的一致性
- (模拟尚未实现的客户端或服务端)来验证新功能的正确性
目前server测试的代码比client测试代码更成熟一些。 请注意,测试结果并不能作为相关协议正确性的权威声明 – 如果你发现有测试项测试失败 请在断定是bug之前详细阅读相关 RFC 并仔细思考。
下载
目前 pynfs 由 J. Bruce Fields 开发维护,源代码地址:
url=git://git.linux-nfs.org/projects/bfields/pynfs.git
git clone $url
安装使用
dependency install python2 #最近的版本(2020/05之后)已经不再支持 python2
yum install krb5-devel python-devel swig screen python-ply python-gssapi
# or if there isn't python-ply or python-gssaip, please install them from pip
rpm -q python-ply || {
OSVER=$(rpm -E %rhel)
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-${OSVER}.noarch.rpm
yum install -y python-pip && pip2 install ply gssapi
}
dependency install python3
yum install krb5-devel python3-devel swig screen python3-ply python3-gssapi
# or if there isn't python3-ply or python3-gssaip, please install them from pip
rpm -q python3-ply || {
OSVER=$(rpm -E %rhel)
yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-${OSVER}.noarch.rpm
yum install -y python3-pip && pip3 install ply gssapi
}
see also: https://github.com/tcler/kiss-vm-ns/blob/master/utils/pynfs-install.sh
server test
(cd pynfs/; python setup.py install)
cd pynfs/nfs4.0 # or cd pynfs/nfs4.1
mkdir -p /exportdir && echo '/exportdir *(rw,no_root_squash,insecure)' >/etc/exports && systemctl restart nfs-server
./testserver.py --outfile ${logf:-log.txt} --maketree ${serv:-localhost}:${export:-/exportdir} all
# ^^^
# 注: all 是测试用例的 flags 之一,表示运行所有 flags 里带有 all 标记的 测试用例
# 有些测试用例的 FLAGS 里没有 all flag,跑这些 case 需要指定其特有的 flag 或 显式的指定case的 CODE
./testserver.py --outfile ${logf:-log.txt} --maketree ${serv:-localhost}:${export:-/exportdir} WRT16 RD4 --rundeps
# ^^^ ^^^
# 注: 上面的 WRT16b RD4 是 case 的唯一标识, --rundeps 告诉程序自动运行依赖的 case
pnfs client test # 目前(2020/07)还有 bug: mds 跑不起来,开发正在调查中
systemctl stop nfs-server
(cd pynfs; python setup.py install)
cd pynfs/nfs4.1 # nfs4.1 开始支持 pnfs
echo "${IP:-127.0.0.1}:12345/pynfs_mds" >dataservers.conf
\cp -f sample_code/ds_exports.py .
screen -dm bash -c "./nfs4server.py -r -v --is_ds --exports=ds_exports --port=12345 &>ds.log"
screen -dm bash -c "./nfs4server.py -r -v --use_files --dataservers=dataservers.conf &>mds.log"
nfsmp=/mnt/nfsmp; mkdir -p $nfsmp
mount -o minorversion=1 ${IP:-127.0.0.1}:/ ${nfsmp}
echo 88888 >${nfsmp}/a/testfile
: <<-COM
$ cat sample_code/ds_exports.py
"""
A very simple exports file intended for use with a files-layout dataserver.
"""
from fs import StubFS_Mem
def mount_stuff(server, opts):
B = StubFS_Mem(2)
server.mount(B, path="/pynfs_mds")
COM
pnfs nfsproxy
service nfs stop
(cd pynfs; python setup.py install)
cd pynfs/nfs4.1 # nfs4.1 开始支持 pnfs
pnfs_server=<your pnfs server address>
nfsmp=/mnt/nfsmp
mkdir -p $nfsmp
echo '<errorconf>
<error>
<name>layoutget</name>
<operation>LAYOUTGET</operation>
<errorcode>NFS4ERR_LAYOUTUNAVAILABLE</errorcode>
<frequency>1</frequency>
<delay>0</delay>
</error>
</errorconf>' >error.xml
./nfs4proxy.py --dserver=$pnfs_server &>nfsproxy.log &
pid=$!
mount -o vers=4.1 127.0.0.1:/ $nfsmp
echo '#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
void main(int ac, char*av[])
{
int fd2, ret;
char *wrbuf;
fd2 = open(av[1], O_WRONLY | O_CREAT | O_DIRECT);
if (fd2 < 0) {
perror("OPEN fd1 error\n");
return;
}
printf("opened %s write\n", av[1]);
wrbuf = malloc(6);
memset(wrbuf, 0xa, 6);
ret = write(fd2, wrbuf, 6);
if (ret <=0) {
perror("write error\n");
return;
} else printf("write succeeded\n");
if (fsync(fd2) < 0) printf("fsync failed\n");
if (close(fd2) < 0) printf("close failed\n");
return;
}' >test.c
gcc test.c -o test
./test $nfsmp/testfile
troubleshooting
testmod.FailureException: Could not LOOKUP /exportdir/tmp, should return NFS4_OK, instead got NFS4ERR_PERM
检查 server 端 export option, 通常添加 insecure 后, 重启服务 即可
nfs4lib.BadCompoundRes: Trying to remove 'testfile': operation OP_REMOVE should return NFS4_OK, instead got NFS4ERR_GRACE
server 在 GRACE duration, 等 90 秒 再执行就好了