27 сентября 2012 г.

Проект LazyCat

Есть один проект, над которым я работаю уже достаточно давно. Проект называется LazyCat. Моей целью в рамках этого проекта является создание системы для администрирования множества (множества в математическом и в обычном смысле) компьютеров, объединённых в сеть.

Идея, которая стоит за данным проектом достаточно проста - если у вас есть много компьютеров, то иногда возникает потребность выполнить какие-то однотипные действия на всех ваших ПК. Или же бывает полезно получить "общую картину" происходящего. Это достаточно просто, когда у вас есть доступ к компьютерам (физический и/или сетевой), и когда компьютеров не много. С ростом количества компьютеров такая задача, как развёртывание программного дистрибутива, становится нетривиальной.

Возьмём наглядный пример.

Университет. Пятница. Вечер. Системный администратор по имени Боб допивает свой кофе и готовится уйти домой. И в тот момент, когда он уже накинул сумку на плечо и собрался уходить, к нему прибегает преподаватель и просит сегодня же установить на все компьютеры в классе номер 21 пакеты Inkscape и Gimp, так как только что стало известно, что в субботу будут проходить курсы по компьютерной графике.

Предположим, в классе 30 компьютеров. На каждый нужно установить необходимые программы и (возможно) произвести некоторую настройку - например, добавить учётные записи для новых пользователей. Итого - требуется выполнить порядка 60 одинаковых действий. Что в такой ситуации может сделать Боб? Он может, во-первых, пойти в класс номер 21 и поставить программы на каждый компьютер в отдельности. Но, поскольку за плечами Боба - годы системного администрирования, то он знает пару полезных трюков. Например, он может со своей машины зайти по SSH на каждый из компьютеров и выполнить установку. Но ему по-прежнему нужно залогиниться на каждый компьютер, выполнить установку и настройку вручную. Лучше, чем бегать от компьютера к компьютеру, но всё ещё не слишком удобно.

Было бы гораздо удобнее, если бы Боб мог отправить команду установки сразу всем компьютерам в классе 21, и получить обратно отчёт, если что-то пошло не так - например, если пакет уже был установлен в системе, или же во время установки произошла ошибка.

Есть достаточно большое количество программного обеспечения, которое решает подобную задачу (в Википедии есть обширный список) - например, Ansible и Puppet.

LazyCat - один из таких инструментов. Он написан на языке C и на Scheme (диалекте Lisp) с использованием Guile. На языке C написано ядро проекта и прокси-сервисы. Под прокси в данном контексте я понимаю процессы, которые непосредственно пересылают сообщение по сети конечному хосту. Графический интерфейс пользователя и высокоуровневая логика написаны на Scheme.

По сути, базовая часть LazyCat является интерпретатором Scheme с дополнительным API. Благодаря использованию Scheme, LazyCat можно легко расширить - например, написать другой интерфейс, добавить функциональность или же использовать его в автоматическом режиме.

Проект находится в разработке и пока не может похвастать большим количеством возможностей. Вот, что сделано на данный момент:

  • Графический интерфейс пользователя на GTK.
  • Выполнение команд на хостах через TCP- и SSH-подключения.
  • Базовый режим "Raw", в котором lazycat отправляет команду на все хосты из списка и отображает необработанный вывод команд.
  • Режим "Diff", при котором результат выполнения команды с каждого хоста сравнивается с результатом выполнения этой же команды с эталонного хоста.
  • Группировка хостов в списке (пока имеет чисто эстетический характер).
  • Сохранение и восстановление списка хостов между сессиями.

В ближайших планах:

  • Отладка.
  • Возможность выбора эталонного хоста перед отправкой команды в Diff-режиме (сейчас выбирается первый хост из списка).
  • Возможность изменять информацию о хосте из графического интерфейса (пока реализовано только API для этого).
  • Возможность отправки сообщений только выбранным хостам из списка, или же группе хостов.
  • Организация списка хостов по типу контакт-листа IM-клиента (за образец думаю взять Pidgin) - статусы, состояния (online/offline) и т.п.
  • Периодический опрос состояния хостов (для отображения их статусов в списке).

Сейчас над проектом работаю я один, just for fun, в свободное от работы время. В связи с этим прогресс идёт достаточно медленно, и проекту не хватает тестирования. Если вас заинтересовал LazyCat и вы можете и хотите поучаствовать в разработке - то вот страница проекта на GitHub, откуда вы можете получить исходный код (под GPLv3) и дополнительную информацию о проекте:

https://github.com/artyom-poptsov/lazycat

- Артём

20 сентября 2012 г.

Сентябрьский месяц над городом N^2

Осенний вечер, сентябрьское небо
Темнеет быстро - вот зажглись огни,
Весь горизонт теперь мерцает светом,
Лишь месяц отрешённо смотрит с высоты.

18 сентября 2012 г.

История Computer Science: Системы с разделением времени

Нашёл крайне интересную документальную видео-запись из MIT, которая относится к тем временам, когда компьютеры были большими и их время стоило несравненно дороже, чем сегодня:

http://hackaday.com/2012/09/17/retrotectacular-time-sharing/

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

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

Да, это всё напоминает то, к чему мы привыкли сейчас. Однако на заре компьютерной эры, когда обычным способом работы с компьютером была пакетная обработка данных, система с разделением времени была гениальной разработкой, которая позволила сделать значительный шаг вперёд.

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

Во-первых, ей нужно подготовить для ЭВМ задание, записанное на магнитной ленте или на перфокартах. После этого она должна загрузить это задание в компьютер. В те времена пользователи часто не имели непосредственного доступа к ЭВМ, так что Алисе, скорее всего, нужно будет отдать её задание программисту по имени Боб (одному из обслуживающего персонала ЭВМ), который поместит задание Алисы в очередь на выполнение.

Теперь Алисе нужно ждать, пока задание будет выполнено (возможно, это займёт пару часов, если на ЭВМ много других заданий). Когда задание будет выполнено, Боб отдаст Алисе распечатку с результатами вычислений. Или же распечатку с программной ошибкой (если что-то пошло не так). Если в программе обнаружилась ошибка, то Алисе нужно будет внести необходимые изменения, создать новое задание, отдать его на выполнение и т.п.

Надеюсь, что ничего не упустил в описании этого алгоритма - к сожалению (или к счастью) я не застал эти времена, так что описываю этот процесс работы на основе информации, полученной из книг и других источников (вроде приведённого выше).

Работа же на системе с разделением времени происходит так, как мы привыкли сегодня - пользователь работает в режиме диалога с компьютером. Он даёт команду компьютеру, компьютер отвечает практически сразу. Если программе требуются входные данные, эти данные вводятся с клавиатуры. Ну а если в программе возникает ошибка, можно сразу же попробовать найти причину ошибки, устранить её и попробовать ещё раз.

Правда здорово?

- Артём

10 сентября 2012 г.

X-сервер в Debian GNU/Hurd и особенности системы

В комметарии к скриншоту из этого [1] поста мне задали два вопроса касательно текущего статуса GNU Hurd. Я решил опубликовать ответ здесь, так как он получился достаточно длинным и он может быть интересен ещё кому-нибудь (кого волнуют эти же вопросы).

Итак, вопрос первый:

> А X сервер на нем заводится?

На сайте Debian GNU/Hurd есть инструкция по запуску X-сервера [2] - судя по всему, сервер должен запускаться без особых проблем. У меня пока не получилось его запустить. Надо будет ещё раз попробовать - возможно, я что-нибудь упустил из виду при настройке.

В качестве подтверждения, что X-сервер действительно работает - вот обсуждение [3] Debian GNU/Hurd, где можно найти скриншоты иксов, работающих на Hurd, запущенном в QEMU.

> Ощущаются ли особенности архитектуры?

Во-первых, надо сказать, что система работает достаточно стабильно (по сравнению с тем, что я видел в Arch Hurd в начале года). Например, исправлена досадная ошибка с "замораживанием" консоли при простое системы (патч оказался достаточно тривиальным [4]).

Однако, в плане производительности Hurd всё ещё отстаёт от Linux - по собственным ощущениям, по крайней мере. При работе с разделами ext2 очень активно нагружает процессор ext2fs сервер (транслятор, в терминологии Hurd), который обеспечивает доступ к разделам с этой ФС - скажем, при aptitude upgrade он ест иногда более 40% CPU.

Вот скриншот с рабочей системы, на котором видно, что ext2fs заметно нагружает CPU (htop запущен через SSH-подключение):

Что интересно, по сути ext2fs представляет собой переписанный драйвер ext2 из Linux (насколько я понимаю), который отражает особенности Hurd - например, его i-node хранят так же информацию о трансляторах, которые являются частью Hurd. В системе даже привычный mount является ни чем иным, как скриптом, который запускает соответствующий транслятор для обслуживания запросов к монтируемому разделу.

Так что ты можешь видеть в ps/top/htop, что творится "под капотом" ОС - работу серверов, которые по сути и превращают микроядро Mach в Hurd.

На тему данную тему есть интересный обзор GNU Hurd с оценкой производительности, который был опубликован в прошлом году на Phoronix [5].

Ссылки:

9 сентября 2012 г.

По поводу концепции микроядерной ОС

Продолжаю наблюдать за развитием GNU Hurd. Напомню, что Debian GNU/Hurd стоит на одном из моих ПК как основная система. Мне интересна концепция микроядерной ОС - разработчики микроядер обещают высокую надёжность и возможность легко расширять и изменять систему под свои нужды.

Надёжность достигается путём переноса большей части функциональности, составляющей собственно ОС, в пространство пользователя. То есть, если в обычных (монолитных) операционных системах драйвер файловой системы является частью ядра ОС, то в микроядерной ОС этот драйвер работает, как обычная программа-сервер, обслуживающая запросы.

Эта концепция напоминает деловые связи, которые возникают в обществе людей. Вот пример: Боб выращивает помидоры в теплицах. Он получает каждую неделю удобрения для помидор от Мэлори. Так же раз в месяц к нему приходит электрик Дэйв, который обслуживает автоматическую систему полива. Если, например, Мэлори заболеет и не сможет обеспечивать какое-то время Боба удобрениями, то Боб может обратиться к Джону (другому поставщику) и тот доставит ему удобрения. То есть, бизнес Боба почти не пострадает от того, что Мэлори заболел, так как он является внешним "сервисом", который Боб использует. С другой стороны, некоторая часть работы выполняется самим Бобом - например, сбор и упаковка помидор перед продажей. Так же в небольшой фирме Боба работает его супруга, Элис - она отвечает за учёт средств и поддержку web-сайта фирмы Боба.

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

Следущим важным моментом является то, что микроядра гораздо меньше по размеру (да, приставка микро- здесь используется не просто так). Так, например, ядро MINIX3 - одной из широко известных микроядерных ОС - содержит примерно 10000 строк кода [1]. Чем меньше кода, тем проще его поддерживать и вылавливать ошибки. Меньше кода, меньше ошибок, надёжнее ОС.

В современном мире уже почти каждый холодильник и телефон работает под управлением ОС и/или может быть подключён к компьютеру. Поэтому многим подобным устройствам необходим драйвер, который обеспечивает взаимодействие с устройством, с его аппаратным обеспечением. В монолитой ОС драйверы включаются в состав ядра и (очевидно) работают в пространстве ядра. Таким образом, драйверы являются "доверенными лицами" ядра. ОС полагается на них, когда нужно взаимодействовать с вашим USB-вентилятором или записать данные на жёсткий диск. Однако, если драйвер работает неправильно, то это может привести (и вероятнее всего, приведёт) к нестабильной работе ядра и всей ОС.

Здесь стоит заметить, что ядро Linux, хотя и монолитно по своей природе, предоставляет механизм "модулей ядра", благодаря которому функциональность ядра может быть расширена "на лету" путём загрузки модулей. Вам не нужно включать в ядро драйверы для _всех_ устройств - вы можете собрать ядро с драйверами только для тех устройств, которые у вас есть. Большинство драйверов так же позволяют скомпилировать их, как модули, которые могут быть загружены в ядро при загрузке или во время работы ОС (как правило, без перезагрузки) - например, при появлении нового устройства.

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

Одним из замечательных примеров надёжности микроядерных ОС явлется так называемый сервер реинкарнации (reincarnation server), который является частью ОС MINIX3, и который автоматически перезапускает серверы, если они по каким-то причинам сбоят и аварийно завершают свою работу [2].

Тем не менее, микроядерные ОС обладают своими недостатками - например, их намного сложнее разрабатывать, и обычно они обладают более низкой производительностью (хотя, например, микроядро L4 достаточно быстро[3]).

Исследования в области микроядер ведуться десятки лет, но на данный момент можно назвать лишь несколько успешных проектов в этой области. Микроядро MINIX и микроядро Mach (третья версия которого лежит в основе GNU Hurd и Darwin) - пожалуй, самые известные.

Всё вышесказанное не претендует на полноту и безошибочность, так как мои познания в этой области являются достаточно скромными. За дополнительной информацией вы можете обратиться к соответствующим статьям в Википедии (например, [4] хорошо написана) и другим источникам.

Ссылки:

GNU Emacs на Debian GNU/Hurd

Сегодня наконец-то запустил GNU Emacs на Debian GNU/Hurd. Emacs версии 23 при запуске у меня выдавал следующую ошибку

$ emacs -nw
emacs: Not a tty device: /dev/tty

Различные попытки запустить Emacs 23 не увенчались успехом.

В списке рассылки нашёл патч [1], который должен был устранить эту проблему. Далее мне нужен был исходный код GNU Emacs, чтобы собрать его с данным патчем.

Однако сначала я решил попробовать более простой путь. Ранее я читал, что данная ошибка была устранена версиях Emacs старше 23.4 (у меня на тот момент была установлена версия 23.2). Поэтому я решил первым делом проверить, не появилась ли более новая версия в репозитории - и обнаружил Emacs версии 24, где ошибка была устранена.

Для меня запуск Emacs на GNU/Hurd был важным рубежом - ведь если у вас есть работающий Emacs в системе, то у вас есть практически всё, что может потребоваться - даже текстовый редактор.

Источники:

  1. http://lists.debian.org/debian-hurd/2011/01/msg00023.html