Эта проблема сводила меня с ума.
У меня есть сервер NFS с общими ресурсами NFS, установленными на различных клиентах. Однако всякий раз, когда мне приходится перезагружать сервер NFS, я неизменно получаю кучу ошибок «Устаревший дескриптор файла» при монтировании на всех моих клиентах, что вынуждает меня вручную размонтировать и перемонтировать мои общие ресурсы NFS на клиентах.
Я проверил свой экспорт на моем сервере NFS с помощью cat /etc/exports
и я передаю один и тот же fsid для каждого экспорта NFS при перезагрузке.
Мои вопросы:
/etc/fstab:
[NFSserver]:/mnt/backup /mnt/backup nfs bg,nfsvers=3,tcp 0 0
За эта почтабыло предложено добавить hard
и intr
варианты монтирования, но это, похоже, не имело никакого значения.
Заранее спасибо.
-Гаечный ключ
Вы используете NFS версии 3, для которой требуется несколько вспомогательных служб в дополнение к основной службе NFS в порту 2049. Одна из них - rpc.statd
, который играет ключевую роль в обнаружении перезагрузок и восстановлении / снятии блокировок NFS после перезагрузки.
Эти вспомогательные службы могут располагаться в случайных портах, и они обнаруживаются при обращении к сопоставителю портов RPC (обычно к процессу с именем rpcbind
на современных Linux). В современных сетях с брандмауэрами такое поведение может усложнить задачу: даже если вы можете найти их в портах с детерминированным внешним видом после перезагрузки, они могут быть выделены совсем другим номерам портов, если / когда вы перезапустите службы NFS.
К счастью, во многих современных Unix-подобных системах вы можете заблокировать номера портов диспетчера блокировок NFS (исторически rpc.lockd
, в настоящее время обычно реализуется в ядре), rpc.statd
и rpc.mountd
. Это важно, если вы хотите передать NFSv3 через брандмауэры с какой-либо надежностью.
Для RHEL и связанных дистрибутивов вы можете заблокировать номера вспомогательных портов NFS, добавив эти строки в /etc/sysconfig/network
:
LOCKD_TCPPORT=4045
LOCKD_UDPPORT=4045
STATD_PORT=4046
MOUNTD_PORT=4047
Для Debian и связанных дистрибутивов вы можете добавить эту строку в /etc/modprobe.d/nfs.conf
:
options lockd nlm_udpport=4045 nlm_tcpport=4045
... и эта строка в /etc/default/nfs-common
:
STATDOPTS="-p 4046"
... и эта строка в /etc/default/nfs-kernel-server
:
RPCMOUNTDOPTS="-p 4047" # you may want to add a --manage-gids option here
(При желании вы можете использовать другие номера портов, но 4045 является портом по умолчанию для диспетчера блокировок NFSv3 в Solaris и жестко запрограммирован для него в HP-UX 11.31.)
Но в протоколе NFSv3 есть еще один подводный камень. Хотя вы можете успешно смонтировать общий ресурс NFS, используя только IP-адреса, протокол блокировки NFSv3 внутренне использует имена хостов. И клиент, и сервер должны знать друг друга по правильным именам, иначе блокировка файлов NFS и восстановление блокировки после перезагрузки не сработают. И "правильное имя" для каждой системы - это имя, сообщенное uname -n
.
Так что если uname -n
возвращается server.example
на сервере и соответственно client.example
на клиенте, то вы должны убедиться, что эти точные имена будут разрешаться в IP-адреса, которые хосты должны использовать для NFS. Другими словами, сервер должен иметь возможность связываться с клиентским rpc.statd
используя имя client.example
и наоборот.
Если вы этого не сделаете, сначала может показаться, что все работает хорошо ... но при любой из конечных перезагрузок вы можете получить эти Stale file handle
ошибки.
В дополнение к отличному ответу от @telcoM я хотел бы предложить два других возможных решения:
смонтировать nfs с помощью noac
вариант (помните, что это воля вызвать потерю производительности при выдаче ls
в большом каталоге или stat
на многих файлах)
используйте NFS v4.1 (v4.0 имеет некоторые ошибки, приводящие к «обработке устаревших файлов», поэтому обязательно выберите протокол v4.1).