Добавлен: 29.10.2018
Просмотров: 48067
Скачиваний: 190
866
Глава 10. Изучение конкретных примеров: Unix, Linux и Android
Однако в операционной системе Linux данная идея получила дальнейшее развитие.
Основная концепция этой файловой системы заключается в том, что для каждого про-
цесса системы создается каталог в каталоге
/proc
. Имя каталога формируется из PID
процесса в десятичном формате. Например,
/proc/619
— это каталог, соответствующий
процессу с PID 619. В этом каталоге находятся файлы, которые хранят информацию
о процессе — его командную строку, строки окружения и маски сигналов. В действи-
тельности этих файлов на диске нет. Когда они считываются, система получает инфор-
мацию от реального процесса и возвращает ее в стандартном формате.
Многие расширения, реализованные в операционной системе Linux, относятся к дру-
гим файлам и каталогам, расположенным в каталоге
/proc
. Они содержат информацию
о центральном процессоре, дисковых разделах, устройствах, векторах прерываниях,
счетчиках ядра, файловых системах, подгружаемых модулях и многом другом. Неприви-
легированные программы пользователя могут читать большую часть этой информации,
что позволяет им узнать о поведении системы (безопасным способом). Некоторые из
этих файлов могут записываться в каталог
/proc
, чтобы изменить параметры системы.
10.6.4. Файловая система NFS
Сети играют важную роль в операционной системе Linux (и в UNIX-системах вообще)
с самого начала (первая сеть в системе UNIX была построена для переноса новых ядер
с машины PDP-11/70 на компьютер Interdata 8/32). В данном разделе мы рассмотрим
файловую систему NFS (Network File System — сетевая файловая система) корпо-
рации Sun Microsystems, которая используется на всех современных системах Linux
для объединения (на логическом уровне) файловых систем отдельных компьютеров
в единое целое. На данный момент шире всех распространена версия 3 реализации NFS
(введенная в 1994 году). Версия NSFv4 была введена в 2000 году. Она предоставляет
несколько улучшений по сравнению с архитектурой предыдущих версий. Интересны
три аспекта файловой системы NFS: архитектура, протокол и реализация. Мы рассмо-
трим их все по очереди — сначала в контексте более простой версии 3, а затем кратко
обсудим улучшения версии 4.
Архитектура файловой системы NFS
В основе файловой системы NFS лежит представление о том, что пользоваться общей
файловой системой может произвольный набор клиентов и серверов. Во многих слу-
чаях все клиенты и серверы располагаются в одной и той же локальной сети, но это не
требуется. Файловая система NFS может также работать через Глобальную сеть (если
сервер находится далеко от клиента). Для простоты мы будем говорить о клиентах
и серверах так, как если бы они работали на различных компьютерах, хотя файловая
система NFS позволяет каждой машине одновременно быть и клиентом, и сервером.
Каждый сервер NFS экспортирует один или несколько своих каталогов, предоставляя
доступ к ним удаленным клиентам. Как правило, доступ к каталогу предоставляется
вместе со всеми его подкаталогами, так что, фактически все дерево каталогов экс-
портируется как единое целое. Список экспортируемых сервером каталогов хранится
в файле (обычно это файл
/etc/exports
), чтобы эти каталоги экспортировались автома-
тически при загрузке сервера. Клиенты получают доступ к экспортируемым каталогам,
монтируя эти каталоги. Если клиент монтирует (удаленный) каталог, то этот каталог
становится частью иерархии каталогов клиента (рис. 10.20).
10.6. Файловая система UNIX
867
Рис. 10.20. Примеры монтирования удаленных файловых систем. Каталоги показаны на рисун-
ке в виде квадратов, а файлы — в виде кружков
В этом примере клиент 1 смонтировал каталог
bin
сервера 1 в собственном катало-
ге
bin
, поэтому он теперь может сослаться на оболочку как на
bin/sh
и получить обо-
лочку сервера 1. У бездисковых рабочих станций часто есть только скелет файловой
системы (в ОЗУ), и все свои файлы они получают с удаленных серверов (как в данном
примере). Аналогично, клиент 1 смонтировал каталог
/projects
сервера 2 в своем ката-
логе
/usr/ast/work
, поэтому он теперь может получать доступ к файлу
a
как к
/usr/ast/
work/proj1/a
. И наконец, клиент 2 также смонтировал каталог
projects
и тоже может
обращаться к файлу
а
, но уже так:
/mnt/proj1/a
. Как видно из этого примера, у одного
и того же файла могут быть различные имена на различных клиентах, так как он может
монтироваться в различных местах деревьев каталогов. Точка монтирования является
локальной для клиента — сервер не знает, где клиент монтирует его каталог.
Протоколы файловой системы NFS
Так как одна из целей файловой системы NFS заключается в поддержке разнородных
систем, в которых клиенты и серверы могут работать под управлением различных
операционных систем и на различном оборудовании, то весьма существенно, чтобы
интерфейс между клиентами и серверами был тщательно определен. Только в этом
случае можно ожидать, что новый написанный клиент будет корректно работать с су-
ществующими серверами (и наоборот).
В файловой системе NFS эта задача выполняется при помощи двух протоколов клиент-
сервер. Протокол (protocol) — это набор запросов, посылаемых клиентами серверам,
и соответствующих ответов серверов, посылаемых обратно клиентам.
Первый протокол NFS управляет монтированием. Клиент может послать серверу
путь к каталогу и запросить разрешение смонтировать этот каталог где-либо в своей
868
Глава 10. Изучение конкретных примеров: Unix, Linux и Android
иерархии каталогов. Данные о месте, в котором клиент намеревается смонтировать уда-
ленный каталог, серверу не посылаются, так как ему это безразлично. Если путь указан
верно и данный каталог был успешно экспортирован, то сервер возвращает клиенту
описатель
файла (file handle) . Этот описатель содержит поля, однозначно идентифи-
цирующие тип файловой системы, диск, номер i-узла каталога и информацию системы
безопасности. Этот описатель файла используется при последующих обращениях чте-
ния и записи к файлам в смонтированном каталоге или в любом из его подкаталогов.
Во время загрузки операционная система Linux (до перехода в многопользователь-
ский режим) запускает сценарий оболочки
/etc/rc
. В этом сценарии можно разместить
коман ды монтирования удаленных файловых систем. Таким образом, все необходимые
удаленные файловые системы будут автоматически смонтированы прежде, чем будет раз-
решена регистрация в системе. В качестве альтернативы в большинстве версий системы
Linux также поддерживается автомонтирование (automounting) . Эта функция позволяет
ассоциировать с локальным каталогом несколько удаленных каталогов. Ни один из этих
удаленных каталогов не монтируется во время загрузки операционной системы (не про-
исходит даже контакта с сервером). Вместо этого при первом обращении к удаленному
файлу (когда файл открывается) операционная система посылает сообщения всем сер-
верам. Побеждает ответивший первым сервер, его каталог и монтируется.
У автомонтирования есть два принципиальных преимущества перед статическим
монтированием (с использованием файла
/etc/rc
). Во-первых, если один из серверов,
перечисленных в файле
/etc/rc
, окажется выключенным, то запустить клиент будет
невозможно (по крайней мере, без определенных трудностей, задержки и большого
количества сообщений об ошибках). Если пользователю в данный момент этот сер-
вер не нужен, то вся работа окажется просто напрасной. Во-вторых, предоставление
клиенту возможности связываться параллельно с несколькими серверами позволяет
повысить устойчивость системы к сбоям (так как для работы достаточно всего одного
работающего сервера) и повысить производительность (так как первый ответивший
сервер, скорее всего, окажется наименее загруженным).
В то же время при таком подходе неявно подразумевается, что все указанные для
автомонтирования альтернативные файловые системы идентичны. Поскольку файло-
вая система NFS не предоставляет поддержки репликации файлов или каталогов, то
следить за идентичностью всех файловых систем должен сам пользователь. Поэтому
автомонтирование используется, как правило, для таких файловых систем, в которых
клиенту разрешено только чтение. Такие файловые системы обычно содержат систем-
ные двоичные файлы, а также другие редко изменяемые файлы.
Второй протокол NFS предназначен для доступа к каталогам и файлам. Клиенты
могут посылать серверам сообщения для управления каталогами, а также для чтения
и запи си файлов. У них есть также доступ к атрибутам файла, таким как режим, раз-
мер и время последней модификации файла. Файловой системой NFS поддерживается
большинство системных вызовов операционной системы Linux, за исключением (как
ни странно) системных вызовов open и close.
Исключение системных вызовов open и close не случайно. Это сделано преднамеренно.
Нет необходимости открывать файл, прежде чем прочитать его. Также не нужно закры-
вать файл после того, как данные из него прочитаны. Вместо этого, чтобы прочитать
файл, клиент посылает на сервер сообщение lookup (содержащее имя файла) с запро-
сом найти этот файл и вернуть описатель файла, представляющий собой структуру,
10.6. Файловая система UNIX
869
идентифицирующую файл (то есть содержащую идентификатор файловой системы
и номер i-узла вместе с прочей информацией). В отличие от системного вызова open,
операция lookup не копирует никакой информации во внутренние системные таблицы.
Системный вызов read содержит описатель файла (который предстоит прочитать),
смещение в файле (с которого надо начинать чтение), а также требуемое количество
байтов. Таким образом, каждое сообщение является самодостаточным. Преимущество
этой схемы заключается в том, что серверу не нужно помнить (между обращениями
к нему) что-либо об открытых соединениях. Поэтому если на сервере произойдет сбой
с последующей перезагрузкой, то не будет потеряно никакой информации об открытых
файлах, так как ее просто нет. Серверы, которые не поддерживают информации состо-
яния открытых файлов, называются серверами без состояния (stateless) .
К сожалению, методы файловой системы NFS усложняют соблюдение точной файло-
вой семантики системы Linux. Например, в системе Linux файл может быть открыт
и заблокирован, чтобы никакой другой процесс не смог получить к нему доступ. Когда
файл закрывается, блокировки снимаются. В сервере без состояния (таком, как сервер
NFS) с открытыми файлами нельзя связать блокировку, так как сервер не знает, какие
файлы открыты. Следовательно, файловой системе NFS требуется отдельный допол-
нительный механизм осуществления блокировки.
Файловая система NFS использует стандартный механизм защиты UNIX с битами rwx
для владельца, группы и всех прочих пользователей (этот вопрос упоминался в главе 1,
а также будет подробно обсуждаться в дальнейшем). Изначально каждое сообщение
с запросом просто содержало идентификаторы пользователя и группы вызывающей
стороны, которые сервер NFS использовал для проверки прав доступа. То есть сервер
NFS предполагал, что клиенты не будут его обманывать. Несколько лет работы показали,
что такое предположение было (как бы это помягче назвать?) чрезвычайно наивным.
Сегодня для аутентификации клиента и сервера при каждом запросе и ответе можно
использовать шифрование с открытым ключом. При этом злоумышленник не сможет
выдать себя за другого клиента, так как ему не известен секретный ключ этого клиента.
Реализация файловой системы NFS
Хотя реализация кода клиента и сервера не зависит от протоколов NFS , в большинстве
систем Linux используется трехуровневая реализация, сходная с изображенной на
рис. 10.21. Верхний уровень — это уровень системных вызовов. Он обрабатывает такие
системные вызовы, как open, read и close. После анализа системного вызова и проверки
его параметров он вызывает второй уровень — уровень VFS (Virtual File System — вир-
туальная файловая система).
Задача уровня VFS заключается в обслуживании таблицы, содержащей по одной
запи си для каждого открытого файла. Уровень VFS содержит для каждого открытого
файла записи, называемые v-узлами (virtual i-node — виртуальный i-узел). V-узлы ис-
пользуются, чтобы отличать локальные файлы от удаленных. Для удаленных файлов
предоставляется информация, достаточная для доступа к ним. Для локальных файлов
записываются сведения о файловой системе и i-узле, так как современные системы
Linux могут поддерживать несколько файловых систем (например, ext2fs, /proc, FAT
и т. д.). Хотя уровень VFS был создан для поддержки файловой системы NFS, сегодня
он поддерживается большинством современных систем Linux как составная часть
операционной системы (даже если NFS не используется).
870
Глава 10. Изучение конкретных примеров: Unix, Linux и Android
Рис. 10.21. Структура уровней файловой системы NFS
Чтобы понять, как используются v-узлы, рассмотрим выполнение последовательности
системных вызовов mount, open и read. Чтобы смонтировать удаленную файловую си-
стему, системный администратор (или сценарий
/etc/rc
) вызывает программу mount,
указывая ей удаленный каталог, локальный каталог (в котором следует смонтировать
удаленный каталог) и прочую информацию. Программа mount анализирует имя уда-
ленного каталога и обнаруживает имя сервера NFS, на котором располагается удален-
ный каталог. Затем она соединяется с этой машиной, запрашивая у нее описатель файла
для удаленного каталога. Если этот каталог существует и доступен для удаленного
монтирования, то сервер возвращает его описатель файла. Наконец, программа делает
системный вызов mount, передавая ядру полученный от сервера описатель.
Затем ядро формирует для удаленного каталога v-узел и просит клиента NFS
(см. рис. 10.21) создать в своих внутренних таблицах r-узел (удаленный i-узел) для
хранения описателя файла. V-узел указывает на r-узел. Каждый v-узел на уровне VFS
будет в конечном итоге содержать либо указатель на r-узел в клиенте NFS, либо указа-
тель на i-узел в одной из локальных файловых систем (показанный на рис. 10.21 в виде
пунктирной линии). Таким образом, по содержимому v-узла можно понять, является
ли файл (или каталог) локальным или удаленным. Если он локальный, то могут быть
найдены соответствующая файловая система и i-узел. Если файл удаленный, то могут
быть найдены удаленный хост и описатель файла.
Когда на клиенте открывается удаленный файл, то в какой-то момент (при анализе
пути файла) ядро обнаруживает каталог, в котором смонтирована удаленная файловая
система. Оно видит, что этот каталог удаленный, и в v-узле каталога находит указатель
на r-узел. Затем оно просит клиента NFS открыть файл. Клиент NFS просматривает
оставшуюся часть пути на удаленном сервере (ассоциированном со смонтированным