本文转载于NFS /etc/exports参数解释,有修改。

问题引入

之前利用NFS从ubuntu中下载根文件系统到开发板(见博客以NFS方式挂载rootfs的设置方法),但只是遵照教程安装的,对里面的设置含义不是很清楚。后来在开发板上上进行文件的创建与修改,数据居然同步到 ubuntu 中的文件夹里。NFS不是只把根文件系统下载到开发板吗?下载之后,开发板上的根文件系统就和ubuntu中的NFS服务器没有关系,为何这里还挂载了?带着疑问,我重新查看了NFS的配置过程,对里面的步骤含义进行了了解。

NFS服务器的功能

NFS 服务器,可以看作是一个文件服务器。NFS 客户端通过网络将远端NFS服务器共享出来的目录挂载到自己的系统中。在 NFS 客户端看来,NFS服务器的远端文件就像客户端的本地文件一样。

NFS 本身没有提供信息传输的协议和功能,但它借用了一些其他的传输协议,这些传输协议要用到RPC功能,因此不论是NFS服务器还是NFS客户端,只要用到 NFS 的地方都要启动RPC 服务,这样服务器和客户端才能通过RPC来传输数据。

NFS服务器的配置

假设ubutun系统的局域网IP:192.168.1.141

1、安装NFS服务器

sudo apt install nfs-kernel-server
sudo apt install nfs-common

2、编辑配置文件/etc/exports

(1)通过vim /etc/exports 来编辑配置文件

# 编辑格式
# NFS服务器里你想分享的目录的具体路径 可接入NFS服务器的主机名字或者IP(参数1,2,…)

# 举例(注意*表示所有主机)
/root/share/ 192.168.1.2(rw,insecure,sync,all_squash) 
/home/xjh/iot/embedded_basic/rootfs/roofs_xjh *(rw,insecure,sync,all_squash) 

(2)参数含义说明

参数含义
Ro该主机对该共享目录有只读权限
Rw该主机对该共享目录有读写权限
Root_squash客户机用root用户访问该共享文件夹时,将root用户映射成匿名用户
No_root_squash客户机用root访问该共享文件夹时,不映射root用户
All_squash客户机上的任何用户访问该共享目录时都映射成匿名用户
Anonuid将客户机上的用户映射成指定的本地用户ID的用户
Anongid将客户机上的用户映射成属于指定的本地用户组ID
Sync资料同步写入到内存与硬盘中
Async资料会先暂存于内存中,而非直接写入硬盘
 Insecure允许从这台机器过来的非授权访问
subtree_check如果共享/usr/bin之类的子目录时,强制NFS检查父目录的权限(默认)
no_subtree_check和上面相对,不检查父目录权限
wdelay如果多个用户要写入NFS目录,则归组写入(默认)
no_wdelay如果多个用户要写入NFS目录,则立即写入,当使用async时,无需此设置。
hide在NFS共享目录中不共享其子目录
no_hide共享NFS目录的子目录
secureNFS通过1024以下的安全TCP/IP端口发送
insecureNFS通过1024以上的端口发送

(3)举例说明

/ user01(rw) user02(rw,no_root_squash)

表示共享服务器上的根目录(/)只有user01和user02两台主机可以访问,且有读写权限。

user01主机用root用户身份访问时,将客户机的root用户映射成服务器上的匿名用户(root_squash,该参数为缺省参数),相当于在服务器使用nobody用户访问目录。

user02主机用root用户身份访问该共享目录时,不映射root用户(no_root_squash),即相当于在服务器上用root身份访问该目录。

/root/share/ 192.168.1.2(rw,insecure,sync,all_squash)

表示共享服务器上的/root/share/目录只有192.168.1.2主机可以访问,且有读写权限。

此主机用任何身份访问时,将客户机的用户都映射成服务器上的匿名用户(all_squash),相当于在服务器上用nobody用户访问该目录(若客户机要在该共享目录上执行写操作,则服务器上的nobody用户对该目录必须有写的权限)。

/home/ylw/ .test.com (rw,insecure,sync,all_squash)

表示共享/home/ylw/目录,.test.com域中所有的主机都可以访问该目录,且有读写权限。

/home/share/ .test.com (ro,sync,all_squash,anonuid=zh3,anongid=wa4)

表示共享目录/home/share/,*.test.com域中的所有主机都可以访问,但只有只读的权限,所有用户都映射成服务器上的uid为zh3、gid为wa4的用户。

3、重启NFS服务

sudo service nfs-kernel-server restart

附录:常用的命令

(1)修改后将配置文件中的目录全部重新export(和重启效果一样)

sudo exportfs -rv

 (2)查看有NFS服务器设置了哪些共享目录

sudo showmount -e localhost
//或者sudo showmount -e 127.0.0.1
//或者sudo showmount -e 192.168.1.141

(3)将NFS服务器某共享目录挂载在NFS客户端的某目录

sudo mount -t nfs 192.168.1.141:/home/xjh/iot/embedded_basic/rootfs/tmp /mnt

(4)umount 命令取消挂载(使用格式待求证)

sudo umount 192.168.1.141:/home/xjh/iot/embedded_basic/rootfs/tmp
或者
sudo umount 192.168.1.88:/mnt
或者
sudo umount 192.168.1.141:/home/xjh/iot/embedded_basic/rootfs/tmp 192.168.1.88:/mnt

(4)查看NFS的运行状态

sudo nfsstat

(5)查看rpc执行信息,可以用于检测rpc运行情况

sudo rpcinfo

(6)查看网络端口(NFS默认是使用111端口)

sudo netstat -tu -4

NFS客户端的配置

注意以下操作是在NFS客户端进行操作。

1、安装nfs-common软件包

sudo apt install nfs-common

2、查看NFS服务器上的共享目录

NFS服务器和NFS客户端能够ping通时,可以在NFS客户端输入下面命令查看NFS服务器(192.168.1.141)设置了哪些共享目录。

sudo showmount -e 192.168.1.141

如果不能ping通,那只能在NFS服务器输入下面的命令查看NFS服务器设置了哪些共享目录。

sudo showmount -e 192.168.1.141 
//或者 sudo showmount -e localhost
//或者 sudo showmount -e 127.0.0。1

127.0.01表示本主机,另外localhost这个符号也表示本主机,在/etc/hosts中如此定义:

127.0.0.1   localhost

而之前我在/etc/network/interfaces中将如此设置,则192.168.1.141也表示本机:

# interfaces(6) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
#iface eth0 inet dhcp
address 192.168.1.141
netmask 255.255.255.0
gateway 192.168.1.1

所以localhost、127.0.0.1、192.168.1.141所指的都是NFS客户端,因此:

root@ubuntu:/# sudo showmount -e 127.0.0.1         //方式1
Export list for 127.0.0.1:
/home/xjh/iot/embedded_basic/rootfs/tmp        *
/home/xjh/iot/embedded_basic/rootfs/rootfs_xjh *
/home/xjh/iot/hisi_development/hisi_rootfs     *
root@ubuntu:/# sudo showmount -e 192.168.1.141     //方式2
Export list for 192.168.1.141:
/home/xjh/iot/embedded_basic/rootfs/tmp        *
/home/xjh/iot/embedded_basic/rootfs/rootfs_xjh *
/home/xjh/iot/hisi_development/hisi_rootfs     *
root@ubuntu:/# sudo showmount -e localhost         //方式3
Export list for localhost:
/home/xjh/iot/embedded_basic/rootfs/tmp        *
/home/xjh/iot/embedded_basic/rootfs/rootfs_xjh *
/home/xjh/iot/hisi_development/hisi_rootfs     *
root@ubuntu:/#

3、将NFS服务器上的某个共享目录挂载在NFS客户端目录

比如将NFS服务器上的共享目录/home/xjh/iot/embedded_basic/rootfs/tmp,挂载到NFS客户端的/mnt目录:

sudo mount -t nfs 192.168.1.141:/home/xjh/iot/embedded_basic/rootfs/tmp /mnt

4、查看挂载状态

在NFS客户端命令行输入以下指令查看挂载状态。

mount | grep nfs 

5、测试

通过NFS客户端的/mnt目录,可以查看NFS服务器上的共享目录/home/xjh/iot/embedded_basic/rootfs/tmp中的内容。

问题解决

我的目的是,让开发板通过NFS下载根文件系统之后,就断开与ubuntu中的根文件系统的关联,这样在开发板上目录上修改数据,不会同步到ubuntu中的根文件系统的文件夹里。

我没有在开发板系统上安装NFS客户端,只是在内核配置阶段配置了NFS相关的内容(见本文开始部分的链接博客),不知道这个配置与安装NFS客户端有什么关联?

通过在ubuntu的etc/exports文件中输入以下内容后,可以顺利下载根文件系统到开发板。这体现了可以利用NFS进行文件下载。

但是下载之后,/home/xjh/iot/embedded_basic/rootfs/rootfs_xjh居然挂载在了开发板的根目录上(体现在开发板的数据与此目录下的数据同步)。NFS也提供挂载吗?还是说哪里使用了mount指令?如果某个地方使用了挂载mount指令,那么按理我可以取消这个挂载的。

我在根文件系统里的etc/profile里,取消将/home/xjh/iot/embedded_basic/rootfs/rootfs_xjh挂载到开发板。但不知道是因为命令格式不对,还是这个挂载的特殊性,提示没有/home/xjh/iot/embedded_basic/rootfs/rootfs_xjh这个文件或者目录。

于是我在开发板的命令行中输入umount /,成功后想看下在开发板创建文件是否还会影响ubuntu中的文件夹形式的根文件系统。但是此时提示:

[root@xjh ]# umount /
[root@xjh ]# ls
bin      etc      lib      mnt      root     sys      usr
dev      home     linuxrc  proc     sbin     tmp      var
[root@xjh ]# mkdir test
mkdir: can't create directory 'test': Read-only file system

于是我想把开发板的根目录挂载到/home/xjh/iot/embedded_basic/rootfs/rootfs_xjh,但提示如下。

[root@xjh mnt]# mount / 192.168.1.141:/home/xjh/iot/embedded_basic/rootfs/rootfs
_xjh
mount: mounting / on 192.168.1.141:/home/xjh/iot/embedded_basic/rootfs/rootfs_xjh failed: No such file or directory

折腾比较闹心,因为对mount命令的使用格式不熟悉,以及对根文件根目录是否有特殊性不了解。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐