Эмулятор Linux своими руками!

Xakep, номер #047, стр. 047-060-1


Оцени всевозможные прелести Perl

Дмитрий Докучаев aka Forb (dmitry@dokuchaev.com)

Многих могут смутить два заголовка, имеющих, на первый взгляд, мало общего. Но поверь мне – только на первый взгляд, на самом деле общего у них не так уж мало. А что именно - ты узнаешь, если дочитаешь эту статью хотя бы до середины :).

Сага об эмуляторах

Лично меня эмуляторы интересовали всегда - еще задолго до того, как я начал заниматься программированием. Эмуляторы различного рода приставок, spectrum и иже с ними. Занятно переместиться в каменный век :). Но больше всего мне нравились эмуляторы операционных систем.

Я видел много различных эмуляторов *nix, в том числе и портированные бинарники Cygwin. Что-то мне в них нравилось, что-то нет. Поразмыслив, я решил написать свою систему на языке Perl. Аналог Linux. Конечно, я понимал, что замахнулся на нечто грандиозное (для меня, по крайней мере), но - кто не рискует... Сначала я все делал в одном файле. Получалось сумбурно, кроме того, возникла проблема путаницы в собственном коде :). Тогда я начал программить с нуля, используя все возможности Perl. Я пытался придерживаться стандарта Linux, но так как в качестве ядра у меня выступал Windows, пришлось немного поизвращаться (особенно с сигналами).

FLinux - эмулятор нового поколения :)

И вот чудо природы aka Flinux v1.0 появилось на свет :). Перловые скрипты, олицетворяющие собой линуксовые бинарники - в первую очередь login, bash, ps, kill, ls, cat, passwd, su и другие. Вот плюсы и минусы моего эмулятора.

Плюсы:

1) Многопользовательность - Flinux эмулятор легко справляется с несколькими пользователями, так как для каждого выделяется отдельный "tty-файл" и процесс :).

2) Политика прав и безопасности. В своем эмуляторе я реализовал права для отдельного uid и gid пользователя. Как я этого добился - читай далее.

3) Возможность удаленного администрирования - что тебе мешает поставить Telnet server на эмулятор?

Минусы:

1) Ядро - Windows. Таким образом, эмулятор – оболочка, и все права могут сойти на нет (локальная безопасность не гарантирована).

2) Плохая работа с сигналами и межпроцессорном взаимодействии (третье ответвление процесса невозможно, отсутствие конвейеров и т.п.).

3) Медлительность. Единственный минус Perl - медленная работа - может сказаться при какой-либо обработке. Хотя я такого не замечал.

Разумеется, Perl-код доступен каждому для чтения, и ты сможешь в нем разобраться (кое-где я даже вставил комментарии).

Алгоритмы и межпроцессорное взаимодействие

При написании Flinux для меня были важны две вещи - сигналы и права. Так как Windows не умеет толком обращаться ни с тем, ни с другим, я начал придумывать собственные алгоритмы обработки сигналов и прав.

Эмулятор стартуется /bin/login'ом. После успешной аутентификации запускается user-shell. Запускается он fork()'ом. То есть шелл становится потомком логина, что, в общем, логично (при убийстве или завершении работы шелла убивается и логин). Дальше - сложнее. Интерпретатор (bash в моем случае) обрабатывает команды пользователя и (если необходимо) запускает внешние программы (/bin/uname, /usr/bin/passwd, etc). При этом желательно, чтобы каждая программа имела свой собственный процесс и не зависела от других. Сначала я использовал do() для вызова внешних программ (функция do() выполняет perl-скрипт с сохранением всех переменных запускаемого скрипта, но процесс у запущенного скрипта не изменяется). Из-за невозможности выделения процесса от do() пришлось отказаться и использовать system() - функцию, которая запускает новый скрипт, выделяя под него процесс, но не сохраняя старых переменных. Поэтому внешняя программа запускается по типу: system("ПУТЬ/К/FLinux/Perl/скрипт параметры Путь/К/Flinux UserTTY").

Содержание  Вперед на стр. 047-060-2