/sys/doc/ Documentation archive

Использование пространства имен в Plan 9

Роб Пайк
Дейв Пресотто
Кен Томпсон
Говард Трики
Фил Уинтерботтом
Bell Laboratories, Murray Hill, NJ, 07974 USA

АБСТРАКТНО

Plan 9 — это распределенная операционная система, созданная в научно-исследовательском центре вычислительной техники AT&T Bell Laboratories (сейчас Lucent Technologies, Bell Labs) несколько лет тому назад. Цель проекта — представление качественной системы для разработки программного обеспечения и общих вычислений, используя разнородные аппаратные средства и минимум программных. Аппаратной основой Plan 9 являются CPU и файловые серверы, соединенные высокоскоростными сетями. Низкоскоростные сети используются для терминалов, которые представляют собой машины класса рабочих станций. Проект Plan 9 показал, что из нескольких тщательно реализованных абстракций можно построить небольшую операционную систему, обеспечивающую поддержку для больших систем на разнотипных архитектурах и сетях. Программная основа системы построена на двух идеях: пространства имен процессов и простой, ориентированный на сообщения протокол файловой системы.

Операционная система для CPU серверов и терминалов имеет традиционное ядро: скомпилированный образ, содержащий код управления ресурсами и процессами, виртуальной памятью и вводом-выводом. Так как файловый сервер является отдельной машиной, его ядро включает управление пространствами имен и атрибутами процессов, но не включает саму файловую систему. Ядро для многопроцессорной машины SGI Power Series занимает 25 тыс. строк кода на С, наибольшая часть которого — код для четырех типов сетей, включая Ethernet с блоком Internet протокола. Менее 1,5 тыс. строк специфичны для машины, и функциональное ядро с минимумом ввода-вывода могут быть собраны вместе в итоговых 6 тыс. строк. [3]

Система сравнительно небольшая по нескольким причинам. Первая, система полностью новая: не было необходимости и времени для обрастания как многочисленными исправлениями, так и характеристиками других систем. Также, кроме сетевого протокола, система не придерживается внешнего интерфейса, в частности, она не совместима с Unix(!). Темпы развития экономики руководили тщательным выбором всех сервисов и интерфейсов. И наконец, по возможности, Plan 9 строилась на двух принципах: каждый ресурс в системе, будь то локальный или удаленный, представлен в виде иерархической файловой системы; пользователь или процесс создают свой вид системы путем сбора пространств имен файлов, которые соединяют эти ресурсы. [2]

Файловый протокол

Все ресурсы в Plan 9 выглядят как файловые системы. Это не означает, что они являются хранилищами для постоянных файлов на диске, просто их интерфейс файловоподобен. Посредством вызовов чтения и записи выполняются операции поиска файлов (ресурсов) в иерархическом дереве имен, обращение к ним по имени, и получение доступа к их содержимым. Всего в Plan 9 существует дюжины типов файловых систем, но всего несколько из них работают с традиционными файлами. На этом уровне абстракций, файлы в Plan 9 подобны объектам. Если же файлы уже представлены с присваиванием имен, доступом и способами защиты, то они вновь должны быть созданы для объектов.

Интерфейс к файловым системам описан специальным протоколом под названием 9P, аналогичным по функциям с NFS. Протокол 9Р воспринимает файлы как последовательность байт, а не блоков; при соединении с корневым каталогом файлового сервера сообщения 9P управляют иерархией файлов, открывают файлы для ввода-вывода, и читают или записывают произвольные байты в файлы. 9P содержит 17 сообщений: три для инициализации и аутентификации соединения и четырнадцать для управления объектами. Сообщения генерируются ядром в ответ на запросы ввода-вывода пользовательского или ядерного уровней. Опишем в нескольких словах основные типы сообщений. Сообщения auth и attach аутентифицируют соединение и проверяют идентичность пользователя. В результате получается аутентифицированный канал, указывающий на корневой каталог сервера. Сообщение clone выполняет дублирование канала, который затем помещается в файл на сервере с использованием сообщения walk (перемещение по уровням иерархии файловой системы). Сообщения stat и wstat читают и записывают атрибуты в файл, указанный каналом. Сообщение open подготавливает канал для последующих сообщений: read и write — для доступа к содержимому файла, и create и remove — для соответственно создания и удаления файла. Сообщение clunk отвергает канал без влияния на файл. Ни одно из сообщений 9P не производит операций кеширования, при необходимости, файловые кеши предусматриваются или сервером (централизированное кеширование), или путем реализации кеша как прозрачной файловой системы между клиентом и соединением 9P к серверу (клиентское кеширование).

Соединения с локальными ядро резидентными файловыми системами называются устройствами, они являются постоянными, а не удаленными процедурными вызовами. Процедуры отображаются один-в-один с типами сообщений 9P. Локально каждый канал имеет связанную структуру данных, которая хранит тип поля, используемого для индексирования таблицы процедурных вызовов, один комплект на тип файловой системы, аналогично для выбора метода, установленного для объекта. Одно устройство монтирования ядра транслирует вызовы локальных процедур 9P в сообщения RPC для удаленных сервисов, при этом используется отдельный протокол передачи данных наподобие TCP или IL, новый надежный протокол дейтаграмм, или же канал к пользовательскому процессу. Вызовы чтения и записи выполняют передачу сообщений через транспортный уровень. Устройство монтирования считается исключительным мостом между процедурным интерфейсом, который видят пользовательские программы, и сервисами локального и пользовательского уровней. Он выполняет все ассоциированные операции, включая управление буфером и мультиплексирование, и представляет собой единственный неотъемлемый механизм RPC в Plan 9. Устройство монтирования — это эффективный объект полномочий. В системе отсутствует компилятор RPC, взамен устройство монтирования и все серверы используют библиотеку, которая выполняет упаковку и распаковку сообщений 9P.

Примеры

В Plan 9 существует один из типов файловых систем, который служит как средство постоянного хранения данных главного файлового сервера. Это автономная многопроцессорная система включает дисковод с автоматической сменой WORM-дисков общей емкостью 350 GB как основной накопитель, двухуровневый блочный кеш на магнитном диске емкостью 7 GB и 128 MB RAM. Клиенты подключаются к файловому серверу через любые типы сетей и протоколов и, используя 9P, получают доступ к его файлам. Файловый сервер работает с четкой операционной системой, в которой присутствует поддержка пользовательских процессов и стандартный набор команд, доступных в консоли. Все, что он делает, это отвечает на сообщения 9P от клиентов.

Один раз в сутки, в 5:00 утра, файловый сервер выполняет разметку кеш блоков и маркирует dirty блоки копирования-для-записи. Он создает каталог в корне файловой системы и присваивает ему название, используя текущую дату, например 1995/0314. Затем он запускает фоновый процесс копирования dirty блоков на WORM диск. В результате сервер возвращает образ файловой системы, какой она была этим утром. Набор устаревших каталогов доступен при использовании 9P, таким образом, используя обычные команды, клиент может работать с резервными копиями файлов. Благодаря использованию сервиса резервирования, реализованного в виде простой файловой системы, мы получили ряд преимуществ, наиболее очевидное из которых состоит в том, что к файлам возможен доступ обычными командами. К примеру, чтобы увидеть когда была устранена ошибка, выполните команду наподобие этой

Владелец, время доступа, права доступа и другие свойства файлов также являются вспомогательными. Так как это отдельная файловая система, резервирование имеет защитные механизмы, при просмотре резерва нельзя отвергать такую важную вещь как безопасность.

Файловый сервер — это лишь один из типов файловых систем. Большее число необычных сервисов применяются вместе с ядром как локальные файловые системы. Эти сервисы не ограничиваются лишь устройствами ввода-вывода как, к примеру, диски. Они включают сетевые устройства и связанные с ними протоколы, растровый экран и мышь, представление процессов схожих с /proc [1], пары имя/значение, формирующие «окружение», которую получает новый процесс, профилевые сервисы и их ресурсы. Каждый из них представляет собой файловую систему, т.е. каталог, содержащий набор файлов, но эти файлы, все же, отличаются от обычных тем, что они не являются постоянными хранилищами на диске. Взамен, они близки по свойствам к файлам устройств Unix.

К примеру, консольное устройство содержит файл /dev/cons, схожий с /dev/console в Unix. При записи, /dev/cons добавляется к консольному машинописному тексту, при чтении, он возвращает символы, введенные с клавиатуры. Другие файлы в консольном устройстве включают /dev/time — количество секунд с начала эпохи, /dev/cputime — процессорное время, используемое процессом при чтении устройства, /dev/pid — идентификатор процесса, читающего устройство, и /dev/user — логин пользователя, который получил доступ к устройству. Все эти файлы являются текстовыми, так что их использование не влечет проблем с порядком байт. При чтении их содержимые синтезируются по требованию, при записи они вызывают модификации в структурах данных ядра.

Процессовое устройство Plan 9 содержит по одному каталогу на каждый действующий локальный процесс. Эти каталоги получают названия от числовых идентификаторов их процессов: /proc/1, /proc/2, и т.д., каждый из них содержит набор файлов для доступа к процессу. К примеру, в каждом каталоге файла mem находится образ виртуальной памяти процесса, который может быть прочитан или записан для отладки. Файл text представляет собой некий сорт ссылки на файл, из которого будет выполняться процесс, он открывается при чтении таблиц символов для этого самого процесса. Для управления выполнением процесса в файл ctl записываются текстовые сообщения вроде stop или kill. В файле status находится строка специального формата, которая содержит информацию о процессе: его название, владелец, состояние и т.д. Текстовые строки, записываемые в файл заметок, доставляются процессу как специальные сообщения, аналогично сигналам в Unix. Эти сервисы реализованы текстовым вводом-выводом над файлами, а не системными вызовами (наподобие, скажем, kill) или специализированными операциями (наподобие ptrace). Процессовое устройство упрощает реализацию отладчиков и связанных программ. Например, команда

представляет собой необработанную версию программы ps; фактически, ps выполняет лишь реформацию данных, полученных таким образом.

Растровое устройство содержит три файла: /dev/mouse, /dev/screen и /dev/bitblt, обеспечивающих интерфейс для локального растрового дисплея (если таковой имеется) и координатное устройство. Файл mouse возвращает запись специального формата, содержащую 1 байт для состояния кнопки и 4 байта для каждой позиции мыши (координаты по x и y). Если мышь не перемещалась с момента последнего чтения этого файла, последующее чтение будет блокировано. В файле screen находится растровый образ содержимого экрана, а файлом bitblt обеспечивается процедурный интерфейс. Вызовы к графической библиотеке транслируются в сообщения, которые впоследствии записываются в файл bitblt для выполнения операций с растровой графикой. (Это, по существу, вложенный протокол RPC.)

Различные сервисы, используемые процессом, собираются вместе и создают тем самым пространство имен, — единую корневую иерархию файловых имен. Когда процесс раздваивается, порожденный процесс разделяет пространство имен с порождающим. Для управления пространством имен существует несколько системных вызовов — это mount и bind. Вызов

аутентифицирует пользователя и подключает файловое дерево сервиса к каталогу под названием old. Fd — это файловый дескриптор, который хранит открытый соединительный канал для сервиса. Аргумент flags определяет способ подключения к old: (1) замена текущего содержимого; (2) появление перед текущим содержимым каталога; (3) появление после текущего содержимого каталога. Каталог с несколькими подмонтированными сервисами носит название союзного каталога. Вызов

делает часть существующего пространства имен видимым в new, будь то файл или каталог, а также в old. Например, команда

выполняет перекрытие каталога включаемых файлов (include files) с его дамповым содержимым от первого марта.

Создание процесса выполняет системный вызов rfork, его аргумент — битовый вектор, описывает какие атрибуты процесса будут разделены между порождающим и порожденным процессом (взамен их обычному копированию в Unix). Одним из атрибутов является пространство имен, при его разделении, изменения одного процесса оказывают влияние на другой, изменения независимы только при копировании.

Хотя глобального пространства имен и не существует, для нормального функционирования процесса локальные пространства имен должны придерживаться глобальных соглашений. Следует также отметить тот факт, что использование локальных пространств имен критично для системы. Для иллюстрации этих идей подходит использование пространства имен для управления гетерогенностью. Двоичные файлы для данных архитектур находятся в каталоге, который имеет название от типа архитектуры (например, /mips/bin), при работе этот каталог связывается с /bin. (В связи с этим нет нужды в использовании специализированной переменной окружения PATH.) Локальные связи (bindings) также полезны при отладке.

Оконная система [5] — это сервер для файлов типа /dev/cons и /dev/bitblt. Каждый клиент видит четкие копии этих файлов в своем пространстве имен. Каждый пример /dev/cons подается в локальном пространстве окна. Вновь, реализует сервисы, используя локальные пространства имен плюс использование ввода-вывода для стандартно названных файлов. Каждый клиент соединяет свой стандартный ввод, вывод и файлы ошибок с /dev/cons, аналогичные операции используются для доступа к растровой графике. Такая реализация весьма отличается от реализации драйвера /dev/tty в Unix, который выполняется специальным кодом в ядре, перезагружает файл при открытии, со стандартными вводом или выводом процесса. При этом чтобы вести себя предсказуемо с /dev/tty оконная система Unix должна подвергаться специальным преобразованиям.

Среда обеспечивает клиентам точно такую же среду, в которой она сама реализована, т.е. стандартный набор файлов в /dev. Это дает возможность оконной системе запускаться рекурсивно в одном из своих окон, что вновь удобно при отладке. Также это означает, что если файлы экспортируются на другую машину, как будет описано ниже, оконная система или клиентские приложения могут запускаться прозрачно на ней, даже при отсутствии графического оборудования как такового. Этот механизм использовался при реализации оконной системы X Window в Plan 9: X запускается как клиент , часто на удаленной машине с большим количеством оперативной памяти. Мы произвели некоторые подсчеты и выяснилось, что при использовании Ethernet для соединения машин MIPS, коэффициент снижения производительности запуска X на Plan 9 машине равен от силы 10 %, комментарии излишни.

Примером использования этих идей считается файловая система сбора статистики, реализованная командой iostats. Работа этой команды заключается в изоляции процесса в локальном пространстве имен и проверке запросов 9P, идущих от процесса к внешнему миру. После завершения работы iostats выводит использование и файловую активность данного процесса. К примеру, выполнение команды таким образом

выводит сколько ввода-вывода оконная система тратит на растровое устройство, файлы шрифтов и т.п.

Команда import соединяет часть пространства имен удаленной системы с локальным пространством имен. Ее задача заключается в подключении к удаленной машине и запуске на ней процесса, который, используя 9P, обслуживает удаленное пространство имен. Затем она вызывает mount для присоединения этого пространства имен к локальному и, наконец, завершает свою работу. Import часто используется для получения доступа к устройствам, не доступным локально. Например, для записи файла на удаленную дискету можно выполнить следующее

Первая строка импортирует файловое дерево /a: машины lab.pc (которая должна поддерживать 9P) в локальный каталог /n/dos. Вторая посредством простого копирования записывает файл foo на дискету.

Еще одно применение import заключается в удаленной отладке:

делает доступной локально файловую систему процессов машины helix; после этого команды наподобие ps взамен локальным процессам будут иллюстрировать процессы helix, и отладке можно будет поддать удаленный процесс:

Также доступна и кросс архитектурная отладка. Таким образом есть возможность перекрестной отладки процесса машины little-endian i386 на, скажем, big-endian MIPS.

Сетевые интерфейсы реализованы тоже как файловые системы [4]. Например, /net/tcp — это каталог в чем-то схожий с /proc, он содержит набор нумерованных подкаталогов, по одному на каждое соединение. Каждый из каталогов содержит файлы для передачи и управления соединением. Посредством доступа к файлу /net/tcp/clone процесс распределяет новое соединение. Здесь также происходит оценка неиспользуемых соединений. Чтобы сделать вызов, процесс записывает текстовое сообщение вроде «connect 135.104.53.2!512» в файл ctl, а затем читает и записывает файл с данными. Сервис rlogin может быть реализован в нескольких строках кода в оболочке.

Такая структура делает легким сетевое шлюзование. Мы используем машины с интерфейсами Datakit, а не Internet. Вот так

Первая строка использует Datakit для импорта TCP интерфейса с helix, который затем может использоваться непосредственно. Нотация tcp! обязательна, поскольку мы программно используем многочисленные сети и протоколы в Plan 9, здесь она определяет сеть, в которой адрес ai.mit.edu является корректным.

На практике мы не используем ни rlogin, ни telnet между машинами Plan 9, взамен мы пользуемся командой cpu, которая эффективно заменяет процессор в окне на процессор другой машины (типично это быстрый многопроцессорный CPU сервер). Такая реализация воссоздает пространство имен на удаленной машине, используя эквивалент команды import для соединения частей пространства имен терминала с процессом (оболочкой) на CPU сервере, она делает терминал файловым сервером для CPU. CPU-локальные устройства вроде быстрых соединений файловых систем все еще локальны, импортированию поддаются лишь терминало резидентные устройства. Такой механизм чужд как Unix rlogin, который перемещается в четкое пространство имен на удаленной машине, так и разделению файлов с NFS, при котором пространство имен остается без изменений, но процессы выполняются локально. Связи в /bin могут изменяться поскольку меняются процессорные архитектуры, связанные сети также могут отличаться на различном аппаратном обеспечении, при этом получается эффект повышения скорости процессора в текущем пространстве имен.

Позиция

Все вышеописанные примеры иллюстрируют то, как идеи представления ресурсов в виде файловых систем и пространства имен процессов могут использоваться для решения определенного класса проблем, при этом часто приходится прибегнуть к достаточно экзотическим механизмам. Все же в Plan 9 существуют операции, которые не имеют отображения в файловом вводе-выводе. Примером тому операция создания нового процесса, детали создания окружения которого: открытые файлы, использование памяти и т.д. — слишком сложные и описать их в простой операции ввода-вывода очень трудно (почти невозможно). Как результат, новые процессы в Plan 9 создаются довольно стандартными системными вызовами rfork и exec, при этом каталог /proc используется лишь для представления существующих процессов и управления ими.

Plan 9 не отображает сетевые пространства имен в пространство имен файловой системы по нескольким причинам. Во-первых: разные правила адресации для различных сетей и протоколов не могут одинаково отображаться в иерархическое файловое пространство имен. Во-вторых: даже если бы это было возможно, различные механизмы аутентификации, выбора сервисов и управления соединением не смогли бы последовательно отображаться в операции над файлом.

Совместно используемая память это еще один ресурс, который не может быть адекватно представлен в виде файлового пространства имен. Plan 9 имеет механизмы, позволяющие группам локальных процессов распределять и отображать память. Память управляется системными вызовами, а не специальными файлами, при этом ее представление в файловой системе, казалось бы, может подразумевать, что импорт памяти с удаленных машин возможен, но это не так.

И все-таки, несмотря на эти небольшие ограничения, файловые системы и пространства имен предлагают эффективную модель, вокруг которой можно построить распределенную систему. При удачном использовании они могут обеспечить однородный, знакомый, прозрачный интерфейс для разнообразного набора распределенных ресурсов. Они имеют представление о правах доступа, безопасности и схеме присваивания имен. Интеграция устройств в иерархическую файловую систему была отличной идеей в Unix. Plan 9 намного дальше продвигает эти концепции и показывает, что при изобретательном использовании файловые системы имеют много граней для продуктивных исследований.

Литература

[1] T. Killian, Processes as Files, USENIX Summer Conf. Proc., Salt Lake City, 1984
[2] R. Needham, Names, in Distributed systems, S. Mullender, ed., Addison Wesley, 1989
[3] R. Pike, D. Presotto, K. Thompson, H. Trickey, Plan 9 from Bell Labs, UKUUG Proc. of the Summer 1990 Conf., London, England, 1990
[4] D. Presotto, Multiprocessor Streams for Plan 9, UKUUG Proc. of the Summer 1990 Conf., London, England, 1990
[5] Pike, R., 8.5, The Plan 9 Window System, USENIX Summer Conf. Proc., Nashville, 1991

Copyright © 2000 Lucent Technologies Inc. All rights reserved.
Copyright © 2003 Перевод Андрей С. Кухар.