Процесс INIT — это движущая сила, которая обеспечивает работу компьютера под управлением Linux

Процесс INIT — это движущая сила, которая обеспечивает работу компьютера под управлением Linux, но она может и убить систему. Эта статья расскажет о том, что такое процесс Init, а также поможет узнать, как подчинить поведение этого процесса себе. (Да, Init — это сила, но администратор системы может управлять этой силой).
Вообще-то в UNIX слово "init" не обозначает конкретную программу, скорее всего целый класс программ. Название "init" используется для вызова первого процесса после загрузки системы, первого и единственного процесса. Когда кернел завершает проверку и настройку аппаратного обеспечения компьютера, он вызывает "init" и передает ему контроль над компьютером. С этого момента кернел обрабатывает только системные вызовы ( system calls), не заботясь более о поведении операционной системы. После того как кернел монтирует корневую файловую систему, все контролируется процессом "init".

Сейчас существует несколько способов реализации процесса "init". Вы можете использовать классическую программу Микеля ван Смаренбурга, которая поставляется с модулем SysVinit, simpleinit Питера Орбака (его можно найти среди модулей приложений util-linux), или простой шелловский скрипт (например, тот, который приведен в этой статье, правда, он обладает гораздо меньшими возможностями, чем любое приложение языка С).
Если Вы настраиваете ограниченную изолированную систему, можно выбрать любое приложение, которое будет использоваться в качестве процесса "init". Некоторые мазохисты, которым не нравится многозадачность, могут даже перенести command.com на Linux и запустить его в качестве процесса "init", хотя Вам никогда не удастся ограничить себя 640 Kb оперативной памяти, пока загружен кернел Linux.
Вне зависимости от того, какую программу Вы выбрали, доступ к ней должен осуществляться по пути /sbin/init, /etc/init или /bin/init, так как именно эти пути жестко скомпиллированы в кернел. Если ни одна из этих программ не может быть найдена и запущена на выполнение, система считается неисправной и кернел порождает шелл администратора системы, пользователя root, чтобы дать возможность исправить ситуацию (таким образом, в качестве процесса "init" используется шелл /bin/sh).
Для достижения максимальной гибкости разработчики кернела предоставили возможность выбирать другой, альтернативный путь для запуска процесса "init". Кернел воспринимает командную строку "init=" именно для этой цели. Параметры кернела могут быть переданы интерактивно во время загрузки, либо можно использовать команду "append=" в файле /etc/lilo.conf. Silo, Milo, Loadlin и другие загрузчики также позволяют передавать некоторые параметры кернелу.

Как Вы уже догадываетесь, простейший путь для получения прав доступа супервизора системы и его администратора на компьютере с ОС Linux — это напечатать строку "init=/bin/sh" в ответ на приглашение загрузчика LILO. Учтите, что это не является "прорехой" в безопасности системы, потому что настоящей угрозой безопасности системы является физический доступ к компьютеру и его системной консоли. Если Вы опасаетесь возможности ввода параметров "init=" в процессе загрузки, то сам загрузчик LILO может предотвратить возможность подобного несанкционированного управления при помощи защиты своим собственным паролем.
Задача процесса Init
Мы уже знаем, что имя "Init" не собственное, а, скорее, нарицательное, и его может использовать почти любая программа. Вопрос лишь в том, чем в самом деле должен заниматься "Init"? Будучи первым (и единственным) процессом, выполняемым кернелом, "Init" должен заботиться о запуске всех остальных процессов в системе, включая различные программы-демоны, используемые операционной системой, а также обеспечивать сеансы связи с текстовыми консолями. "Init" также должен перезапускать некоторые из своих порожденных процессов после завершения их работы. Обычно это касается всех сеансов связи через консоли. Как только Вы отключаетесь от системы, она должна вновь запустить программу getty, чтобы предоставить возможность следующего соединения. Кроме этого, "Init" заботится о мертвых процессах и отделывается от них. В соответствии с понятием процессов в UNIX, процесс не может быть удален из системной таблицы процессов, пока о его смерти не будет сообщено процессу, породившему данный процесс (или другому процессу-предку, в случае, если процесс-родитель больше не существует). В случае, если процесс прекращает работу после системного вызова exit, он остается в состоянии зомби-процесса, пока кто-нибудь не позаботится о нем. "Init", будучи предком любого другого процесса, должен собирать информацию о состоянии завершения каждого усыновленного зомби-процесса. Следует отметить, что грамотно написанная программа должна сама заботиться о всех порожденных собой процессах, зомби появляются только как следствие некорректного поведения программ. Если бы "Init" не собирал все зомби-процессы, то ленивые программисты легко и быстро исчерпали бы все системные ресурсы и компьютер с переполненной системной таблицей процессов просто завис бы.

Последняя задача "Init" — забота об отключении системы. Программа "Init" должна остановить все процессы и размонтировать все файловые системы, когда системный администратор решит, что пришло время выключать компьютер. Программа shutdown не делает ничего, она только сообщает процессу "Init", что все закончено.
Как видно, задача "Init" не так уж трудно выполнима, и простой шелловский скрипт может справиться с большинством из поставленных задач. Вспомним, что любой шелл сам прекрасно заботится о порожденных собой же процессах, так что забота об умерших потомках — не проблема для простого скрипта. Но настоящий "Init" должен заниматься контролем над поведением всей системы и выполнять его достаточно эффективно, надежно и быстро.
Использование /bin/sh в качестве минимального выбора

Как говорилось выше, шелл может использоваться в качестве программы "Init". Использование "голого"шелла (init=/bin/sh) просто открывает сеанс связи системного администратора на абсолютно несконфигурированном компьютере. Эта глава описывает, как скрипт шелла может выполнить все задачи, необходимые для работы системы в минимальной конфигурации. Этот вид упрощенной программы "Init" может использоваться в изолированных системах либо в случаях ограничения системных ресурсов, когда нужно экономить каждый бит памяти. Самым радикальным решением для изолированных систем является прямое использование конкретного приложения в качестве процесса "Init", в результате мы получим закрытую систему (без возможности взаимодействия с ее администратором, что, несомненно, вызовет проблемы), но иногда такая конфигурация удовлетворяет конкретным технологическим требованиям. Типичным примером системы Linux без реальной программы "Init" служит установочный диск с дистрибутивом операционной системы, в ней /sbin/init — это символьная ссылка на программу установки.

Листинг 1. Пример скрипта init
#!/bin/sh
# избегаем указания полного пути к именам файлов
export PATH=/usr/bin:/bin:/sbin:/usr/sbin
# монтируем корневую файловую систему только для чтения,
# и все разделы диска
mount — -n -o remount, rw /
mount -a
swapon -a
# протоколирование работы системы
syslog
klogd
# запуск сети
modprobe eth0 2 /dev/null
ifconfig eth0 192.168.0.1
route add 192.168.92.0 eth0
route add default gw 192.168.92.254
# запуск сетевых служб
inetd
sendmail -bd -q30m
# все остальное: crond, named,...
# и запуск одной getty
export PATH=/usr/bin:/bin
/sbin/mingetty tty1

В Листинге 1 приведен скрипт, который может использоваться в качестве программы "Init". Скрипт этот короток и неполон, в частности, видно, что он запускает только одну программу getty, которая не может рестартовать после своего завершения. Будьте осторожны, если Вы решите использовать этот скрипт, так как каждый дистрибутив Linux использует свой собственный вид программы getty. Наберите команду: grep getty /etc/inittab, чтобы узнать, какая программа используется в вашей системе и как она называется.
В этом скрипте есть второй недостаток: он не заботится об отключении системы. Добавить поддержку отключения системы (shutdown) довольно легко, нужно просто отключить все процессы, когда завершит работу сеанс командного интерпретатора. Добавление текста, приведенного в листинге 2, выполнит этот трюк.
Листинг 2. Команды остановки всех процессов перед выключением
# убиваем все процессы, которые мы запустили
killall inetd
killall sendmail
killall klogd
killall syslogd
killall inetd
# убиваем все остальное
kill -TERM -1
sleep 2
kill -KILL -1
# освобождаем диск
swapoff -a
umount -a
mount -n -o remount, ro /
echo "The system is halted"
exit

Когда Вы загружаете систему в режиме init=/bin/sh, Вы должны по крайней мере перемонтировать корневую файловую систему перед тем, как делать что-либо еще, не забудьте также выполнить команду:
umount -a
перед нажатием ctrl-alt-del, потому что шелл не перехватывает эту комбинацию из трех клавиш.
Программа simpleinit
Модуль util-linux содержит исходники программы Init на языке С. У этой программы гораздо больше возможностей, чем у простого скрипта, и она может хорошо работать с большинством персональных компьютеров, хотя она не обладает такими широкими возможностями изменения своей конфигурации, как модуль SysVinit, поставляемый со многими дистрибутивами Linux.
Роль программы simpleinit (которая должна называться init для нормальной работы) очень похожа на роль скрипта, приведенного выше, с добавлением возможностей управления однопользовательским режимом и интерактивным вызовом сеансов связи через консоли. Также она корректно выполняет процедуру отключения системы. На программу simpleinit интересно посмотреть, она хорошо документирована, Вам, несомненно, понравится знакомство с прилагаемой документацией. Я советую обратиться к дистрибутиву модуля util-linux для получения более свежей информации. Средства программы simpleinit предельно просты, как и обещает ее название. Программа вызывает скрипт ( /etc/rc) и запрашивает файл конфигурации, чтобы определить, какой процесс должен быть перезапущен. Файл конфигурации называется /etc/inittab, аналогично файлам конфигурации других программ "init", хотя его формат и отличается от них. Если Вы планируете установить simpleinit на свой компьютер (который, скорее всего, уже содержит SysVinit), вы должны делать это очень осторожно и быть готовым к загрузке системы с аргументом кернела "init=/bin/sh" для исправления ошибок.

Продолжение следует
Алессандро РубиниLinux Journal, issue 55, November 1998, перевод Игоря Греня


Компьютерная газета. Статья была опубликована в номере 49 за 1998 год в рубрике soft :: unix

©1997-2024 Компьютерная газета