К середине 80-X годов наметилась тенденция отхода от больших централизованных компьютеров, работающих в режиме разделения времени, и переориентации на сети из небольших персональных машин (как правило, из рабочих UNIX-станций). Пользователям надоели вечно перегруженные "бюрократические" машины с разделением времени, и они стремились перейти на небольшие системы, которые могли обслуживать сами, даже если это влекло за собой потерю в вычислительной мощности. Микрокомпьютеры становились быстрее, и эти потери компенсировались. Такой стиль вычислений остается популярным и сегодня.
При переходе к персональным рабочим станциям, однако, не были учтены некоторые их недостатки. Во-первых, операционная система UNIX была старой и работала в режиме разделения времени; возможности ее адаптирования к новым технологиям, появившимся позже, были весьма ограничены. Графические и сетевые возможности были добавлены к UNIX еще в период ее расцвета и оставались плохо интегрированными и трудноуправляемыми. И самое важное, ранняя ориентация на персональные машины сделала невозможной беспроблемную работу сетей, характерную для старых монолитных систем с разделением времени. Разделение времени способствовало централизации управления и амортизации затрат и ресурсов; при появлении персональных вычислений до предела обострились административные проблемы. Выбор старой операционной системы с разделением времени для работы на этих персональных машинах был бы неоправдан.
Работы по ОС Plan 9 начались в конце 80-х годов. При этом преследовались две цели: система, построенная из дешевых современных микрокомпьютеров, должна была управляться централизованно и при этом быть недорогой. Идея заключалась в том, чтобы построить систему с разделением времени не только из рабочих станций. Различные компьютеры выполняли бы различные задачи: маленькие дешевые машины в офисах могли служить бы терминалами, обеспечивая доступ к большим, центральным, совместно используемым ресурсам, таким как вычислительные и файловые серверы. Очевидными кандидатами на роль центральных машин представлялись появившиеся многопроцессорные системы с разделением памяти.
Проблемы с ОС UNIX были слишком глубоки, чтобы их можно было разрешить, однако некоторые ее особенности могли бы найти в дальнейшем свое применение. Это, в первую очередь, использование файловой системы для координирования именования ресурсов и доступа к ним, даже тех (например, устройств), интерпретация которых как файлов нетрадиционна. Для Plan 9 мы приняли эту идею, построив протокол сетевого уровня, названный 9Р, так, чтобы обеспечить машинам доступ к файлам на удаленных системах. Сверх того, была разработана система наименования, которая позволяет пользователям и их вычислительным агентам строить собственные представления ресурсов в сети. Именно здесь Plan 9 впервые начала отличаться от других операционных систем: ее пользователь строит личную вычислительную среду или заново создает ее тогда, когда пожелает, а не просто осуществляет все вычисления на личной машине. Вскоре стало ясно, что эта модель перспективнее, чем предполагалось, и идеи предварительной обработки пространства имен и трактовки ресурсов как файловой системы были распространены на всю ОС - на процессы, графику и даже на саму сеть.
К 1989 году система стала настолько устойчивой, что ее начали использовать в качестве единственной среды вычислений. Это означало необходимость перенесения многих служб и приложений, которые ранее применялись в ОС UNIX. Мы использовали эту возможность, чтобы пересмотреть многие вопросы, связанные не только с резидентным ядром, которые UNIX, как нам казалось, выполняла недостаточно хорошо. Plan 9 имеет новые компиляторы, языки, библиотеки, оконные системы и разнообразные новые приложения. Многие из старых инструментальных средств были опущены, а те, что оставлены, написаны заново или отлажены.
Почему было необходимо пересмотреть столь многое? Различия между операционной системой, библиотекой и приложением важны для исследователя операционных систем, но неинтересны для пользователей. Для них значение имеет только функциональность. Создавая полностью новую систему, мы смогли решить многие проблемы, которые, по нашему мнению, должны были быть решены. Например, в ядре реально отсутствует "драйвер tty"'. он является результатом работы оконной системы. В современном мире вычислительные системы в силу необходимости являются многоархитектурными и составлены из продуктов многих поставщиков, однако обычные компиляторы и инструментальные средства предполагают, что программа должна быть построена для работы в локальной среде. Важнее, однако, то, что определенным тестом для системы служит вычислительная среда, которую она предоставляет. Обеспечение большей эффективности при работе старых программ - "рабочих лошадок" UNIX - было только делом техники; гораздо более мы были заинтересованы в том, чтобы новые идеи, предлагаемые архитектурой основополагающей системы, способствовали повышению эффективности работы. Таким образом, хотя Plan 9 обеспечивает среду эмуляции для выполнения команд POSIX, это не главное в системе. Большая часть системного ПО разработана в "родной" среде Plan 9.
Полностью обновленная система, безусловно, обладает определенными преимуществами. Во-первых, наша лаборатория имела опыт разработки контроллеров экспериментальных периферийных устройств. Для того чтобы облегчить написание их драйверов, мы хотели иметь систему, которая была бы доступна в исходной форме (чего уже не могла гарантировать UNIX, даже в лаборатории, где она родилась). Кроме того, мы хотели перераспределить нашу работу: это означает, что ПО должно было создаваться децентрализованно. Например, мы могли бы использовать для нашей системы компиляторы С некоторых поставщиков, но, даже если бы мы преодолели проблемы с кросс-компиляцией, у нас возникли бы трудности с перераспределением результата этой работы.
Конструкция
Система построена на трех принципах. Во-первых, ресурсы именуются и к ним можно получить доступ как к файлам в иерархической файловой системе. Во-вторых, имеется стандартный протокол, называемый 9Р, для доступа к этим ресурсам. И, наконец, несвязанные иерархии, обеспечиваемые различными службами, соединяются вместе в единое личное иерархическое пространство имен файлов. Необычные свойства Plan 9 обусловлены целенаправленным последовательным применением этих принципов.
Крупная инсталляция Plan 9 состоит из ряда компьютеров, соединенных в сеть и предоставляющих каждый услуги определенного класса. Совместно используемые многопроцессорные серверы обеспечивают выполнение вычислительных циклов; другие большие машины служат хранилищами файлов. Эти машины расположены в помещении с кондиционированием воздуха и соединены высокопроизводительной сетью. Сети с меньшей пропускной способностью, такие как Ethernet или ISDN, соединяют эти серверы с офисными или домашними рабочими станциями или ПК, называемыми в терминологии Plan 9 терминалами.
Современный стиль вычислений предполагает наличие для каждого пользователя выделенной рабочей станции или ПК. Plan 9 использует принципиально другой подход. Хотя она может функционировать и на рабочей станции с файлами, хранящимися на локальном диске, такая конфигурация не является канонической. Вместо этого машины с дисплеями, клавиатурами и мышами получают доступ к большинству вычислительных ресурсов и систем хранения по сети, становясь терминалами системы, подобно терминалам старой системы с разделением времени. При использовании Plan 9, терминал временно персонализируется этим пользователем. Принцип построения аппаратуры под пользователя здесь не работает: Plan 9 предлагает возможность программными средствами изменить то, как она пользователем воспринимается. Эта подстройка сопровождается приданием публично видимым ресурсам в сети локальных персональных имен. Plan 9 обеспечивает механизм организации персонального представления общего пространства с локальными именами глобально доступных ресурсов. Так как наиболее важными ресурсами сети являются файлы, модель этого представления ориентирована на файлы.
Локальные пространства имен предоставляют способ реализации представления сети "под себя". Все службы, доступные в сети, экспортируют иерархии файлов. Те из них, которые важны для пользователя, собираются вместе в личное пространство имен; не представляющие в данное время интереса игнорируются. Этот стиль использования отличается от "однородного глобального пространства имен". В Plan 9 имеются известные имена для служб и унифицированные имена для файлов, экспортированных этими службами, однако их представление полностью локально. Примером может служить разница между словосочетанием "мой дом" и четко сформулированным точным адресом. Последний может быть использован каждым, тогда как первое используется только в разговорной речи: смысл фразы меняется в зависимости от того, кто и когда ее произносит, однако она считается понятной. Подобным образом в Plan 9 имя /dev/mouse всегда относится к мыши, а /bin/date - это команда вывода даты, но то, какие файлы эти имена представляют, зависит от обстоятельств, например, от архитектуры машины, исполняющей команду date. Plan 9, таким образом, имеет локальные пространства имен, которые подчиняются глобальным соглашениям; именно эти соглашения гарантируют разумное поведение при наличии локальных имен.
Протокол 9Р структурирован как набор транзакций, каждая из которых посылает запрос от процесса клиента локальному или удаленному серверу и возвращает результат. 9Р контролирует файловую систему, а не только файлы; он включает процедуры для различения имен файлов и преобразования иерархии имен файловой системы, предоставляемой сервером. С другой стороны, в отличие от таких систем, как Sprite [7], пространство имен пользователя поддерживается только системой клиента, а не на сервере или с его помощью. Кроме того, доступ к файлам происходит на уровне байтов, а не блоков, что отличает 9Р от таких протоколов, как NFS и RFS. Дальнейшее сопоставление можно найти в работе[13].
Хотя Plan 9 изначально предназначалась для работы с традиционными файлами, ее идеи были распространены и на многие другие ресурсы. Службы Plan 9 по экспорту иерархий файлов включают устройства ввода/вывода, резервного копирования, оконную систему, сетевые интерфейсы и многое другое. Одним из примеров может быть команда файловой системы /proc, которая обеспечивает ясный способ исследования текущих процессов и управления ими. Прекурсорные системы имеют в основе подобную же идею [5], однако в Plan 9 метафора файлов развита много дальше [9]. Модель файловой системы хорошо понятна как разработчикам систем, так и обычным пользователям, так что службы, имеющие файлово-подобные интерфейсы легко построить, понять и использовать. Файлы поступают со знакомыми, унифицированными правилами защиты, наименования и доступа (как локального, так и удаленного), поэтому службы, построенные таким образом, готовы для использования в распределенных системах. (В этом заключается отличие от "объектно-ориентированных" моделей, где с этими аспектами приходится заново иметь дело для каждого класса объектов). В последующих разделах приведены примеры, иллюстрирующие эти идеи на практике.
Представление на командном уровне
Plan 9 предназначена для использования на машинах с дисплеем и функционирующей оконной системой. Она не имеет представления о "телетайпе" в том смысле, какой присущ UNIX. Работа с клавиатурой в основной системе находится на рудиментарном уровне, однако при функционировании оконной системы 8 1/2 [8] текст можно редактировать с помощью операций "вырезать и вклеить" из всплывающих меню, копировать между окнами и т. д. 8 1/2, позволяет редактировать текст в предыдущей, а не только в текущей строке. Редакторские возможности достаточно мощны для перемещения таких специальных функций, как история, в оболочку, для разбивки на страницы и прокрутки и редактирования почты. Окна 8 1/2, не поддерживают адресацию курсора и, кроме одного терминального эмулятора для упрощения связи с традиционными системами, в Plan 9 отсутствует ПО для адресации курсора.
Каждое окно создается в отдельном пространстве имен. Подстройки, произведенные к пространству имен в одном окне, не влияют на другие окна или программы, делая безопасным экспериментирование с локальными модификациями нространства имен, например, подстановку файлов из системы их резервного копирования при отладке. Как только отладка произведена, окно может быть стерто, и все следы экспериментального устройства убраны. Подобные аргументы применяются и к личному пространству, которое каждое окно имеет для переменных окружения, пометок (аналогичных сигналам UNIX) и т. д.
Окна создаются работающей программой, например, оболочкой, со стандартными входом и выходом, связанной с редактируемым текстом окна. Каждое окно имеет также личное побитовое отображение и мультиплексированный доступ к клавиатуре, мыши и другим графическим ресурсам через файлы типа /dev/mouse, /dev/bitblt и /dev/cons (аналогично /dev/tty в UNIX). Эти файлы предоставляются редактором 8 1/2, выступающим в роли файлового сервера. В отличие от системы Х Window, где новое приложение обычно создает новое окно, в котором и исполняется, графическое приложение 8 1/2, обычно выполняется в том окне, где стартует. Возможным и эффективным для приложения является создание нового окна, но это не в стиле системы. В отличие от Х Window, где удаленное приложение для начала выполнения делает сетевой вызов Х-серверу, удаленное приложение 8 1/2, видит файлы mouse, bitblt и cons для окна как обычно в /dev. Оно не знает, локальные ли это файлы, а просто читает и записывает их для управления окном; сетевая связь уже присутствует и мультиплексируется.
Предполагаемый способ использования заключался в запуске с терминала таких интерактивных приложений, как система окон и текстовый редактор, и в запуске приложений с большим объемом вычислений или файлов с удаленных серверов. Различные окна могут исполнять программы на различных машинах по различным сетям, но при эквивалентности пространства имен во всех окнах такой подход является прозрачным: доступны те же команды и ресурсы, с теми же именами, где бы ни исполнялись вычисления.
Набор команд Plan 9 подобен таковому у UNIX. Команды разделяются на несколько обширных классов. Некоторые из них представляют собой новые программы для выполнения старой работы: программы, подобные 1s, cat и другим, имеют знакомые имена и функции, но это новые, более простые их версии. Команда who, например, является командным файлом, а ps - просто 95 строк кода С. Некоторые команды с необходимостью совпадают с их предшественниками в UNIX awk, troff и другие были конвертированы в ANSI С и расширены для обработки Unicode, но все еще представляют собой знакомые инструменты. Другие команды - полностью новые программы, заполняющие старые ниши: командный интерпретатор rc, текстовый редактор sam, отладчик acid и другие заменяют хорошо известные инструменты UNIX, выполняя подобные же функции. Наконец, около половины команд совсем новые.
К системе не предъявлялось требование совместимости. Когда старые команды или обозначения казались достаточно хорошими, мы их сохраняли. Когда это было не так, мы их заменяли.
Файловый сервер
Центральный файловый сервер постоянно хранит файлы и выдает их в сеть как иерархию файлов, экспортированную 9Р. Сервер представляет собой отдельную систему, доступную только через сеть и предназначенную для выполнения своей собственной работы. На нем не выполняется никаких пользовательских процессов, кроме фиксированного набора процедур, скомпилированных в образ загрузки. В отличие от набора дисков или отдельной файловой системы, главная иерархия, экспортированная сервером, представляет собой единое дерево, отражающее файлы на многих дисках. Эта иерархия совместно используется многими пользователями на больших расстояниях через множество сетей. Другие ветви дерева файлов, экспортированные сервером, включают системы специального назначения, например, временную систему хранения и службу резервного копирования.
У файлового сервера три уровня хранения. Центральный сервер в нашей инсталляции имеет буферную память объемом около 100 Мбайт, магнитный диск емкостью 27 Гбайт и дисковод с автоматической сменой WORM-дисков общей емкостью 350 Гбайт как основной накопитель. Магнитный диск - не что иное как кэш-память для WORM-дисковода, а буферная память - кэш для диска; каждый уровень намного быстрее и видит трафик примерно на порядок больший, чем уровень, который он кэширует. Объем адресуемых данных в файловой системе может быть больше, чем объем магнитных дисков, поскольку они являются только кэшем; наш главный файловый сервер имеет около 40 Гбайт активного объема хранения.
Наиболее необычная черта файлового сервера обусловлена использованием WORM-устройства для постоянного хранения. Каждое утро в 5 часов автоматически происходит дамп файловой системы. Система замораживается, и все блоки, модифицированные со времени последнего дампа, становятся в очередь для записи на WORM. После этого служба восстанавливается, и в иерархии всех дампов, когда-либо проведенных, появляется корневой каталог выведенной файловой системы с атрибутом "только для чтения", названный по дате создания. Например, каталог /n/dump/1995/0315 - корневой для образа файловой системы в том виде, каком он был на раннее утро 15 марта 1995 года. Создание очереди из блоков занимает несколько минут, однако процесс копирования блоков на WORM, который происходит в фоновом режиме, может занять часы.
Возможны два способа использования дампа файловой системы. Во-первых, сами пользователи могут непосредственно просматривать дамп или присоединять его участки к своему пространству имен. Например, чтобы выявить причину ошибки, естественно попробовать откомпилировать программу из ее состояния три месяца назад или связать программу со вчерашней библиотекой. Имея ежедневную картину всех файлов, легко обнаружить, когда было сделано конкретное изменение или какие изменения были сделаны в конкретный день. Рискуя делать большие изменения в файлах, пользователи чувствуют себя более свободно, сознавая, что они могут вернуться назад с помощью одной команды копирования. Система собственно резервного копирования отсутствует; вместо нее, имея в арсенале дамп в пространстве имен файлов, проблемы резервного копирования можно разрешить с помощью стандартных инструментальных средств, такие как команды ср, 1s, grep и diff.
Другое (очень редкое) использование - это резервное копирование всей системы. В случае повреждения, активная файловая система может быть инициализирована из любого дампа очисткой дискового кэша и введением установки, чтобы корневой каталог активной файловой системы был копией корневого каталога дампа. Но не надо думать, что все так просто: кроме потерь всех изменений, сделанных после даты дампа, этот метод восстановления приводит к очень медленной работе системы. Кэш должен быть перезагружен из WORM, который намного медленнее, чем магнитные диски. Файловой системе потребуется несколько дней, чтобы перезагрузить рабочий набор и восстановить полную производительность.
Права на доступ к файлам в дампе такие же, какие они были в момент осуществления дампа. Обычные утилиты в дампе имеют обычные разрешения без какихлибо специальных мер. Однако файловая система дампа имеет атрибут "только для чтения", что означает, что в дамп не могут быть записаны файлы независимо от того, каковы права доступа к ним; в действительности, поскольку каталоги являются частью структуры "только для чтения", не могут быть изменены даже разрешения.
После того, как файл записан на WORM-диски, он не может быть перемещен, поэтому наши пользователи никогда не видят сообщения "сотрите, пожалуйста, ваши файлы", и в системе отсутствует команда df. Мы считаем дисковод WORM неограниченным ресурсом. Единственный вопрос заключается в том, сколько времени потребуется на его заполнение. Наш накопитель WORM служил сообществу из почти 50 пользователей в течение 5 лет и поглотил ежедневные дампы, заполнив 65% своей емкости. Сейчас его производитель улучшил технологию, удвоив емкость отдельных дисков. Если бы мы перешли на новую среду, мы могли бы иметь больше свободного пространства, чем исходный пустой накопитель. В результате развития технологии емкость систем хранения растет быстрее, чем мы можем ее использовать.
Необычные файловые серверы
Plan 9 характеризуется множеством необычных серверов с файловоподобными интерфейсами. Многие из них реализованы процессами на уровне пользователя, хотя отличие для их клиентов не так уж важно; предоставлена ли служба ядром, процессом пользователя или удаленным сервером не имеет отношения к тому, как она используется. Имеются десятки таких серверов; в этом разделе мы представим описания трех из них.
Возможно, наиболее заметным файловым сервером в Plan 9 можно назвать оконную систему 8 1/2. Она уже рассматривалась подробно [8],но стоит привести здесь ее краткое описание. 8 1/2, обеспечивает два интерфейса: пользователю, сидящему перед терминалом, она предлагает взаимодействие в традиционном стиле с множеством управляемых с помощью мыши и клавиатуры окон, в каждом из которых выполняется приложение. Для клиентских программ вид также достаточно традиционен: программы, выполняющиеся в окне, видят набор файлов в /dev с именами типа mouse, screen и сопя. Программы, которым необходимо напечатать текст в своем окне, производят запись в /dev/cons; чтобы обратиться к мыши, они считывают /dev/mouse. В стиле Plan 9 побитовая графика применятся обращением к файлу /dev/bitblt, куда клиенты записывают кодированные сообщения для исполнения таких графических операций, как bitblt (RasterOp). Необычно то, как это делается: 8 1/2, является файловым сервером, предоставляющим файлы из каталога /dev клиентам, работающим в каждом окне. Хотя каждое из окон выглядит для ее клиентов одинаково, все они имеют отдельные наборы файлов в /dev. 8 1/2, мультиплексирует доступ своих клиентов к ресурсам терминала путем обслуживания множества наборов файлов. Каждому клиенту предоставляется личное пространство имен с различным набором файлов, которые одинаково работают и во всех других окнах. Такая структура имеет много преимуществ. Одно из них заключается в том, что 8 1/2, обслуживает те же файлы, которые необходимы для его собственного внедрения (он мультиплексирует свой собственный интерфейс), и поэтому может работать рекурсивно, как клиент самого себя. Кроме того, рассмотрим внедрение /dev/tty в UNIX, требующее специального кода в ядре для перенаправления вызовов open соответствующим устройствам. Вместо этого в 8 1/2, эквивалентная служба выпадает автоматически: 8 1/2, обслуживает /dev/cons как свою основную функцию; ничего другого он не делает. Когда программа хочет считать с клавиатуры, она открывает /dev/cons, но это личный файл, а не совместно используемый со специальными свойствами. Снова это становится возможным из-за локальности пространства имен; соглашения о совместимости файлов делают эту возможность легко осуществимой.
8 1/2, имеет уникальную особенность, вытекающую из ее строения. Реализуясь как файловый сервер, он обладает возможностью отложенного ответа на запросы чтения для конкретного окна. Эта опция переключается зарезервированной клавишей клавиатуры. Нажав ее один раз, вы приостановите чтение клиента из окна; повторное нажатие восстанавливает нормальное чтение, которое построчно поглощает любой текст. Таким образом, пользователь сможет редактировать многострочный входной текст на экране до того, как приложение видит его; устраняется необходимость включения отдельного редактора для подготовки текста, например, почтовых сообщений. С этим связана и возможность ответа на считывания непосредственно из структуры данных, определяющих текст на дисплее: текст можно редактировать до тех пор, пока его конечная новая строка делает подготовленную строку текста считываемой для клиента. Даже в то время, когда строка считывается, текст, который увидит клиент, может быть изменен. Например, после набора в оболочке, пользователь может вернуться назад на конечную новую строку в любое время, пока не кончится работа make и не появится следующее приглашение оболочки перед rm. Пользователь может прервать выполнение команды rm или даже указать мышью до rm и набрать другую команду, чтобы она исполнялась первой.
В Plan 9 отсутствует команда ftp. Вместо нее файловый сервер на уровне пользователя генерирует вызовы ftpfs к узлу FTP, входит в него от имени пользователя и использует протокол FTP для исследования файлов в удаленном каталоге. Для локального пользователя он предлагает иерархию файлов, присоединенных к /n/ftp в локальном пространстве имен, отражая содержание узла FTP. Такая реализация рискованна: для эффективности ftpfs придется делать некоторый усложненный захват с использованием эвристического подхода для декодирования информации удаленного каталога. Однако результат стоит того: все локальные средства управления файлами, такие как ср, grep, diff и, конечно, 1s, доступны для обслуживаемых FTP-файлов точно так же, как если бы они были локальными файлами. Другие системы, например Jade and Prospero, используют ту же возможность[6,11].
Один сервер, exportfs, является процессом пользователя, занимающим часть его собственного пространства имен и делающим его доступным для других процессов путем трансляции запросов 9Р в системные вызовы ядра Plan 9. Иерархия файлов, которую он экспортирует, может содержать файлы из множества серверов. Exportfs обычно исполняется как удаленный сервер, инициируемый локальной программой, или import, или cpu. Import производит сетевой вызов удаленной машины, затем стартует exportfs и подсоединяется к локальному пространству имен. Например, команда
import helix /net
делает интерфейс сети Helix видимым в локальной директории /proc, позволяя локальным отладчикам исследовать удаленные процессы.
Команда cpu подключает локальный терминал к удаленному серверу CPU. Она работает в направлении, обратном команде import после вызова сервера, она запускает локальную exportfs и встраивает ее в пространство имен процесса на сервере, обычно через вновь создаваемую оболочку. Затем она перекомпонует пространство имен, чтобы сделать локальные файлы устройства (как те, которые обслуживаются оконной системой терминала) видимыми в каталоге сервера /dev. Эффект действия команды cpu сводится, следовательно, к запуску оболочки на быстрой машине с пространством имен, аналогичном локальному, при наличии еще одной, тесно связанной с файловым сервером. Все локальные файлы устройств видимы с удаленной машины, так что удаленные приложения имеют полный доступ к локальным службам, таким как растровая графика, /dev/cons и т. д. Это не то же, что rlogin, которая не делает ничего для воспроизводства локального пространства имен на удаленной системе, и не то же, что совместное использование файлов при работе, например, с NFS, при котором можно достичь некоторой эквивалентности пространства имен, но не такой же комбинации доступа к локальным аппаратным устройствам, удаленным файлам и удаленным ресурсам вычислительного сервера. Команда cpu является уникальным прозрачным механизмом. Например, разумно запустить систему окон в окне с работающей командой cpu; все окна, созданные в нем, автоматически запускают процесс на вычислительном сервере.
Конфигурируемость и управление
Однородные взаимные связи компонентов в Plan 9 делают возможным конфигурирование инсталляции Plan 9 многими различными способами. Один ПК-лэптоп может функционировать как отдельная система Plan 9, использующая локальный диск для хранения файлов; в другом предельном случае наша система имеет центральные многопроцессорные вычислительные серверы, файловые серверы и множество терминалов в диапазоне от небольших ПК до графических станций высокого уровня. Именно на таких больших системах наилучшим образом проявляется работа Plan 9.
Системное ПО переносимо, и та же самая операционная система может выполняться на любой аппаратуре. Кроме производительности, проявления системы на, скажем, рабочей станции SGI, будут такими же, как и на ноутбуке. Поскольку вычислительные и файловые серверы централизованы, а терминалы не имеют постоянного места хранения файлов, все терминалы функционально идентичны. Таким образом, Plan 9 обладает одним из хороших качеств старых систем с разделением времени, когда пользователь может сидеть перед любой машиной и видеть одну и ту же систему. В современном сообществе рабочих станций имеется тенденция, когда машины принадлежат людям, которые подстраивают их под себя путем хранения личной информации на локальном диске. Мы отвергли этот стиль использования, хотя сама система может быть использована и таким образом. В своей группе мы имеем лабораторию с множеством машин с публичным доступом - терминальную комнату, - и пользователь может работать за любой из них.
Центральные файловые серверы централизуют не только файлы, но и их администрирование и обслуживание. В действительности один сервер является главным, содержащим все системные файлы; другие серверы обеспечивают дополнительное место для хранения или доступны для отлаживания и другого специального использования, однако системное ПО размещено на одной машине. Это означает, что каждая программа имеет единственную копию двоичного кода для каждой архитектуры, так что инсталляция новых версий и поиск ошибок достаточно тривиальны. Имеется также единственная база данных пользователя; нет необходимости синхронизировать отдельные файлы /etc/passwd. С другой стороны, зависимость от единого центрального сервера не ограничивает размер инсталляции и непрерывность сервиса. Хотя центральный сервер обычно остается включенным в течение месяцев, когда он выключен, зависящие от него машины не могут функционировать.
Другим примером мощи централизованной файловой службы является то, как Plan 9 управляет сетевой информацией. На центральном сервере существует директория /lib/ndb, которая содержит всю информацию, необходимую для управления локальной сетью Ethernet и другими сетями. Все машины используют для обращения к сети одну и ту же базу данных; нет необходимости управлять распределенной системой наименований или сохранять параллельные файлы до последнего момента. Чтобы инсталлировать новую машину в локальную сеть Ethernet, надо выбрать имя и IP-адрес и добавить их к единственному файлу в /lib/ndb; все машины в инсталляции смогут обратиться к ней сразу же. Чтобы начать работу, подсоедините машину к сети, включите ее и используйте ВООТР и TFTP для загрузки ядра. Все остальное произойдет автоматически.
Наконец, автоматический дамп файловой системы освобождает всех пользователей от необходимости обслуживать свои системы, предоставляя легкий доступ к файлам резервного копирования без лент, специальных команд или привлечения персонала поддержки. Трудно переоценить улучшение образа жизни, обеспечиваемое этим сервисом.
Plan 9 работает на множестве аппаратных средств без ограничения на конфигурацию инсталляции. В нашей лаборатории мы выбрали использование центральных серверов, поскольку при этом снижаются расходы и облегчается управление. Признаком того, что такое решение является правильным, является то, что наши дешевые терминалы оставались удобным местом для работы в течение пяти лет, намного дольше, чем рабочие станции, которые должны обеспечивать полную вычислительную среду. Мы, однако, обновили центральные машины, так что производительность вычислений даже со старых терминалов Plan 9 со временем повысилась. Средства, сэкономленные за счет отказа от обычного обновления терминалов, были потрачены на новейшие, самые быстрые многопроцессорные серверы. Мы считаем, что эти затраты составляют примерно половину стоимости рабочих станций в сети, но обеспечивают общий доступ к более мощным машинам.
Программирование на Си
Утилиты Plan 9 написаны на нескольких языках. Некоторые из них представляют собой сценарии оболочки, rc [2], многие написаны на новом языке-конкуренте, подобном С, названном Alef и описанном ниже. Большая же часть написана на диалекте ANSI С. Из них большинство являются полностью новыми программами, однако происхождение некоторых идет от UNIX-кода, предшественника ANSI С. Эти части были обновлены до ANSI С и переработаны для большей мобильности и чистоты.
Диалект Plan 9 имеет некоторые небольшие добавления, описанные ранее [10], и несколько основных ограничений. Наиболее важные из них - это требование компилятора, чтобы все определения функций имели прототипы ANSI и все вызовы функций появлялись в контексте прототипной декларации функций. Как стилистическое правило, прототипная декларация помещена в файл заголовка, включенный во все файлы, которые вызывают функцию. Каждая системная библиотека имеет ассоциированный файл заголовка, декларирующий все функции в этой библиотеке. Например, стандартная библиотека Plan 9 называется libc, так что все файлы-источники включают
Другое ограничение заключается в том, что для компиляторов С приемлем только поднабор препроцессорных директив, требуемых ANSI. Основное опущенное звено - #if, поскольку мы считаем, что оно никогда не было необходимым и часто использовалось неправильно. Кроме того, его эффект лучше достигался другими средствами. Например, #if, используемый для переключения характеристик во время компиляции, может быть переписан как обычный оператор if, основанный на свертке с константой времени компилирования и исключении мертвого кода для отбрасывания объектного кода.
Условная компиляция, даже с #ifdef, в Plan 9 используется как резервная. Единственные зависимые от архитектуры операторы #ifdef в системе находятся в процедурах низкого уровня в графической библиотеке. Мы избегали таких зависимостей или, когда это было необходимо, выделяли их в отдельные файлы-источники или библиотеки. Кроме того, что применение #ifdef делает код трудночитаемым, становится невозможным узнать, какой источник скомпилирован в двоичный вид или будет ли источник, защищенный ими, компилироваться или работать правильно. Они также затрудняют поддержку ПО.
Стандартная библиотека Plan 9 перекрывается во многом с ANSI С и POSIX, но расходится с ними при адаптации к целям или реализации Plan 9. Когда изменялась семантика функции, мы изменяли также и имя. Например, вместо оператора UNIX create, Plan 9 имеет функцию create, которая воспринимает три аргумента - два исходных, плюс третий, который, подобно второму аргументу open, определяет, должен ли возвращенный дескриптор файла быть открыт для чтения, записи или того и другого. Такой подход был вынужденным из-за способа, которым 9Р выполняет создание, однако он упрощает также общее использование create для инициализации временного файла.
Другое отступление от ANSI С заключалось в том, что Plan 9 использует 16-разрядный набор символов, называемый Unicode. Хотя мы совершенно прекратили полную интернационализацию, Plan 9 обрабатывает представление всех основных языков однородно по всему своему ПО. Для упрощения обмена текстами между программами, символы скомпонованы в поток битов путем сконструированной нами процедуры кодировки, названной UTP-8, которая в настоящее время начинает приниматься в качестве стандартной. Она имеет несколько привлекательных свойств, включая независимость от порядка байтов, обратную совместимость с ASCII и легкость внедрения.
Существует много проблем в адаптировании существующего ПО к большому набору символов с кодировкой, которая описывает символы переменным количеством байтов. ANSI С обращается к некоторым из этих аспектов, однако не решает их все. В этом диалекте нельзя выбрать кодировку набора символов и определить все необходимые библиотечные процедуры ввода/вывода. Более того, функции, которые определить можно, имеют технические проблемы. Поскольку этот стандарт оставляет слишком много проблем нерешенными, мы решили создать свой собственный интерфейс.
Небольшой класс программ Plan 9 не следует соглашениям, обозначенным в этом разделе. Это программы, импортированные из сообщества UNIX или им поддерживаемые; представительным их примером является tex. Чтобы избежать многократного конвертирования таких программ всякий раз, когда выпускается новая версия, мы создали переносимую среду, названную ANSI C/POSIX Environment (АРЕ) [13]. АРЕ включает отдельные файлы, библиотеки и команды, соответствующие насколько можно более точно спецификациям ANSI С и базового POSIX. Для возможности переносимости сетевого ПО, такого как Х Window, к этим спецификациям было необходимо добавить некоторые дополнения, такие как сетевые функции BSD.
Переносимость и компиляция
Plan 9 переносима на множество процессорных архитектур. В рамках одного сеанса расчетов, общим правилом является использование нескольких архитектур. Возможна оконная система, работающая на процессорах Intel, соединенных с вычислительным сервером на основе MIPS с файлами, размещенными на системе SPARC. Для прозрачности такой разнородной системы должны существовать соглашения относительно обмена данными между программами; чтобы поддержка ПО была прямой, должны быть соглашения о кросс-платформной компиляции.
Чтобы избежать проблем с порядком байтов, данные передаются между программами как тексты всякий раз, когда это оправдано. Иногда, однако, объем данных достаточно велик для того, чтобы был необходим двоичный формат, такие данные передаются как поток байтов с заранее определенным кодированием многобайтовых значений. В редких случаях, когда формат достаточно сложен, чтобы определяться структурой данных, эта структура никогда не передается как единый блок; вместо этого она раскладывается на индивидуальные поля, закодированные как упорядоченный поток данных, и затем переупорядочивается реципиентом. Эти соглашения влияют на данные в диапазоне от информации о состоянии ядра или прикладной программы до промежуточных объектных файлов, сгенерированных компилятором.
Программы, включая ядро, часто представляют свои данные через интерфейс файловой системы - механизм доступа, который изначально переносим. Например, библиотечная функция time (системный вызов time отсутствует) читает файл и конвертирует его в двоичный. Подобным же образом, вместо кодирования состояния прикладного процесса в серии флагов и битов в персональной памяти, ядро представляет текстовую последовательность в файле, называемом status в файловой системе /proc, ассоциированной с каждым процессом. Команда Plan 9 ps тривиальна: она распечатывает содержимое файлов статуса после некоторого небольшого переформатирования; более того, после команды
import helix /proc
локальная команда ps выдает отчет о состоянии процессов Helix.
Каждая поддерживаемая архитектура имеет свой собственный компилятор и загрузчик. Компиляторы С и Alef производят промежуточные файлы, которые для переносимости закодированы; их содержимое уникально для конечной архитектуры, однако формат файла независим от типа компилирующего процесса. Когда компилятор для данной архитектуры откомпилирован на процессоре другого типа и затем использован для компиляции программы там же, то промежуточный файл, созданный на новой архитектуре, будет идентичен таковому, созданному на другом процессоре. С точки зрения компилятора, каждая компиляция является кросс-компиляцией.
Хотя загрузчик в каждой архитектуре воспринимает только промежуточные файлы, производимые компиляторами для этой архитектуры, такие файлы могли бы быть сгенерированы компилятором, исполняемым на процессоре любого типа. Например, возможно выполнение компилятора MIPS на процессоре 486, а затем использование загрузчика MIPS на SPARC-станции для получения исполняемого на MIPS файла.
Поскольку Plan 9 работает на множестве архитектур, даже одиночная инсталляция, различающая имена компиляторов и промежуточных файлов, упрощает многоархитектурную разработку из единого дерева-источника. Компиляторы и загрузчик для каждой архитектуры имеют уникальные имена; команда сс отсутствует. Имена получаются путем конкатенации символа кода, ассоциированного с конечной архитектурой, с именем компилятора или загрузчика. Например, символ кода для процессоров Intel x86 - "8", соответствующий компилятор С назван 8с, компилятор Alef - 8al, а загрузчик - 81. Подобным же образом, промежуточные файлы имеют суффиксы .8, а не .о.
Plan 9 создает программу mk, родственную make, читает имена текущей и конечной архитектур из переменных среды, названных 8cputype и $objtype. По умолчанию, текущий процессор является целевым, однако подстановка $objtype в имя другой архитектуры перед вызовом mk приводит к кросс-созданию:
objtype=sparc mk
создает программу для архитектуры SPARC независимо от исполняющей машины. Значение $objtype выбирает файл зависящих от архитектуры определений переменных, который конфигурирует создание для использования соответствующих компиляторов и загрузчика. Эта методика, хотя и простая по идее, хорошо работает и на практике: все приложения в Plan 9 созданы из единого дерева-источника и возможно создание различных параллельных архитектур без конфликтов.
Окончание в следующем номере.
Литература
1.American National Standards for Information Systems - Programming Language С, American National Standards lnstitute, lnc., New York, 1990.
2. АТ&T Bell Laboratories, UNlX Time-Sharing System Programmer's Manual, Research Version, English Edition, Volume 1, Murray Hill, NX, 1985.
3. Том Duf, Rc - А Shell for Plan 9 and UNlX systems, Proc. of the Summer 1990 UKUUG Ccmf., London,July, 1990, рр.21-33.
4. IEEE, Information Technology - Portable Operating System Interface (POSIX) Part 1: System Application Program Interface (API) [С Language], New York, 1990.
5. T.J. Killian, Processes as Files, USENlX, Summer 1984 Conf. Proc., June 1984, Salt Lake City, UT.
6. В. Clifford Neuman, The Prospero File System, USENlX File Systems Workshop Proc., Ann Arbor, 1992, рр.13-28.
7. John Ousterhout, Andrew Cherenson, Fred Douglis, Mike Nelson, and Brent Welch, The Sprite Network Operating Systems Operating System, IEEE Computer, 21(2), 23-38, Feb. 1988.
8. Rob Pike, 8 1/2, the Plan 9 Window System, ESENIX Summer Conf. Proc., Nashville, June, 1991, рр. 257-265.
9. Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom, The Use of Name Spaces in Plan 9, Ор. Sys. Rev., Vol. 27, No. 2, April 1993, рр. 72-76.
10. Rob Pike,How to use thePlan 9 CCompiler,P1an 9 Programmer's Manual, Volume 2, АТ&Т Bell Laboratories, Murray Hill, N, 1995.
11. Herman Chung-Hwa Rao, The Jade File System, (Ph D. Dissertation), Dept. of Сомр. Sci, University of Arizona, TR 91-18.
12. Robert W. Scheifler and Jim Gettys, The Х Window System, АСМ Trans. on Graph, 5(2), рр. 79-109, 1986.
13. Howard Trikey, АРЕ - The ANSI/POSIX Environment, Plan 9 Programmer's Manual, Volume 2, АТ&Т Bell Laboratories, Murray Hill, NJ, 1991.
14. Brent Welch, А Comparison of Three Distributed File System Architectures Vnode, Sprite, and Plan 9, Computing Systems, 7(2), рр. 175-199, Spring, 1994.
(c) 1995, AT&T.
(c) 1995, USENIX Association Plan 9 from Bell Labs, Rob Pike, Dave Presotto, Sean Dorward, Bob Flandrena, Ken Thompson, Howard Trickey, Phil Winterbottom, Computing Systems, v. 8, n. 3, pp. 221-254.