Один из краеугольных камней архитектуры Inferno — юниксовая идея с файлами-устройствами доведена до предела: в Inferno файлами представлено абсолютно всё. Например, в Inferno нет понятия «сокет».
В Inferno файлами представлены не только устройства (аналог
Например, для того, чтобы открыть tcp-соединение на сайт www.habrahabr.ru, нужно проделать следующие операции:
Пояснения к примерам. Примеры для краткости приведены на sh, а не Limbo.
С переменными окружения работа идёт аналогично — есть каталог
Для доступа к информации по процессам используется каталог
Работа всех этих виртуальных файлов обеспечивается разными средствами — например
Такой подход позволил упростить множество вещей:
Но, с моей точки зрения, гораздо важнее не то, что отпала необходимость в куче сисколов, а то, что «объектов» особенности поведения которых необходимо знать для качественного программирования стало намного меньше! К примеру, в юниксах у файлов одни особенности, у специальных файлов (юникс-сокеты, пайпы, некоторые устройства) другие, а у сокетов третьи — а в Inferno всё это одинаковые файлы с одинаковым поведением.
«Правильная» программа в Inferno должна писаться не в стиле традиционных юниксовых утилит (читаем STDIN, пишем STDOUT), а в стиле файлового сервера Styx. Иными словами входом/выходом у такой утилиты должен быть не STDIN/STDOUT, а виртуальный файл или каталог с файлами а-ля
Это позволит очень легко строить распределённые системы. Например, предположим в нашем проекте есть модуль который что-то считает. Он реализован в виде отдельного процесса, который экспортирует файл
Пространства имён (namespace) в Inferno аналогичны тем, которые используются во многих языках программирования… только в Inferno они применяются к файлам и каталогам.
Фактически привилегии и возможности программы под Inferno ограничены тем, к каким файлам (ибо любой ресурс = файл) она имеет доступ. Манипулируя namespace можно для каждого приложения создать свою, изолированную (а-ля chroot) среду, со своими устройствами в
К примеру, в винде есть такая фича — вы логинитесь с любого компа в сети и получаете СВОЙ рабочий стол и СВОЙ каталог «мои документы». В Inferno вы, залогинившись с любого терминала и имея доступ к своим ключам/сертификатам можете манипулируя namespace создать 100% ту же самую среду, которую вы имеете на своём основном компе. И для реализации этого никаких специальных «фич» в Inferno нет — обычные команды mount, bind и протокол Styx.
Возможно всё это звучит не очень принципиально, но принцип работы с приложениями кардинально изменяется — обычно мы пытаемся добиться того, чтобы приложение работало в самых разных условиях (что значительно его усложняет), а в Inferno мы для каждого приложения с помощью namespace, команд mount и bind создаём именно ту среду, на которую расчитано это приложение.
Файлы
В Inferno файлами представлены не только устройства (аналог
/dev/
) и процессы (аналог /proc/
), но и такие вещи как DNS resolver, сокеты и переменные окружения (environment) (список не полный :)).Например, для того, чтобы открыть tcp-соединение на сайт www.habrahabr.ru, нужно проделать следующие операции:
- открыть файл
/net/cs
- записать в него строку 'tcp!www.habrahabr.ru!http'
- считать из него ответ (это будет строка '/net/tcp/clone 217.147.30.151!80')
- открыть файл
/net/tcp/clone
- считать из него число (идентификатор этого соединения, далее ID), при этом в каталоге
/net/tcp/
автоматически появится новый подкаталог/net/tcp/
ID/
с файламиctl
,data
,status
, etc. - записать в файл
/net/tcp/
ID/ctl
строку 'connect 217.147.30.151!80' - читать/писать файл
/net/tcp/
ID/data
Пояснения к примерам. Примеры для краткости приведены на sh, а не Limbo.
;
— приглашение sh.>[1=0]
— перенаправление STDOUT на STDIN.<>/path
— открытие STDIN на чтение+запись в /path.read
— читает из STDIN и выводит на STDOUT заданное кол-во байт.`{...}
— это выполнить команду и вернуть её вывод.
; { echo -n 'tcp!www.habrahabr.net!http' >[1=0]; read -o 0 8192; } <>/net/cs
/net/tcp/clone 209.85.84.157!80
; { id=`{read}
echo 'connect 209.85.84.157!80' >/net/tcp/$id/ctl
echo 'HEAD / HTTP/1.0' >/net/tcp/$id/data
echo 'Host: www.habrahabr.ru' >/net/tcp/$id/data
echo >/net/tcp/$id/data
read </net/tcp/$id/data
} <>/net/tcp/clone
HTTP/1.1 200 OK
Date: Sun, 27 May 2007 11:33:42 GMT
Server: Apache/2.0.52 (Red Hat)
X-Powered-By: PHP/5.1.4
Set-Cookie: vsid=3X02X521137108; expires=Fri, 25-May-2012 11:33:43 GMT; path=/
Connection: close
Content-Type: text/html; charset=UTF-8
С переменными окружения работа идёт аналогично — есть каталог
/env/
, файлы в котором это имена переменных, а содержимое файлов — значения переменных. Соответственно создание/удаление файла это создание/удаление переменной окружения.Для доступа к информации по процессам используется каталог
/prog/
. Причём абсолютно все операции выполняются через его подкаталоги и файлы — в том числе отладка (т.е. не нужен сискол POSIX ptrace) и получение информации о статусе процесса (т.е. не нужны сисколы wait/waitpid).Работа всех этих виртуальных файлов обеспечивается разными средствами — например
/net/tcp/
и /env/
реализованы через драйвера Inferno, а DNS ресолвер /net/cs
реализован обычным приложением.Такой подход позволил упростить множество вещей:
- для работы с сетью достаточно обычного файлового API, отдельные функции POSIX (socket, connect, bind, listen, etc.) стали не нужны
- аналогично, нет специального API для работы с переменными окружения (clearenv, putenv, setenv, getenv, etc.)
- поскольку протокол Styx позволяет расшаривать файлы по сети, то можно делать, например, следующие трюки:
- если машина в локальной сети, не имеющая реального IP-адреса, подмонтирует себе каталог
/net/
шлюза в инет, то она получит прямой выход в инет без необходимости настраивать на шлюзе штуки типа NAT или маскарада - если на удалённый сервер подмонтировать по сети файлы
/dev/cons
,/dev/keyboard
и/dev/pointer
с рабочей станции, то на сервере можно будет запускать графические приложения которые будут управляться с терминала рабочей станции — и всё это без специального протокола а-ля X-Window!.. плюс получаем встроенную (в Styx) авторизацию, аутентификацию и шифрование - если на локальную машину подмонтировать каталог
/prog/
(аналог/proc/
) с удалённого сервера, то можно будет локальным отладчиком отлаживать процессы выполняющиеся на удалённой машине — и отладчик об этом даже знать не будет, потому что он просто работает через файлы в/prog/
- если машина в локальной сети, не имеющая реального IP-адреса, подмонтирует себе каталог
Но, с моей точки зрения, гораздо важнее не то, что отпала необходимость в куче сисколов, а то, что «объектов» особенности поведения которых необходимо знать для качественного программирования стало намного меньше! К примеру, в юниксах у файлов одни особенности, у специальных файлов (юникс-сокеты, пайпы, некоторые устройства) другие, а у сокетов третьи — а в Inferno всё это одинаковые файлы с одинаковым поведением.
Распределённые вычисления
«Правильная» программа в Inferno должна писаться не в стиле традиционных юниксовых утилит (читаем STDIN, пишем STDOUT), а в стиле файлового сервера Styx. Иными словами входом/выходом у такой утилиты должен быть не STDIN/STDOUT, а виртуальный файл или каталог с файлами а-ля
/net/cs
или /net/tcp/
.Это позволит очень легко строить распределённые системы. Например, предположим в нашем проекте есть модуль который что-то считает. Он реализован в виде отдельного процесса, который экспортирует файл
./calc
, в который можно писать задания и считывать из него результат. Если возникает потребность ускорить вычисления перенеся эту подзадачу на отдельный, более мощный сервер, то достаточно двух шагов: запустить этот модуль на другом сервере; подмонтировать файл ./calc
с этого сервера. И всё — остальная часть проекта даже не заметит что этот модуль выполняется на другом сервере!Namespaces
Пространства имён (namespace) в Inferno аналогичны тем, которые используются во многих языках программирования… только в Inferno они применяются к файлам и каталогам.
Фактически привилегии и возможности программы под Inferno ограничены тем, к каким файлам (ибо любой ресурс = файл) она имеет доступ. Манипулируя namespace можно для каждого приложения создать свою, изолированную (а-ля chroot) среду, со своими устройствами в
/dev/
(как выше в примере с удалённым терминалом), со своими сетевыми картами в /net/
(как выше в примере с NAT), etc.К примеру, в винде есть такая фича — вы логинитесь с любого компа в сети и получаете СВОЙ рабочий стол и СВОЙ каталог «мои документы». В Inferno вы, залогинившись с любого терминала и имея доступ к своим ключам/сертификатам можете манипулируя namespace создать 100% ту же самую среду, которую вы имеете на своём основном компе. И для реализации этого никаких специальных «фич» в Inferno нет — обычные команды mount, bind и протокол Styx.
Возможно всё это звучит не очень принципиально, но принцип работы с приложениями кардинально изменяется — обычно мы пытаемся добиться того, чтобы приложение работало в самых разных условиях (что значительно его усложняет), а в Inferno мы для каждого приложения с помощью namespace, команд mount и bind создаём именно ту среду, на которую расчитано это приложение.