exec script $0 $LOGFILE
Начать знакомство с чужими сценариями вы можете с инициализационных файлов bash
/etc/bashrc
и /etc/profile
. Команда «.» (точка) в оболочке sh и ее производных (bash, ksh), подобно команде source, означает чтение и выполнение команд из файла-аргумента этой команды в текущем процессе.Глава 9Управление процессами
9.1. Как загружается Linux
9.1.1. Начальная загрузка: LILO и GRUB
Общие механизмыКак известно, первая программа, которая выполняется после включения компьютера, — это BIOS. Она находит загрузочное устройство, считывает в память его первый (нулевой) сектор и передает на него управление. В этом секторе находится MBR (Master Boot Record) — главная загрузочная запись размером в 512 байт, в которой помещаются:
♦ первичный загрузчик;
♦ таблица разделов диска (Partition Table) размером в 64 байта, описывающая четыре первичных раздела: номера их первого и последнего цилиндров, тип файловой системы и признак активности раздела;
♦ «волшебное число» (0xAA55), предназначенное для проверки, служит ли данный сектор загрузочным.
Формат MBR стандартен для всех операционных систем, а содержание области, отведенной под первичный загрузчик, может различаться. Этот загрузчик очень мал, поэтому перед ним стоит всего одна задача: найти на диске и считать в память код загрузчика следующего этапа, разворачивающего уже саму операционную систему, и передать ему управление.
В ОС Windows 9x первичный загрузчик передает управление на Boot Record — первый сектор того первичного раздела, который отмечен как активный (bootable — такой может быть только один). В более сложных системах из MBR запускается диспетчер загрузки (NTLoader для Windows NT, LILO и GRUB — для Linux), позволяющий выбрать вариант загрузки и даже загружаемую ОС. Такую гибкость диспетчеру обеспечивает возможность не ограничиваться тем объемом данных, который помещается в MBR, а читать необходимые данные из файлов на диске. Достигается эта гибкость ценой зависимости от файловой системы: существуют файловые системы (например, XFS и ReiserFS с включенным режимом оптимизации дискового пространства), с которыми ОС Linux может работать, но загружаться с них не может. Отдельный раздел
/boot
, о котором говорилось в п.1.2.2 в связи с «барьером 1024 цилиндра», необходим еще и поэтому: на нем должна быть создана файловая система ext2fs или ext3fs, а для всех остальных разделов файловые системы можно выбирать произвольно.Загрузчик LILOСтандартный загрузчик Linux — LILO (LInux LOader) — состоит из двух частей: первичного загрузчика LI и вторичного LO. LI располагается в MBR и только и умеет, что загружать LO, а тот уже передает управление ядру или вызывает другой первичный загрузчик (например, Windows 9x). LO находится в файле на диске (по умолчанию
/boot/boot.b
). О файловых системах LI не знает, поэтому карта размещения этого файла хранится в нем в виде «цилиндр/головка/сектор». Помещает ее туда утилита /sbin/lilo, которую нужно запускать после любого изменения LO или его конфигурационного файла /etc/lilo.conf
.У вторичного загрузчика LO есть собственная карта размещения файлов (по умолчанию
/boot/map
). По ней он ищет загружаемое ядро и образ виртуального диска, поэтому после любого изменения ядра или загружаемых модулей тоже обязательно запускать утилиту lilo.Что такое виртуальный диск? Представьте себе загрузку Linux со SCSI-диска или другого устройства, драйвер которого не вкомпилирован в ядро, а подгружается в виде модуля. LILO сможет найти и прочитать с него файл образа ядра. Теперь ядру предстоит смонтировать корневую файловую систему. Чтобы сделать это, нужно подключить драйвер SCSI, а чтобы найти драйвер в
/lib/modules
, нужно смонтировать корневую файловую систему.Похожая проблема возникает при первоначальной установке ОС Linux: для работы инсталлятора нужна файловая система со стандартными утилитами, а на диске ее еще нет. Обе проблемы решаются в Linux с помощью технологии initrd (INITial Ram Disk): вместе с ядром LILO загружает в память образ стартового диска, и ядро монтирует его как обычную файловую систему. В этой файловой системе находятся модули, необходимые для работы с нестандартными внешними устройствами и сетью, и утилиты для их подгрузки. Подключив модули, ядро отсоединяет виртуальный диск и монтирует настоящую корневую файловую систему.
Файл образа виртуального диска обычно называется
/boot/initrd-<версия_ядра>
. Если нестандартных устройств у вас нет или их драйверы встроены в ядро, то этот файл для загрузки не нужен.Поведение LILO зависит от настроек в его конфигурационном файле
/etc/lilo.conf
. Ниже приведен пример такого файла. Символ #, как обычно, служит для комментариев.Листинг 9.1. Примерный файл /etc/lilo.conf
# LILO version: 21.5
# Общий раздел
#
# использовать MBR первого жесткого диска первого
# контроллера IDE
boot=/dev/hda
#
# Карта LO
map=/boot/map
#
# Файл вторичного загрузчика
install=/boot/boot.b
#
# Режим для загрузочных дискет. У меня закомментирован.
# compact
#
# Режим VGA: normal - 80x25, ext - 80x50
vga=normal
#
# Раскладка клавиатуры
keytable=/boot/ru4.kit
# Диск поддерживает режим LBA (Large Block Access) —
# трансляцию
# физических адресов в логические так,
# чтобы число цилиндров не превышало
# понятных BIOS 1024. Другое значение этого
# параметра - linear. Не меняйте значения, выставленного
# инсталлятором, если вы не знаете точно, что делаете.
lba32
#
# Сообщение, которое выдается при загрузке
message=/boot/message
#
# Задержка 5 секунд (в других версиях LILO этот параметр
# называется delay)
timeout=50
#
# Вывести message и приглашение
# к выбору загружаемого ядра на
# timeout/10 секунд, после которых загружается ядро,
# выбранное по умолчанию.
# Если prompt не установлен, добиться приглашения
# можно, удерживая во время загрузки.
prompt
#
#Цветовая схема
menu-scheme=wb:bw:wb:bw
#
# Ядро, загружаемое по умолчанию. Если не указано, то
# загружается первое в списке
default=Fedora
#
# Список вариантов загрузки, не более 16.
# В каждой секции варианта должна быть строка
# label. Это имя, которое вводится в ответ на приглашение
# LILO или является командой меню и служит для выбора
# загружаемого ядра или ОС.
#
image=/boot/vmlinuz-2.4.20 # ядро
label=linux-initrd # метка
initrd=/boot/initrd-2.4.20.img
root=/dev/hda6 # монтировать этот раздел как корневой
read-only # режим монтирования / на время загрузки
#
image=/boot/vmlinuz-2.6.9-1.667
label=Fedora
root=/dev/hda2
read-only
#
image=/boot/vmlinuz
label=failsafe
root=/dev/hda6
append=" mem=64M failsafe" # параметры, передаваемые ядру
read-only
#
other=/dev/hda1 # ОС - не Linux
label=WindowsXP # root не указывается
table=/dev/hda # где находится таблица разделов
Если вы определили секцию other=/dev/hda1, то в корневом каталоге раздела /dev/hda1 (диска С:) должен находиться вторичный загрузчик. У меня, например, на одном из компьютеров с много вариантной загрузкой там находится NTLoader (поскольку WindowsXP была установлена до Linux), и LILO успешно загружает WindowsXP.
Команда append позволяет передать ядру необходимые параметры. Ее формат:
append=" параметр1[=значение1][, значение2...] [параметр2[=значение3][,значение4...]...]"
Значения разделяются запятой без пробелов, параметры разделяются пробелами. Например, у вас есть устройство CD-RW, которое вы до сих пор использовали как обыкновенный CD-ROM, подключив его как Secondary Slave, то есть
/dev/hdd
. Чтобы записывать компакт-диски под Linux, CD-RW должен быть устройством SCSI, значит, это устройство нужно эмулировать. Команда выглядит так:append=" hdd=ide-scsi "
Не забудьте после каждого изменения конфигурационного файла запустить утилиту lilo. Некоторые ее полезные ключи:
♦-V — показать версию LILO;
♦-q — показать текущую карту загрузки;
♦-t — проверить
lilo.conf
на ошибки;♦-u — удалить LILO. После удаления вы сможете загрузить Linux только с внешнего носителя (дискеты).
Если вы решили пока не удалять LILO, то при очередной загрузке системы вас встретит приглашение LILO. Нажмите <Ввод>, чтобы загрузить вариант по умолчанию. Нажмите для просмотра вариантов. Иногда на экран выдается только подсказка:
LILO
Чтобы выбрать ядро, нужно нажать клавишу «Shift», после чего появится подсказка:
LILO boot:
и только теперь можно нажать . Если вы введете команду help, то получите список всех команд LILO.
Чтобы загрузиться в однопользовательском режиме (например, для восстановления системы после аварии), введите в строке приглашения:
<метка_варианта> single
Если вы переустановили Windows, а она заменила вам содержимое MBR, то восстановить его можно, загрузившись с дискеты или компакт-диска и введя команду
lilo
. Таким же образом можно установить LILO, если при инсталляции системы вы выбрали другой диспетчер загрузки.Любопытно, что четыре буквы приглашения LILO — это отметки об успешном окончании четырех шагов загрузки. Если вы видите меньше четырех букв, то это значит:
♦L : первичный загрузчик запустился, но не смог загрузить вторичный. Двузначное число xx — это код ошибки. Обычно причина ошибки — аппаратный сбой.
♦LI: LI смог загрузить вторичный загрузчик, но не смог передать ему управление. Причина: перемещение
/boot/boot.b
без запуска утилиты lilo. Чаще всего это значит, что вы удалили или добавили раздел.♦LIL: LO запустился, но не смог прочитать карту размещения файлов. Аппаратный сбой.
♦LIL?: LO загрузился по неправильному адресу. Причина — перемещение
/boot/boot.b
без запуска утилиты lilo.♦LIL-: испорчена карта размещения файлов. Причина — перемещение
/boot/map
без запуска утилиты lilo.♦ Еще одной причиной любой из этих ошибок может быть неправильное указание геометрии диска (несовпадение ее с фактической).
Загрузчик GRUBДругой известный диспетчер загрузки — это набирающий все большую популярность GNU GRUB (GRand Unified Bootloader). В дистрибутивах Mandrake и Fedora Core этот загрузчик используется по умолчанию, хотя я рекомендую вам сменить его на проверенный временем LILO.
GRUB использует несколько отличную от LILO схему загрузки. Вторичный загрузчик хранится не в каком-то файле, а в не используемом системой пространстве. Обычно это вся первая дорожка диска. Если места для полноценного вторичного загрузчика там недостаточно, туда помещается маленький загрузчик промежуточного этапа, «полуторный», состоящий из драйвера файловой системы и инструкций для вызова настоящего, большого, вторичного загрузчика. Благодаря такой организации GRUB поддерживает большинство файловых систем (FAT и FAT32, ext2fs и ext3fs, ReiserFS, XFS, BSD FFS), понимает большинство форматов исполняемых файлов и — не главное, но самое заметное для начинающего системного администратора, — изменения в конфигурационном файле вступают в силу сразу же, без прописывания их в специальном месте специальной утилитой.
Конфигурационный файл GRUB называется /boot/grub/grub.conf. В мгновенно устаревающих руководствах вы можете встретить другое название — /boot/grub/menu.1st — но это не страшно: этот файл является символической ссылкой на первый. Пример такого файла приведен ниже.
Листинг 9.2. Примерный файл /boot/grub/grub.conf
#boot=/dev/hda
default=0
fallback=1
timeout=5
splashimage=(hd0,1)/grub/splash.xpm.gz
hiddenmenu
title Fedora Core (2.6.9-1.667)
root (hd0,1)
kernel /vmlinuz-2.6.9-1.667 ro root=/dev/hda2
initrd /initrd-2.6.9-1.667.img
title WindowsXP
rootnoverify (hd0,0)
chainloader +1
Закомментированная команда boot указывает загрузочный диск. Команда default говорит, какая метка (title) будет загружена по умолчанию, а fallback — какая система будет загружена в случае неудачи. Команда timeout указывает время (в секундах) ожидания ввода команды или выбора другой операционной системы.
Команда splashimage указывает, какой рисунок будет использован в качестве фона. Если у вас что-то не ладится с видеорежимом, закомментируйте это строку.
Труднее всего смириться с тем, как GRUB именует жесткие диски и их разделы. Диски отсчитываются не с буквы «а», а с нуля, а разделы — не с единицы, а тоже с нуля. Таким образом, раздел, который Linux именует
/dev/hda1
, a Windows — С:, GRUB называет (hd0,0). Круглые скобки обязательны.Команда rootnoverify нужна для не-Linux систем, a chainloader +1 —для ОС, понимающих только «цепочечную» загрузку (MBR → загрузочная запись активного раздела). Если вы зачем-то разместили Windows на неактивном разделе, откуда она сама загрузиться не сможет, то команде chainloader должна предшествовать команда makeactive.
GRUB имеет графический интерфейс, но попасть в его командную строку все-таки можно: увидев меню вторичного загрузчика, выберите курсором нужную позицию и нажмите <с> (нажав <Ввод>, вы загрузите выбранную систему, нажав <а>, вы сможете передать ядру дополнительные параметры, а нажав <е> — отредактировать последовательность команд, выполняемых при загрузке выбранной системы).
Итак, вы в командной строке. Редактировать вводимые команды можно в стиле bash: поддерживается автодополнение команд и путей к файлам, пролистывание истории команд стрелками «вверх» и «вниз». Список всех доступных команд можно получить по команде help, а получить краткую справку о команде — введя
help <имя_команды>
.Установить диспетчер загрузки GRUB (если вы не сделали этого при инсталляции системы) можно командой
/sbin/grub-install /dev/hda
. Утилита grub-install, как и все остальные компоненты GRUB, содержится в пакете grub, который можно скачать по адресу http://www.sisyphus.ru/srpm/grub
.Как установить графический фон загрузчика GRUBМного интересных картинок, пригодных для установки в качестве фона загрузчика GRUB, можно найти по адресу
http://ruslug.rutgers.edu/~mcgrof/grub-images/images/working-splashimages.
Чтобы не загружать все эти картинки, можно просмотреть их уменьшенные изображения по адресу http://ruslug.rutgers.edu/~mcgrof/grub-images/images
, а потом уже загрузить понравившуюся картинку.Выбранную картинку поместите в каталог
/boot/grub
и укажите ее в директиве splashimage конфигурационного файла:splashimage=(hd0,0)/boot/grub/image.xpm.gz
Собственную картинку можно использовать как фон для загрузчика, если преобразовать ее в формат, поддерживаемый GRUB. Преобразование выполняется утилитой convert, после чего картинку нужно сжать компрессором gzip:
# convert myimage.png -colors 14 -resize 640x480 myimage.xpm
# gzip myimage.xpm
9.1.2. Продолжение загрузки.
Демон initС момента загрузки ядра процесс начальной загрузки системы идет под управлением самой системы. Первой получает управление процедура автозапуска ядра. Она определяет объем доступной оперативной памяти, тип и быстродействие процессора, тип видеоадаптера, переинициализирует жесткие диски, не полагаясь на инициализацию, выполненную BIOS.
Это делается для того, чтобы выбрать из возможных вариантов выполнения ядром основных функций оптимизированные именно для данной архитектуры компьютера, повысив тем самым быстродействие всей системы. Здесь же определяется системная консоль, на которую выводятся диагностические сообщения.
Наконец, процедура автозапуска распаковывает загруженный в память образ ядра (на этом этапе вы видите сообщение: «Uncompressing Linux…») и передает ему управление («OK, booting the kernel»). Теперь ядро инициализирует таблицу страниц виртуальной памяти, устанавливает обработчики прерываний, разбирает параметры, переданные ему диспетчером загрузки, и настраивается в соответствии с ними.
Завершив самонастройку, ядро создает несколько системных «процессов», фактически представляющих собой части самого ядра: планировщик процессов, диспетчер виртуальной памяти, различные обработчики сигналов ядра.
В списке текущих процессов, который вы видели по команде
ps -e
, эти системные процессы взяты в квадратные скобки. Один из них получает идентификатор 1, он-то и станет полноценным пользовательским процессом, в котором будет выполняться код демона init. Этот демон запустит все остальные службы и процессы, управляющие базовыми операциями: например, входом пользователей в систему.Ядро монтирует корневую файловую систему в режиме «только чтение», находит исполняемый файл демона init (в каталоге
/bin
, /sbin
или там, где вы укажете, передав ядру параметр init=/путь_к_init
) и посредством системного вызова exec() загружает его код в процесс номер 1. Все остальные процессы порождает init и его потомки путем деления с помощью системного вызова fork().ПримечаниеЯдро покорно запустит в качестве первопроцесса любую программу, которую вы укажете ему как init:
LILO: my_linux init=/bin/sh
Конечно, оболочка sh не запустит других процессов, но она предоставит вам интерфейс командной строки, в которой вы сможете выполнить необходимые ремонтные работы.
Процесс init прочитывает свой конфигурационный файл
/etc/inittab
и запускает другие процессы согласно указанным в нем инструкциям. В этот момент выводится приглашение нажать определенную клавишу (обычно ), чтобы войти в интерактивный режим, позволяющий запускать каждый процесс вручную или отказываться от такого запуска.Уровни выполненияУровень выполнения (runlevel) — это такой режим работы системы, в котором разрешается существование только определенной группы процессов. В каждый момент времени система находится на одном из уровней выполнения (на каком именно, можно узнать по команде
who -r
. Она покажет также значение предыдущего уровня).Разрешенные на каждом уровне процессы указаны в файле
/etc/inittab
. Демон init заведует переключением уровней, остановкой запрещенных на новом уровне процессов и запуском предписанных. В ОС Linux определено:♦ семь уровней выполнения, обозначаемых номерами с 0 до 6;
♦ особый уровень S или s — однопользовательский;
♦ уровни по требованию (ondemand) А, В и С — фиктивные: при переходе на эти уровни запускаются приписанные к ним процессы, но текущий уровень выполнения не меняется.
Термин «уровень выполнения» унаследован от тех времен, когда система была обязана проходить уровни последовательно, от низшего к высшему при загрузке и обратно при выключении. Сейчас их можно переключать в любом порядке. Для переключения на уровень n нужно от имени суперпользователя ввести команду
# telinit n
Эта команда посылает соответствующий сигнал процессу init (tell init). Ее исполняемый файл представляет собой символическую ссылку на
/sbin/init
, так что вместо нее можно отдавать просто команду init
. При этом не будет запущена копия процесса init: стартующий процесс первым делом проверяет свой PID и, если тот не равен 1, просто передает сообщение настоящему процессу init.Запустив все процессы, приписанные к текущему уровню выполнения, init засыпает до получения сигнала о завершении дочернего процесса, отключении питания или требовании переключить уровень. Тогда он просыпается, перечитывает свой конфигурационный файл и, если нужно, выполняет записанные в нем инструкции. Чтобы заставить его перечитать измененный вами
/etc/inittab
, не дожидаясь трех вышеуказанных событий, введите команду# telinit q
Важно понять, что уровень выполнения — это программная абстракция, аппаратура ни о каких уровнях не знает. Поэтому в разных реализациях Linux (разных дистрибутивах) одному уровню могут соответствовать разные конфигурации системы. Следующие уровни используются в дистрибутивах, основанных на Red Hat:
♦ 0: Останов системы.
♦ 1: Однопользовательский режим. То же, что уровень S.
♦ 2: Многопользовательский режим без поддержки сети.
♦ 3: Полный многопользовательский режим.
♦ 4: Не используется.
♦ 5: Графический режим с X11.
♦ 6: Перезагрузка.
В однопользовательском режиме никакие службы не стартуют: только грузится ядро, монтируется корневая файловая система и запускается командный интерпретатор. На этом уровне не нужен даже файл
/etc/inittab
, повреждение которого означает невозможность загрузиться на любом другом рабочем уровне. Этот уровень обычно использует администратор для аварийно-восстановительных работ.Неиспользуемые уровни можно занять под свою собственную конфигурацию служб, собранных для конкретной задачи.
Конфигурационный файл /etc/inittabПервая незакомментированная строка этого файла определяет уровень выполнения по умолчанию, то есть тот, в котором стартует система, если в процессе загрузки ядру не указано иначе. Эта строка выглядит как
id:3:initdefault
Обычно в качестве уровня по умолчанию выбирают 3 (полнофункциональный многопользовательский текстовый режим) или графический 5 (запускается X Window и выдается графическое приглашение для входа в систему). Если оставить поле уровня пустым, то init переспросит значение в процессе загрузки. Если указать в поле уровня несколько значений, то сработает наибольшее. Уровни 0 (останов) и 6 (перезагрузка) указывать нельзя.
Следующие строки имеют формат:
идентификатор:уровни_выполнения:действие:запускаемый_процесс
♦Идентификатор — это уникальная последовательность из четырех символов (в старых дистрибутивах — двух).
♦Уровни_выполнения: перечень уровней выполнения (номера без каких-либо разделителей), для которых будет выполнено указанное действие. Например, значение 2345 требует выполнить действие на уровнях 2, 3, 4 и 5. Здесь можно указывать также уровни по требованию (ondemand) А, В и С.
♦Действие: одно из действий, перечисленных в таблице 9.1.
♦Запускаемый_процесс: процесс, над которым производится действие. Это может быть исполняемый файл или сценарий.
Действия над процессами, задаваемые а файле /etc/inittab Таблица 9.1
Действие Описание respawn В случае завершения процесс будет перезапущен wait Процесс будет запущен при переключении на любой из указанных уровней, и init будет ждать его завершения once При переключении на любой из указанных уровней процесс будет запущен только однажды boot Процесс будет запущен во время загрузки системы. Поле «уровни_выполнения» игнорируется bootwait То же, что и boot, но init ждет завершения процесса off Не выполняет никаких действий ondemand Процесс выполняется в режиме по требованию, то есть, он будет запущен при переключении на уровни a, b или с initdefault Определяет уровень выполнения по умолчанию sysinit Процесс запускается во время загрузки системы до любых процессов, стартующих через boot или bootwait powerwait Процесс будет запущен, когда исчезнет напряжение в сети. Естественно, для корректной работы этой записи нужен источник бесперебойного питания, от которого система и получит уведомление об исчезновении напряжения; init будет ждать завершения этого процесса powerfail То же, что и powerwait, но init не будет ждать завершения процесса powerokwait Процесс запускается по получении init сигнала о восстановлении питания powerfailnow Процесс запускается, когда источник бесперебойного питания подает сигнал о том. что его батареи почти разряжены ctrlaltdel Процесс запускается при получении init сигнала INT. посланного нажатием комбинации клавиш Ctrl+Alt+Del. Обычно это процесс перезагрузки, выключения или перехода в однопользовательский режим. kbrequest Процесс запускается при получении init сигнала, посланного нажатием «специальной» комбинации клавиш. Назначить клавишам специальное значение можно с помощью утилит из пакета kbd
Сценарий, помеченный действием sysinit, выполняется во время запуска системы, однократно, вне зависимости от запрошенного уровня. Затем запускаются процессы, помеченные действиями boot и bootwait.
На данном этапе загрузки системы происходят следующие действия по инициализации, результат которых необходим на любом уровне выполнения:
1. Устанавливается имя машины (hostname).
2. Конфигурируются параметры ядра.
3. Устанавливаются раскладка клавиш и системный шрифт,
4. Активируются разделы подкачки.
5. Корневая система проверяется программой fsck. Если будут найдены ошибки, которые невозможно исправить автоматически, будет запрошен пароль администратора для входа в административный режим, что равноценно переходу на уровень выполнения 1. В этом режиме вы запустите программу fsck с аргументом «/», который означает проверку корневой файловой системы. После исправления всех ошибок введите команду
exit
для перезагрузки системы. Если программа fsck ошибок не обнаружила, файловая система монтируется в режиме чтение/запись.6. Проверяются зависимости модулей ядра.
7. Выполняется проверка других файловых систем.
8. Монтируются локальные файловые системы.
9. Включаются квоты.
10. Подключается (не активизируется!) раздел подкачки. С этого момента система начинает использовать раздел подкачки.
Дальше включается сценарий загрузки, специфичный для запрошенного уровня, и начинается разница между дистрибутивами.
В процессе развития UNIX-подобных ОС выделились две основных системы инициализации (набора сценариев загрузки). Одна была разработана в рамках ОС BSD (Berkeley Software Distribution) Калифорнийского университета, от которой произошли бесплатная FreeBSD и коммерческая SunOS. Другая применяется в классической System V от AT&T и ее потомках, среди которых UnixWare, IRIX, HP-UX и Solaris. ОС Linux заимствовала удачные решения с обеих эволюционных ветвей, и в результате часть дистрибутивов следует в инициализации стилю BSD (Slackware, CRUX, Gentoo), а часть (Red Hat-подобные) — стилю System V.
Инициализация в стиле BSDДля этого стиля характерно наличие конфигурационного файла стартовых сценариев
/etc/rc.conf
. Уровней выполнения как таковых в BSD и ориентированных на нее реализациях Linux нет, вместо них вводится понятие режима — группы процессов, объединенных общей функциональностью. Режимов обычно два: однопользовательский и многопользовательский. Каждый режим запускается своим сценарием. Файлы этих сценариев обычно находятся в /etc
и называются rc.*
(рис. 9.1).Рис. 9.1. Порядок инициализации в стиле BSD
В дистрибутиве Slackware этим сценариям присвоены имена:
♦
rc.S
— сценарий запуска (действие sysinit);♦
rc.0
— останов системы;♦
rc.6
— перезагрузка;♦
rc.K
— однопользовательский режим;♦
rc.M
— многопользовательский текстовый режим;♦
rc.4
— многопользовательский режим с графическим входом в систему.В
/etc/default/rc.conf
хранятся в неизменном хорошо откомментированном виде все системные настройки в количестве нескольких сотен, а редактируемый администратором /etc/rc.conf
содержит только отличия желаемой конфигурации системы от /etc/defaults/rc.conf
, которых раз в десять меньше. Загрузочные сценарии режимов прочитывают оба эти файла и и зависимости от требуемой конфигурации могут запускать из-под себя дополнительные сценарии инициализации различных служб: rc.inetd*
, rc.cdrom
и т.п. Последним при загрузке выполняется сценарий rc.local
, содержание которого определяется администратором конкретной системы.Инициализация в стиле System VВ этом стиле каждому уровню выполнения соответствует целый каталог, все сценарии в котором выполняются при переключении на этот уровень. Это подкаталоги
/etc
с именами rc0.d
, rc1.d
, …, rc6.d
. Сценарии в этих каталогах — файлы с именами вроде S12syslog или K95kudzu — только символические ссылки на настоящие сценарии, находящиеся в /etc/init.d
. Каждый из настоящих сценариев, будучи вызван с аргументом start, запускает свою службу, а с аргументом stop — останавливает ее. Какой аргумент будет ему передан, зависит от первой буквы имени символической ссылки: S означает start, K (kill) — stop. Следующее за этой буквой число определяет порядок вызова настоящих сценариев: чем оно больше, тем позже срабатывает данная ссылка при включении текущего уровня. Сначала выполняются все сценарии останова процессов, не разрешенных на данном уровне, потом — все сценарии запуска (рис. 9.2).Рис. 9.2. Порядок инициализации в стиле System V
Переключением уровней выполнения занимается центральный сценарий
/etc/rc
. Вызванный с аргументом N, где N — это номер включаемого уровня, он ищет каталог /etc/rc.N
и выполняет в нем сначала все стоп-сценарии, потом все старт-сценарии.Для выбора демонов, которые будут запускаться автоматически при загрузке системы, обычно используют конфигуратор drakconf в операционной системе Linux Mandrake, system-config-services в Fedora Core (рис.9.3) или setup в других Red Hat-подобных дистрибутивах.
Рис. 9.3. Конфигуратор служб system-config-services
Чтобы обеспечить автоматический запуск какого-нибудь сервиса, нужно создать сценарий для его запуска и поместить его в каталоге /etc/init.d. Затем, в зависимости от уровня выполнения, в каталоге /etc/rcN.d нужно создать символические ссылки на этот сценарий для его запуска и останова.
Если вы хотите сами создать сценарий для запуска своего демона, можете воспользоваться шаблоном, приведенным в листинге 9.3.
Листинг 9.3. Шаблон для запуска демона
#!/bin/bash
#
# Подключаем библиотеку функций
. /etc/init.d/functions
#
# Определяем параметры
case "$!" in
start)
# Запуск демона
echo "Starting my_daemon..."
daemon my_daemon
touch /var/lock/subsys/my_daemon
;;
stop)
# Останов демона
killproc my_daemon
rm -f /var/lock/subsys/my_daemon
rm -f /var/run/my_daemon.pid
;;
status)
# Выводим статистику работы
;;
restart | reload)
# действия, выполняемые при перезагрузке демона
;;
*)
# Произошел вызов без параметров
echo "Usage: my_daemon {start|stop|status|restart|reload}"
exit 1
esac
exit 0
После того, как в процессе инициализации системы будет выполнен загрузочный сценарий уровня но умолчанию, последним выполняется сценарий
/etc/rc.local
. Выполнив все сценарии, init переходит к другим записям в /etc/inittab
, относящимся к текущему уровню. Обычно там остаются только перезапускаемые (respawn) действия: процессы, которые init запускает в фоне, а когда какой-нибудь из них завершается, запускает вновь. Так ведут себя процессы *getty, обслуживающие виртуальные консоли, и менеджер дисплеев системы X Window. Инициализация системы считается законченной, когда запушены все перезапускаемые процессы и init остается только следить за ними.9.2. Команды управления процессами