Сетевая файловая система (NFS)
NFS (Network File System) является, возможно, наиболее заметной сетевой услугой, использующей RPC. Она позволяет обращаться к файлам на отдаленных хостах так же, как пользователь обращался бы к локальным файлам. Это достигается благодаря совмещению функциональных возможностей ядра на клиентской стороне (которая использует удаленную файловую систему) и NFS сервера на стороне сервера (предоставляющего файл данных). Доступ к файлу полностью прозрачен для клиента и работает на различных серверах и архитектурах хостов.
NFS предоставляет ряд преимуществ:
- Данные, к которым обращаются все пользователи, могут быть централизованно сохранены на одном хосте. Например, все учетные записи пользователей можно сохранить на одном хосте, и все клиентские системы могут подключать к нему свой /home каталог. В сочетании с NIS пользователи могут входить в любую систему и работать с одним и тем же набором файлов.
- Данные, занимающие много дискового пространства, можно хранить на одном хосте. К примеру, все файлы и программы, связанные с LaTeX и METAFONT, могут быть сохранены и поддерживаться в одном месте.
- Административная информация может быть централизованно сохранена на одном хосте, устраняя необходимость использования rcp для копирования одного и того же файла на множество машин.
Linux NFS является в основном результатом работы Rick Sladkey, который написал код NFS для ядра и большую часть NFS сервера. Последний был адаптирован из unfsd — сервера NFS для пространства пользователя, первоначально созданного Mark Shand, и hnfs — сервера NFS от Harris, написанного Donald Becker.
Рассмотрим, как работает NFS: клиент может запросить подключение каталога с удаленного хоста к локальному каталогу так же, как и к физическому устройству. Однако синтаксис, используемый для определения удаленного каталога, отличается. Например, чтобы подключить /home с хоста vlager к /users на vale, администратор выполнит следующую команду на vale:
При выполнении команды:
mount -t nfs vlager:/home /users
система пытается установить соединение с mountd, установленным на демоне на хосте vlager через RPC. Сервер проверяет, разрешено ли хосту vale подключать каталог, и, при положительном ответе, возвращает file handle. Этот дескриптор файла будет использоваться для всех последующих запросов к файлам в директории /users.
Когда пользователь обращается к файлу через NFS, ядро системы делает RPC-вызов к nfsd (NFS демон) на серверной машине. Этот запрос содержит дескриптор файла, имя запрашиваемого файла и идентификаторы пользователя и группы для проверки прав доступа. Для обеспечения безопасности, идентификаторы пользователя и группы должны совпадать на обоих хостах.
На большинстве реализаций Unix, функциональность NFS для клиентов и сервера реализована на уровне ядра в виде демонов, которые запускаются при старте системы. Это nfsd на серверной стороне и biod (блок ввода-вывода) на клиентской стороне. Для улучшения производительности, biod выполняет асинхронные операции ввода-вывода, а несколько экземпляров nfsd могут работать параллельно.
Реализация NFS в Linux отличается тем, что клиентский код тесно интегрирован в файловую систему ядра и не требует дополнительного управления через biod. С другой стороны, серверный код полностью работает в пользовательском пространстве, что делает одновременный запуск нескольких серверов сложной задачей из-за проблем с синхронизацией. В текущей реализации Linux NFS также отсутствуют функции чтения вперед и записи назад, однако Rick Sladkey планирует добавить эти функции в ближайшее время.
Одним из ограничений NFS в Linux является то, что ядро Linux версии 1.0 не может выделять память кусками больше 4К. Это означает, что сетевой код не может обрабатывать UDP-датаграммы размером больше примерно 3500 байт. Это приводит к тому, что передача данных к и от NFS-демонов на системах, использующих большие UDP-датаграммы по умолчанию (например, 8К в SunOS), должна быть искусственно уменьшена. Это может негативно сказаться на производительности в некоторых условиях. Это ограничение было устранено в более поздних версиях ядра Linux, и клиентский код был модифицирован, чтобы использовать эту новую возможность.