1、什么是nfs
(1)NFS(Network File System)是网络文件系统,能让使用者访问网络上别处的文件就像在使用自己的计算机一样;
(2)NFS是基于UDP/IP协议的应用,其实现主要是采用远程过程调用RPC机制,RPC提供了一组与机器、操作系统以及低层传送协议无关的存取远程文件的操作;
(3)NFS可用于不同类型计算机、操作系统、网络架构和传输协议运行环境中的网络文件远程访问和共享;
(4)NFS是服务器/客户端架构,服务器可允许多个客户端访问,服务器向客户端提供对本地文件系统的访问权限,实现网络中文件共享;
2、NFS服务器的工作原理
2.1、NFS和RPC的关系
(1)RPC(Remote Procedure Call Protocol)远程过程调用协议,一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议;
(2)RPC最主要的功能就是指定每个NFS功能所对应的端口,并返回给客户端,使客户端可以连接到正确的端口上;
(3)NFS是依赖RPC才能工作:NFS是一种文件系统,RPC负责在设备间的通过网络传输信息;
(4)NFS服务端常用的端口为2049,但是NFS功能有很多,每个功能就是一个程序,按照TCP/IP协议,计算机中每个程序在传输层都需要有一个端口号,这些端口都是随机产生并且小于1024;(NFS是基于网络的应用,属于套接字程序,所以需要端口号)
(5)NFS的每个程序都先要向RPC注册端口号,所以必须在启动NFS前先启动RPC服务器;
(6)RPC服务器的端口号是111,NFS客户端挂载NFS服务器时,先通过RPC的客户端连接RPC的服务器端,获取到NFS对应程序的端口号,然后再建立连接;
2.2、NFS服务器工作流程
(1)先启动RPC服务,RPC对外的端口是111;
(2)启动NFS服务器,NFS服务器会向RPC注册相应的端口;
2.3、NFS客户端工作流程
(1)当NFS客户端需要连接到服务器上时,先启动客户端的RPC服务,客户端的RPC向服务端的RPC 111端口索要功能对应的端口号;
(2)向服务器端索要到端口号后,便连接到NFS服务对应功能的端口,随后传输数据;
补充:即使客户端已经获取了端口号,客户端仍会借助rpc做为中间人进行通信;
3、rpcbind和portmap的关系
(1)rpcbind和portmap都是在NFS中提供RPC协议层的工具,功能是类似的;
(2)目前的趋势是用rpcbind来替代portmap;
4、NFS的常用命令
(1)rpcbind:启动RPC服务;
(2)rpc.nfsd:管理客户端是否能够使用服务器文件系统挂载信息等, 其中还包含这个登入者的 ID 的判别;
(3)rpc.mountd:读NFS的配置文件/etc/exports来比对客户端的权限,管理NFS分享之目录的权限与安全设定;
(4)rpc.lockd:解决多个客户端同时操作同一份文件的问题;(同时在客户端与服务器端都开启才行)
(5)rpc.statd:监听来自其他主机的重启通知,与sm-notify配套使用,主要应用与NFS V3协议,NFS V4协议中该功能由内核来完成;
(6)exportfs:导出NFS共享目录,客户端可以通过NFS服务访问服务器的这些共享目录;
(7)showmount:显示服务器端mount相关的配置信息;(showmount -e :查看当前的共享目录)
(8)sm-notify:如果服务器和客户端的重启,向其他NFS终端发送该终端重启的通知,主要应用于NFS V3协议,NFS V4协议中该功能由内核来完成;
(9)umount:卸载网络共享目录;
(10)mount:挂载共享目录;
5、nfs服务器端搭建
5.1、开源工具的移植
5.1.1、libtirpc移植
5.1.1.1、源码下载
(1)源码下载网址:https://sourceforge.net/projects/libtirpc/;
5.1.1.2、源码编译
./configure --disable-gssapi --prefix=/home/root/NFS/libtirpc/bin --host=aarch64-mix410-linux
make
make install
(1)–disable-gssapi:禁止gssapi功能,改功能不影响主体功能,编译环境不支持可以禁止;
(2)–prefix:指定安装目录,将来执行"make install"命令,会将生成的动态库、静态库、头文件安装到该目录;
(3)–host:指定编译工具;
5.1.2、rpcbind移植
5.1.2.1、源码下载
(1)源码下载网址:https://www.linuxfromscratch.org/blfs/view/8.3/basicnet/rpcbind.html
5.1.2.2、源码编译
./configure TIRPC_CFLAGS="-I/home/root/NFS/libtirpc/bin/include/tirpc" TIRPC_LIBS="-L/home/root/NFS/libtirpc/bin/lib -ltirpc" --without-systemdsystemunitdir --host=aarch64-mix410-linux --prefix=/home/310793/phoneGate/nfs/rpcbind/bin
make
make install
(1)TIRPC_CFLAGS:指定libtirpc库的头文件路径;
(2)TIRPC_LIBS:指定libtirpc.a的路径;
(3)–prefix:指定安装目录,将来执行"make install"命令,会将生成的动态库、静态库、头文件安装到该目录;
(4)–host:指定编译工具;
总结:得到rpcbind和rpcinfo命令;
5.1.3、nfs-utils移植
5.1.3.1、源码下载
(1)源码下载地址:https://www.linuxfromscratch.org/blfs/view/8.3/basicnet/nfs-utils.html;
5.1.3.2、源码编译
./configure TIRPC_CFLAGS="-I/home/root/NFS/libtirpc/bin/include/tirpc" TIRPC_LIBS="-L/home/root/NFS/libtirpc/bin/lib -ltirpc" --disable-nfsv4 --disable-nfsv41 --disable-gss --disable-uuid --disable-ipv6 --with-tirpcinclude=/home/root/NFS/libtirpc/bin/include/tirpc --host=aarch64-mix410-linux --prefix=/home/root/NFS/utils/bin --disable-mount
make
make install
(1)TIRPC_CFLAGS:指定libtirpc库的头文件路径;
(2)TIRPC_LIBS:指定libtirpc.a的路径;
(3)–prefix:指定安装目录,将来执行"make install"命令,会将生成的动态库、静态库、头文件安装到该目录;
(4)–host:指定编译工具;
总结:得到rpc.mountd、rpc.nfsd、rpc.statd、sm-notify、showmount等命令;
5.2、内核修改
File systems --->
[*] Network File Systems --->
<*> NFS server support
-*- NFS server support for NFS version 3
[*] NFS server support for the NFSv3 ACL protocol extension
[*] NFS server support for NFS version 4
[*] NFSv4.1 server support for pNFS block layouts
[*] NFSv4.1 server support for pNFS SCSI layouts
[*] NFSv4.1 server support for pNFS Flex File layouts
修改内核的配置文件,支持NFS server功能;
5.3、文件系统修改
5.3.1、启动脚本中开启nfs服务
mkdir /var/lib/nfs
chmod 777 -R /var/lib
mkdir /var/run
touch /var/run/rpcbind.lock
rpcbind
exportfs -av
rpc.mountd
rpc.statd --no-notify
rpc.nfsd
sm-notify
在内核启动脚本中添加上面的脚本开启nfs服务器,可以加在/etc/rcS文件中;
5.3.2、设置nfs共享目录
/data/appdata/ *(rw,no_root_squash,sync)
/mnt/ 192.168.1.1(rw,no_root_squash,sync)
(1)增加/etc/exports文件,设置nfs共享目录的路径;
(2)上面的设置中nfs共享目录有两个,都是可读写、同步、允许非root用户去挂载;
(3)/data/mnt/目录做了额外限制,只允许ip地址是192.168.1.1的设备去挂载,增加安全性;
5.3.3、在网络初始化中增加nfs
nfs 2049/tcp nfsd
nfs 2049/udp nfsd
(1)在/etc/services中保存了主机中所有网络服务的端口号,需要确认文件中是否已经添加上面两句;
(2)不添加上面的代码,执行rpc.nfsd会报错:Starting NFS daemon: rpc.nfsd: unable to resolve ANYADDR:nfs: Servname not supported for ai_socktype;
5.3.4、增加/etc/netconfig文件
#
# The network configuration file. This file is currently only used in
# conjunction with the TI-RPC code in the libtirpc library.
#
# Entries consist of:
#
# <network_id> <semantics> <flags> <protofamily> <protoname> \
# <device> <nametoaddr_libs>
#
# The <device> and <nametoaddr_libs> fields are always empty in this
# implementation.
#
udp tpi_clts v inet udp - -
tcp tpi_cots_ord v inet tcp - -
udp6 tpi_clts v inet6 udp - -
tcp6 tpi_cots_ord v inet6 tcp - -
rawip tpi_raw - inet - - -
local tpi_cots_ord - loopback - - -
unix tpi_cots_ord - loopback - - -
(1)不添加/etc/netconfig文件,rpcbind命令会异常退出;
(2)netconfig文件可以去已经搭建完成nfs服务器的虚拟机里拷贝出来;
6、nfs客户端搭建
6.1、内核修改
File systems --->
[*] Network File Systems --->
<*> NFS client support
<*> NFS client support for NFS version 2
<*> NFS client support for NFS version 3
[*] NFS client support for the NFSv3 ACL protocol extension
< > NFS client support for NFS version 4
[*] NFS: Disable NFS UDP protocol support
内核开启nfs客户端的支持;
6.2、挂载命令
mount -t nfs 192.168.2.100:/data/appdata/ /tmp/share -o nolock,tcp
7、调试的注意事项
(1)如果nfs共享的目录本身就是只读文件系统,就算以可读写方式挂载,最后也是只读;
(2)客户端挂载不上服务器端的共享目录,检查服务器端是否关闭防火墙、是否允许非root用户挂载;
(3)查看服务器端当前的共享目录:showmount -e;
(4)修改共享目录后要刷新:exportfs -rv;
(5)查看rpc的端口号:rpcinfo -p;
8、nfs版本不匹配引起的报错
8.1、报错信息
unable to get mount port number from server, using default
VFS: Unable to mount root fs via NFS, trying floppy.
8.2、查看支持的nfs版本
# 服务器端
~ # cat /proc/fs/nfsd/versions
-2 +3 +4 +4.1 +4.2
#客户端:在内核的配置表里可以查看(make menuconfig)
File systems --->
[*] Network File Systems --->
<*> NFS client support
<*> NFS client support for NFS version 2
<*> NFS client support for NFS version 3
[*] NFS client support for the NFSv3 ACL protocol extension
< > NFS client support for NFS version 4
[*] NFS: Disable NFS UDP protocol support
从上面的信息可以看出,服务器端和客户端同时支持3和4版本的nfs;
8.3、解决办法:指定一个同时支持的nfs版本
mount -t nfs 192.168.2.100:/data/appdata/ /tmp/share -o nolock,tcp,nfsvers=3
(1)在用mount命令挂载时,一般是不用指定nfs版本的,会默认使用一个版本;
(2)当出现上面报错,并查看服务器/客户端有同时支持的nfs版本时,可用“nfsvers”关键字在mount时指定nfs版本;
推荐
给大家推荐一个学校嵌入式知识的网站,博主在大学时候学习嵌入式知识、找工作的时候都在用这个网站,网站里有C语言、Linux等等的笔试题、面试常问问题等等知识,无论是学习基础知识、面试刷题、交流工作经验都是不错的选择。大家一起进步,欢迎留言交流。
链接:学习神器跳转