понедельник, 26 декабря 2011 г.

Архитектура ОС Singularity (отзыв на статью)


Прочитал отчет Microsoft Research «Проект Singularity: обзор». Появился ряд мыслей, которыми хочется поделиться.

А. Singularity – это тестовая операционная система, разработанная исследовательской группой Microsoft. При работе над проектом была поставлена такая задача:


«ПО исполняется на платформе, которая эволюционировала последние 40 лет и все чаще демонстрирует свой возраст. Эта платформа представляет собой огромное собрание кода – операционных систем, языков программирования, компиляторов, библиотек и т.д. – и аппаратного обеспечения, на котором исполняются программы. С одной стороны, эта платформа – пример огромного успеха как с финансовой, так и с практической точки зрения. Она лежит в основе 179-миллиардной программной индустрии, и вызвала к жизни такие революционные новинки как Internet. С другой стороны, платформа и работающее на ней ПО куда менее надежны и безопасны, чем хотелось бы большинству пользователей (и разработчиков!).

Отчасти проблема заключается в том, что современная платформа недалеко ушла от компьютерных архитектур, операционных систем и языков программирования 1960-70 годов. Среда вычислений тех времен крайне отличалась от современной. Компьютеры были весьма ограничены в скорости и объеме памяти; они использовались только малыми группами технически грамотных и не злонамеренных пользователей; они редко объединялись в сети или общались с физическими устройствами. Сейчас все не так, но современные архитектуры компьютеров, операционные системы и языки программирования недостаточно изменились для того, чтобы отражать фундаментальные изменения в компьютерах и их использовании.

Singularity – исследовательский проект Microsoft Research, который начался с вопроса: на что была бы похожа программная платформа, если спроектировать ее на пустом месте, и во главу угла поставить не производительность, а надежность? Singularity пытается ответить на этот вопрос, опираясь на усовершенствования в языках и средствах программирования».


Б. Ключевым аспектом Singularity является модель расширения, построенная на SIP’ах (Software Isolated Process). SIP в Singularity – это процессы операционной системы. Они отличаются от обычных процессов более строгим доступом к ресурсам. (Например, SIP – это закрытые объектные, а не адресные пространства.)

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

Чтобы устранить эту лазейку для авторов вредоносных программ, в Singularity создана иная модель расширения. А именно: любое расширение создается в виде отдельного процесса (SIP). Для коммуникации между SIP’ами используются специальные механизмы:

1.       Каналы.
2.       Exchange heap.

Каналы используются для передачи сообщений и небольших порций данных. Exchange heap позволяет передать от одного процесса другому значительную порцию данных.

В. Модель расширения, основанная на SIP’ах, позволяет по-другому взглянуть на типичную многослойную (иерархичную) архитектуру. Подозреваю, что сам взгляд уже далеко не нов, и механизм, описанный ниже, используется в существующих коммерческих операционных системах.

Типичная многослойная архитектура выглядит в виде иерархии слоев, где слой более высокого уровня использует интерфейс слоя, который находится на уровень ниже:

o        Слой N
o        Слой N – 1
§         Слой N – 2

Например, при работе с файлами можно выделить такие слои:

o        Приложение
o        API для работы с файлами
§         Файловая система
·         Драйвер жесткого диска
o        И т.д. (что-нибудь пропустил, но неважно)

Предполагается, что выполнение функции слоя высокого уровня приводит к каскадному вызову функций слоев низкого уровня друг за другом в рамках одного процесса и потока (сверху вниз). Т.е. если пользователь попытался открыть в приложении некоторый файл, то сразу же вслед за этой командой приложение вызовет функцию «Открыть файл» из слоя API, тот, в свою очередь, - обратится к каким-то функциям файловой системы, а те – к драйверу жесткого диска.

На самом деле в современных операционных системах (и в Singularity) все далеко не так. Разные слои могут исполняться в разных процессах (SIP). Так в Singularity существует отдельный процесс для драйвера диска, отдельный процесс для файловой системы и, конечно же, отдельный процесс для самого приложения.

Визуально, слои выполняются последовательно сверху вниз, а в реальности – параллельно. Происходит это так. Функция «Открыть файл» из слоя «API для работы с файлами» формирует сообщение для файловой системы и пересылает его по каналу. А затем – ждет ответа. Поток приложения на этом приостанавливается.

Получив сообщение, файловая система как-то обрабатывает его. Если возникает необходимость, то формирует и посылает новое сообщение слою «Драйвер жесткого диска». Драйвер обрабатывает его и возвращает результат. Получив ответ от драйвера, файловая система формирует свой ответ на запрос из слоя API.

Наконец, слой API, получив ответ от файловой системы, возобновляет выполнение приостановленного потока.

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

В итоге, визуально кажется, что все исполнение происходит в одном процессе и потоке сверху вниз. А в реальности – разные процессы выполняются параллельно.

Основной вывод, который можно сделать из всего этого, таков:

Существует структурная схема (например, многослойная) и существует схема исполнения (последовательная или параллельная). При проектировании системы нужно думать об обеих схемах. Недостаточно просто систему разбить на слои. Нужно еще и продумать, как и кем эти слои будут исполняться.

Если для слишком глубокой иерархии (иерархии, в которой много слоев) использовать последовательную схему исполнения (от верхнего слоя к нижнему), то существует реальный риск написать программу, которая будет зависать в непредсказуемых местах. Т.к. один из слоев может потребовать перераспределения ресурсов, которое займет значительное время.

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

27 февраля 2007 года