对于下面的长读表示歉意。希望这能提供足够的背景和痕迹,以便有人可以帮助我。
语境
我将用户主目录存储在一些 zfs 数据集上(每个用户一个),其中每个用户的每个 Linux 发行版和版本(例如 Debian Buster)都有一个不同的主目录,但实际上所有这些主目录的 XDG 目录(例如下载或桌面)都在其中指向同一目录,以便用户可以访问其所有文件,无论用户登录的终端运行哪个 Linux 发行版。我在家中存储的二进制文件具有相同的结构。请参阅下面的示例(请参阅下面的方括号中的数字含义):
/media/zfs/home/user1/XDG-DIRS/[1]Downloads
| /[2]Videos
| /<some more directories and files>
|
/homes/[3]debian_buster/<some files(1)>
| /[4]ubuntu_groovy/<some files(2)>
|
/[5]usr/share/<some files(3)>
| /include/<some files(4)>
|
/local/linux-x86_64/[6]bin
| /[7]lib
|
/linux-armhf/[8]bin
/[9]lib
使用特定的挂载来纠正上述结构中的点,可以使用与发行版及其版本所服务的桌面环境相匹配的所有用户设置文件重新构建主目录,但仍然可以访问所有个人文件,甚至与操作系统兼容的家庭安装的二进制文件以及用户登录的架构。例如,用户登录在 x86_64 架构上运行的 Linux Debian Buster 时,其主目录结构应如下所示。目录名称末尾方括号中的数字表示该目录的内容实际上应该是上述结构中名称开头具有相同数字的目录中的内容。我让你猜猜登录运行 ubuntu groovy 的树莓派的用户的主目录是什么样的。
/home/AD.EXAMPLE.COM/user1[3]/Downloads[1]
/Videos[2]
/.local[5]/bin[6]
/lib[7]
可以通过在终端计算机上运行 autofs 并使用可执行映射文件来实现此目的,该文件会根据需要安装尽可能多的 nfs(在上面的示例中,每个用户 5 个,通常会更多,因为 XDG 目录更多)。我预期的问题是,如果用户想要将文件从“下载”移动到“视频”,那么由于这是两个不同的 nfs 挂载点,文件实际上会下载到终端,然后上传回服务器。实际上我没有测试这是否会导致性能损失。如果您对这一点有任何见解,请告诉我。
为了限制上述性能问题,我实际上使用 autofs 为服务器上的每个发行版/版本(一侧)和每个操作系统/体系结构(另一侧)重新构建主目录,然后通过 NFS 导出结果。这意味着我使用 autofs 绑定安装在服务器上构建以下结构
/media/user_data/unix/user1/home/[10]debian_buster/Downloads[1]
| | /Videos[2]
| | /.local/<empty>
| /ubuntu_groovy/Downloads[1]
| /Videos[2]
| /.local/<empty>
/[11]local/linux-x86_64[5]/bin[6]
| /lib[7]
/local/linux-armhf[5]/bin[8]
/lib[9]
/etc/auto.master.d/user_data.autofs
(服务器端)
/media/user_data/unix/ /etc/auto.AD.EXAMPLE.COM.unix --ghost --timeout=120
/etc/auto.AD.EXAMPLE.COM.unix
(服务器端,为 ugo 设置的可执行和读取位)
#!/bin/bash
key=$1
echo '- /home -fstype=bind :/media/zfs/home/'$key'/unix/ browse \'
for i in $(ls /media/zfs/home/$key/unix)
do
for j in $(ls /media/zfs/home/$key/XDG_DIRS)
do
echo ' /home/'$i'/'$j' -fstype=bind :/media/zfs/home/'$key'/XDG_DIRS/'$j' browse \'
done
done
for i in $(ls /media/zfs/home/$key/usr)
do
echo ' /local/'$i' -fstype=bind :/media/zfs/home/'$key'/local/ browse \'
for j in $(ls /media/zfs/home/$key/usr/$i)
do
echo ' /local/'$i'/'$j' -fstype=bind :/media/zfs/home/'$key'/usr/'$i'/'$j' browse \'
done
done
echo ''
这是上面所示脚本的示例输出
root@server:~# /etc/auto.AD.EXAMPLE.COM.unix user1
- /home -fstype=bind :/media/zfs/home/user1/unix/ browse \
/home/debian_buster/Downloads -fstype=bind :/media/zfs/home/user1/XDG_DIRS/Downloads browse \
/home/debian_buster/Videos -fstype=bind :/media/zfs/home/user1/XDG_DIRS/Videos browse \
/local/linux-armhf -fstype=bind :/media/zfs/home/user1/local/ browse \
/local/linux-armhf/bin -fstype=bind :/media/zfs/home/user1/usr/linux-armhf/bin browse \
/local/linux-armhf/lib -fstype=bind :/media/zfs/home/user1/usr/linux-armhf/lib browse \
/local/linux-armhf/sbin -fstype=bind :/media/zfs/home/user1/usr/linux-armhf/sbin browse \
/local/linux-x86_64 -fstype=bind :/media/zfs/home/user1/local/ browse \
/local/linux-x86_64/bin -fstype=bind :/media/zfs/home/user1/usr/linux-x86_64/bin browse \
/local/linux-x86_64/lib -fstype=bind :/media/zfs/home/user1/usr/linux-x86_64/lib browse \
root@server:~#
到目前为止,这工作得完美无缺,尽管对我来说有点慢。我/media/user_data/unix
通过 NFS 导出,使用下面的导出文件:
# <other exports of unrelated directories>
/media/user_data *(sec=krb5p,rw,crossmnt)
# <other exports of unrelated directories>
此时,值得一提的是,此文件层次结构中存在“user_data”步骤的一个原因是,因为如果我导出/media/user_data/unix
(/etc/exportfs
或等效地,/media/unix
尽管下面未演示),那么我会收到下面的警告。这并不令人鼓舞,但我无论如何都会尝试user data
在层次结构中使用这个额外的层,希望能够crossmnt
导出正在导出的层次结构中安装的内容。系统似乎并没有抱怨这种尝试。
root@server:~# cat /etc/exports
# Other exports of unrelated directories
/media/user_data *(sec=krb5p,rw,crossmnt)
/media/user_data/unix *(sec=krb5p,rw,crossmnt)
# More unrelated exports
root@server:~# exportfs -ra; zfs share -a
exportfs: /etc/exports [5]: Neither 'subtree_check' or 'no_subtree_check' specified for export "*:/media/user_data".
Assuming default behaviour ('no_subtree_check').
NOTE: this default has changed since nfs-utils version 1.0.x
exportfs: /media/user_data/unix does not support NFS export
root@server:~# showmount -e
Export list for server:
/media/user_data *
/media/user_data/unix *
# <nfs exports of unrelated zfs datasets>
root@server:~#
在下面的文本中,我删除了/media/user_data/unix
in的导出/etc/exports
并运行exportfs -ra
,zfs share -a
以便 NFS 服务器不会抱怨任何不支持 NFS 导出的目录。最后,终端计算机上的 autofs 只需要挂载与其运行的发行版及其版本对应的主目录,以及与local
操作系统和架构对应的子目录,从而在 Linux Debian Buster x86_64 上为 user1 生成以下层次结构。
/home/AD.EXAMPLE.COM/user1[10]/Downloads
/Videos
/.local[11]
我尝试通过下面的 autofs 配置来实现
/etc/auto.master.d/home.autofs
(终端端,Linux Debian Buster,x86_64)
/media/AD.EXAMPLE.COM /etc/auto.AD.EXAMPLE.COM.home --timeout=120
/etc/auto.AD.EXAMPLE.COM.home
(终端端,Linux Debian Buster,x86_64,为 ugo 设置的可执行文件和读取位)
#!/bin/bash
key=$1
distributor()
{
lsb_release -i | cut -f 2 -d : | xargs echo | tr '[:upper:]' '[:lower:]'
}
codename()
{
lsb_release -c | cut -f 2 -d : | xargs echo | tr '[:upper:]' '[:lower:]'
}
architecture()
{
uname -m | tr '[:upper:]' '[:lower:]'
}
os()
{
uname -s | tr '[:upper:]' '[:lower:]'
}
echo '- / -fstype=nfs,vers=4.2,sec=krb5p,fsc server.example.com:/media/user_data/unix/'$key'/home/'$(distributor)'_'$(codename)' \'
echo ' /.local -fstype=nfs,vers=4.2,sec=krb5p,fsc server.example.com:/media/user_data/local/'$key'/local/'$(os)'-'$(architecture)' \'
echo ''
这是上面脚本的输出示例
root@terminal:~$ /etc/auto.AD.EXAMPLE.COM.exp user1
- / -fstype=nfs,vers=4.2,sec=krb5p,fsc server.example.com:/media/user_data/unix/user1/home/debian_buster \
/.local -fstype=nfs,vers=4.2,sec=krb5p,fsc server.example.com:/media/user_data/local/user1/local/linux-x86_64 \
root@terminal:~$
问题
终端计算机上的 Autofs 无法挂载从服务器导出的重建主目录。这是我在尝试列出以下内容时从 automount 获得的跟踪/home/AD.EXAMPLE.COM/user1
:
root@terminal:~# automount -d -f -v
... <lots of output>
get_nfs_info: called with host server.example.com(192.168.80.101) proto 17 version 0x30
get_nfs_info: nfs v3 rpc ping time: 0.000000
get_nfs_info: host server.example.com cost 0 weight 0
prune_host_list: selected subset of hosts that support NFS3 over TCP
mount_mount: mount(nfs): calling mkdir_path /media/AD.EXAMPLE.COM/user1
mount_mount: mount(nfs): calling mount -t nfs -s -o vers=4.2,sec=krb5p,fsc server.example.com:/media/user_data/unix/user1/home/debian_buster /media/AD.EXAMPLE.COM/user1
>> mount.nfs: mounting server.example.com:/media/user_data/unix/user1/home/debian_buster failed, reason given by server: No such file or directory
mount(nfs): nfs: mount failure server.example.com:/media/user_data/unix/user1/home/debian_buster on /media/AD.EXAMPLE.COM/user1
do_mount_autofs_offset: mount offset /media/AD.EXAMPLE.COM/user1/.local at /media/AD.EXAMPLE.COM/user1
mount_autofs_offset: calling mount -t autofs -s -o fd=16,pgrp=20379,minproto=5,maxproto=5,offset automount /media/AD.EXAMPLE.COM/user1/.local
mounted offset on /media/AD.EXAMPLE.COM/user1/.local with timeout 120, freq 30 seconds
mount_autofs_offset: mounted trigger /media/AD.EXAMPLE.COM/user1/.local at /media/AD.EXAMPLE.COM/user1/.local
dev_ioctl_send_ready: token = 114
mounted /media/AD.EXAMPLE.COM/user1
列出的内容什么也/home/AD.EXAMPLE.COM/user1
没有:
root@terminal:~$ ls /home/AD.EXAMPLE.COM/user1
root@terminal:~$
尽管服务器上所谓的挂载目录充满了文件:
root@server:~# ls /media/user_data/unix/user1/home/debian_buster
file1 file2 file3
root@server:~#
上面的自动挂载跟踪暗示服务器上不存在尝试挂载的目录,但这很奇怪,首先因为尝试从服务器列出该确切目录确实显示该目录存在(见上文),并且我可以挂载此目录无论如何,从终端手动操作,如下所示:
root@terminal:~$ mount -vvvv -t nfs server.example.com:/media/user_data/unix/user1/home/debian_buster /mnt
mount.nfs: timeout set for Sat Feb 13 22:37:06 2021
mount.nfs: trying text-based options 'vers=4.2,addr=192.168.80.101,clientaddr=192.168.104.1'
mount.nfs: mount(2): No such file or directory
mount.nfs: trying text-based options 'addr=192.168.80.101'
mount.nfs: prog 100003, trying vers=3, prot=6
mount.nfs: trying 192.168.80.101 prog 100003 vers 3 prot TCP port 2049
mount.nfs: prog 100005, trying vers=3, prot=17
mount.nfs: trying 192.168.80.101 prog 100005 vers 3 prot UDP port 39874
root@terminal:~$ ls /mnt
file1 file2 file3
root@terminal:~$
我对解决方案的尝试
我认为终端上的 autofs 可能找不到要安装的目录,因为它尚未安装在服务器上,因此我尝试使用--ghost
和browser
选项(您可以在上面显示的服务器/etc/auto.master.d/media.autofs
和/etc/auto.AD.EXAMPLE.COM.unix
文件中看到它们),但没有有用。我已经没有办法去探索找到永久解决方案了。
临时解决方法
我目前使用的临时解决方法不是不在服务器端使用 autofs,而是手动绑定挂载所有目录以获得要导出的正确文件层次结构。我对这个解决方案不太满意,因为它需要大量的安装才能永久处于活动状态,并且似乎使服务器处于某种不稳定的状态,尽管我不知道到底为什么。
评论
- 在我的测试中,服务器和终端都运行 Debian Buster (Linux x86_64),并产生了上述痕迹。
- NFS 抱怨 autofs-reconstitutioned 目录不支持 NFS 导出,这暗示我根本不应该尝试通过偷偷导出其父目录来导出它。我找不到任何说明无法 NFS 导出具有 autofs 挂载子目录的目录的参考,因此仍然值得一试。此外,当我
mount --bind
在服务器端手动设置这些子目录而不是使用 autofs 时,它工作得很好,所以应该有一些希望。 - 这是一个相当复杂(并且脆弱?)的设置;如果您有一个更简单(更强大)的建议来实现相同的功能,我也很感兴趣:)
答案1
我似乎默认情况下您的客户端首先尝试 NFSv4。手动安装时,它会回退到 NFSv3。 Autofs 很可能会在第一次失败时放弃。
您也许可以调整默认客户端行为以首先使用 NFSv3。