Наши партнеры

UnixForum






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Тематический каталог -> Процесс начальной загрузки системы



Увеличение скорости загрузки сервера
или
"Потрошим загрузочные скрипты Fedora Core 4"


ДАТА: 27 февраля, 2006 г. | АВТОР: Andrejs Spunitis | EMAIL: spunitis AT one.lv

KEYWORDS:
grub, init, inittab, rc.sysinit, fcsk, mount, swapon, mingetty

ПОСТАНОВКА РЕШАЕМОЙ ЗАДАЧИ

  • Максимально упростить загрузочные скрипты для Fedora Core;
  • Детально разобраться с этапами загрузки системы, от включения питания до командного shell;
  • Сокращение времени загрузки ISP-serv; в моем случае время загрузки сократилось с 16сек. (сервисы: syslogd,sshd,network,crond,gpm) до 7сек, для P4-2.8GHz.

    Полезные ресурсы интернета:
    http://www.opennet.ru/docs/RUS/FromPowerUpToBash/
    http://www.phrack.org/show.php?p=63&a=10
    http://sentinelsecurity.net/whitepapers/diskcloning.pdf
    http://unixforums.org.ru/index.php?t=2
    http://www.comptechdoc.org/os/linux/startupman/linux_surcsysinit.html
    http://wiki.kryukov.biz/wiki/


    АНОТАЦИЯ
    Ознакомление начинающих Linux администраторов с загрузочными скриптами и их упрощения применительно к серверу (ISP-serv).

    ВВЕДЕНИЕ
    В начале освоения Linux, каждый из нас прочитывал строки описывающие загрузку Linux системы, и в курсе, что сначала грузится загрузчик операционной системы (как правило в современных дистрибутивах это grub), затем ядро с каким-то не совсем понятным initrd.img, затем запуск прародителя всех процессов init, который использует файл inittab, затем rc.sysinit и переход в уровень выполнения (runlevel) указанный в файле inittab. Кажется все ясным?! Тогда попробуйте проверить полученные знания на практике, например снесите себе директорию где располагаются образ ядра и initrd.img (директория /boot) и проверьте себя, а заодно и полноту изложенного материала:). Ну а если Вы не сторонник радикальных мер, то попробуйте вначале разобраться с /etc/rc.sysinit, в качестве затравки, rc.sysinit для ISP-serv можно сократить до размера нескольких строк, например:

#!/bin/bash
mount -n -t proc none /proc
fsck -T -A -a
mount -n -o remount,rw /
mount -a
swapon /dev/sda2

а затем, на дисерт разберитесь с скриптом /etc/rc.d/initd/network, который можно заменить тремя строками:

modprobe 8139too
ifconfig eth0 xx.xx.xx.xx netmask 255.255.255.0 up
route add default gw xx.xx.xx.gw


Подытожив, не побоюсь заявить, дистрибутивы Linux-а буквально тонут в скриптах написанных лет 10 обратно, превращая изначально простую систему во что то cложное и непонятное. Во всех сриптах куча проверок, на существование всяких файлов конфигурации, udev - как правило подвисает на пару секунд, в натугах найти звуковую карту там, где ее нет, а в случае ISP-serv ещё ругается на какой-то там md (raid). Конечно в случае Linux-десктопа это оправдано (оправдано незнанием всезнаек), но абсолютно раздражает когда Вы используете собственно настроенный сервер. Честно говоря я также не вижу толка в красочных выводах сообщений от redhata об успешном или неудачном запуске сервисов. Моя цель проста и ясна: "сделать используемые системой скрипты простыми и ясными".

В поисках истины, у Вас может появиться искушение собрать свой Linux, но и там есть могучие скрипты, заставляющие новичков ощутить свою неполноценность, к тому же в самопальных (LFS) Linux Вас буквально заставляют собрать кучу всяких програмных пакетов, только для того что бы вы смогли скомпилировать необходимые Linux програмные пакеты shadow, util-linux, coreutils, sysVinit, bash и так далее.

Источником знаний, излагаемых в этой статье, на первых порах стала статья "От включения питания до приглашения Bash":
http://www.opennet.ru/docs/RUS/FromPowerUpToBash/

Согласно указанной статье, для понятности ниже приведена простенькая таблица, с кратким описанием этапов загрузки системы

Параграф

Этап

Выполняемое действие

Файл

1.

[Включение кнопки]



2.

[Загрузчик]

GRUB выводит меню где пользователь выбирает Операционную Систему (Как правило Linux или Windows)

/boot/grub/grub.conf
@menu.lst

2.1

[Загрузка ядра]

В загрузчике grub реализованы необходимые функции для работы с файловыми системами, что позволяет ему в случае Linux найти файлы vmliniz и initrd.img и загрузить их

/boot/vmlinux
/boot/initrd.img

3.

[Запуск перограммы init]

После того как ядро запущено, запускается самая первая прогрмма, которую называют прародителем всех процессов. По умолчпнию эта программа init

/sbin/init

3.1.

[Чтение инструкций из файла inittab]

Главной задачей init является выполенение инструкций из файла inittab

/etc/inittab

3.1.1.

[Инициализация системы]

В файле inittab есть строка: si::sysinit:/etc/rc.d/rc.sysinit указыающая, какой скрипт должен быть запущен для инициализации системы,

/etc/inittab

3.1.1.1.

[Cоздание псевдо файловых систем]

Создание псевдо-файловой системы: mount -n -t proc /proc /proc хранящей информацию о запущенных процессах, используемой памяти и т.д.

/etc/rc.d/rc.sysinit

3.1.1.2.

[Проверка файловых систем]

Прежде чем изменить доступ к корневой директории с режима чтения на запись, необходимо проверить файловую систему командой: fsck -T -A -a

/etc/rc.d/rc.sysinit

3.1.1.3

[Монтирование файловых систем]

Изменяем режим доступа на запись/чтение к корневой директории командой:
mount -n -o remount,rw /
Монтируем файловые систему которые перечислены в файле /etc/fstab командой:
mount -a

/etc/rc.d/rc.sysinit

3.1.1.4

[Монтирование swap]

Для компьютера с небольшим количеством оперативной памяти создаем файл подкачки, команда: swapon /dev/sda2

/etc/rc.d/rc.sysinit

3.1.2.

[Переход на указанный runlevel]

Выполнение скриптов из директории /etc/rc.d/rc.X.d, где X - номер уровня выполнения (runlevel), runlevel запускаемый по умолчанию определяется строкой id:3:initdefault: из файла /etc/inittab.

/etc/inittab

3.1.3.

[Запуск виртуального терминала]

После того как все сервисы, на которые указывают ссылки из директории /etc/rc.d/rc.X.d выполнились, пользователю дается возможность ввести свой login/pasword и командная оболочка, для этих целей необходимо чтобы программа /sbin/mingetty постоянно работала, на терминалах (tty). Для выполнения этих требований в конце файла /etc/inittab есть строки:
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2

/etc/inittab


Из таблицы наглядно видно, почему init называют прародителем всех процессов.

Рассмотрим поподробнее перечисленные этапы в таблице


2. [Загрузчик] grub


Начну описание загрузчика с одного из эпизодов:

Чтение эпизодов можно пропустить, их цель придать статье большую реалистичность и немного детективного жанра.

Эпизод 1: снес партицию boot, в которой располагалось все хозяйтсво grub и kernel.
PS: для достоверности воспроизведения тех далеких событий я прямо сейчас удалил диреткорию /boot, и для полной нирваны, востановил загрузчик Windows-XP.
Для удаления mbr & востановления загрузчика Windows-XP вставьте загрузочный CD-rom (WinXP), выберете Recovery Console и введите следующие две команды: fixboot и fixmbr после чего перезагрузите компьютер. Ваш Windows сразу начнет грузится, не оставив малейших признаков о том что был установлен Linux :).

Ниже описана хронография событий с использованием спасательного диска rescue для Fedora Core 4 (неудачная попытка)

Загрузился с rescue для Fedora Core 4, во время загрузки набрал rescue:
boot: rescue

В конце концов, появилась табличка, извещающая о том, что "безголовый" пингвин лежит по адресу /mnt/sysimage, и если возникло желание оживить его, то в консоле наберите:
# chroot /mnt/sysimage
Тем самым текущей корневой директорией станет /mnt/sysimage

Выполнив chroot /mnt/sysimage я решил для удобства запустить mc (midnight commander) Fedor-ино горе затряслось, но через секунд 10 решило уйти в глубокий нокдаун, перестартовав машину.

Сдаватся не хотелось, поэтому создал директорию boot:
# mkdir /mnt/sysimage/boot

И запланировал скопировать в созданную директорию необходимые загрузчику файлы (stage1,e2fs_stage1_5, stage2), но к сожалению найти их на спасательном диске от Fedora не удалось (# find * |grep stage не дали результатов), быстрым выходом было переустановить пакеты grub и kernel, для этого необходимо скачать их с интернета.

Поднял сетевой интерфейс командами:
# ifconfig eth0 192.168.10.X netmask 255.255.255.0 up
# route add default gw 192.168.10.Y
# echo “nameserver 159.148.60.20” >> /etc/resolv.conf

При попытке проверить работу интернета, сделал ping. ping пошел, однако остановить его обычной комбинацией клавиш Ctrl+C не удалось, пришлось перейти во вторую консоль (Alt+F2) и выполнить команду # killall ping

После чего начал скачивать в директорию /mnt/sysimage/boot
# cd /mnt/sysimage/boot
необходимые пакеты grub и kernel:
# wget http://mirrors.playboy.com/fedora/4/i386/os/Fedora/RPMS/grub-0.95-13.i386.rpm
# wget http://mirrors.playboy.com/fedora/4/i386/os/Fedora/RPMS/kernel-2.6.11-1.1369_FC4.i686.rpm

Затем сменил корневую директорию (наученный горьким опытом на этот раз уже не запускал mc):
# chroot /mnt/sysimage

# cd /boot
# rpm -е kernel --nodeps
Выдалось сообщение об ошибке:
error: %preun(kernel-2.6.11-1.1369_FC4.i686) scriplet failed, exit status 255

При попытке переустановить командами:
# rpm -ivh kernel*.rpm --allfiles
# rpm -Fvh kernel*.rpm --allfiles
Выдало предупреждение:
warning: kernel-2.6.11-1.1369_FC4.i686.rpm: Header V3 DSA signature: NOKEY, keyID 4f2a6fd2

Поигравшись вдоволь с разными опциями rpm я пришел в ярость, так как при установке ядра всегда выдавалась какая-то ошибка и необходимые системе файлы System.map, initrd.img, vmlinuz не установливались!

Подводя итог работы с rescue Fedora Core 4, посоветую вам иметь с собой не спасательное Fedor-ино горе, а что то зубастое, как например Kanotix!

Теперь опишу хронографию действий по поднятию Fedora с помощью Kanotix (удачная попытка).

Вставил, запустился, выбрал консольный режим.

Запустил mc
# mc

Подмонтировал раздел, где лежит обезглавленный пингвин
# mount /dev/sda3 /mnt/sda3

Установил в качестве корневой директории /mnt/sda3
# chroot /mnt/sda3

Перешел в /boot
# cd /boot

После чего для надежности удалил kernel и grub:
# rpm -e kernel --nodeps
# rpm -e grub --nodeps

Поскольку в rpm файл можно залезть с помощю mc и вытащить оттуда файлы, залез в kernel-*.rpm, но к сожалению там не обнаружил необходимого для загрузки Linux файла initrd.img. Забегая вперед, этот initrd.img очень важный для системы файлик.

В initrd.img находятся модули которые ядро во время загрузки может подключить. Здесь уместно обратить внимание на то, что в grub реализована поддержка многих файловых систем (чтобы убедится в этом, посмотрите директорию /boot/grub) в принципе он этим и отличается от LILO. grub использует встроенные в него функции работы с файловыми системами что дает ему возможность найти и загрузить в память файлы: vmlinuz и initrd.img

После чего проинсталировал ядро
# rpm -ivh kernel*.rpm
вот как раз во время инсталяции ядра и создается initrd.img содержащий в себе необходимые для ядра модули, в зависимости от конфигруции железа компьютера (поэтому если Вы попытаетесь стянуть с другой машины initrd.img ваша попытка будет скорее всего обречена на неудачу).
Отмечу, что во время установки ядра вывелось предупреждение связанное как впоследствие окажется с LABEL:
mount: could not open /proc/partitions, so UUID conversion cannot be done.

Проинсталировал grub:
# rpm -ivh grub*.rpm
# grub-install /dev/sda3
grub-install выдал сообщение что устройства /dev/sda3 нету:
/dev/sda: Not found or not a block device.

Несмотря на это необходимые файлы для работы grub c файловыми системами скопировались в директорию /boot/grub.

Для до-установки grub вернулся в Kanotix:
# exit
что бы с его помощью закончить установку grub:
# grub
grub> root (hd0,2)
grub> kernel /boot/vmlinuz-2.6.11-1.1369_FC4
grub> initrd /boot/initrd-2.6.11-1.1369_FC4
grub> setup (hd0)
grub> quit
#

Приведенные команды хорошо описаны в статье "Самодостаточный GRUB":
http://www.linuxshare.ru/docs/software/grubbest.html

Перезапустил компьютер, и увидел любимое приглашение grub-а:
grub>
После вводил следующие команды:
grub> root (hd0,2)
grub> kernel /boot/vmlinuz-2.6.11-1.1369_FC4
grub> initrd /boot/initrd-2.6.11-1.1369_FC4.img
grub> boot

Началась загрузка Linux, но на каком то этапе на экран вывелась куча сообщений, однако сообщение на которое стоило бы обратить внимание появилось всего на пару секунд, приведу его ниже:
Mounting root file system
mount: error 6 mounting ext3
Switching to new root
ERROR opening /dev/console
далее последовало множество сообщений об ошибках и система не загрузилась!

Но для растройства не было причин, вспомнив о сообщение (которое было во время установки ядра) стало ясно что дело именно в нем! По умолчанию ядру передается параметр root=LABEL=/ который указывает метку (LABEL) партиции корневого раздела Linux.

Корневой раздел Linux может быть совсем не тот раздел который указан при команде:
grub> root (hd0,2)

Почему то в статьях которые мне попадались, авторы поленились об этом написать! Посмотрите стандартный конфигурационный файл grub-а /boot/grub/grub.conf и увидите строку вида:
kernel /boot/vmlinuz-2.6.14-1.1653_FC4 ro root=LABEL=/ rhgb quiet

Мне, и многим другим, кажется такой подход крайне неудобным, при установке на компьютер нескольких Linux систем в различные партиции диска, поскольку метка партиции должна быть уникальной.

Поэтому пришлось перезагрузится, и при загрузке ядра явно указать корневую партицию, передав параметр root=/dev/sda3, например:

grub>
grub> root (hd0,2)
grub> kernel /boot/vmlinuz-2.6.11-1.1369_FC4 root=/dev/sda3
grub> initrd /boot/initrd-2.6.11-1.1369_FC4.img
grub> boot

Все загрузилось удачно!

Чтобы каждый раз при загрузке не вводить в grub команды, существует файл конфигурации grub-a: /boot/grub/grub.conf
При загрузке grub, для взаимодествия с пользователем grub выводит в виде меню содержимое файла grub.conf:

default=1
timeout=5

title Fedora Core (2.6.11-1.1369_FC4)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.11-1.1369_FC4 init=/sbin/init 4 ro root=/dev/sda3 quiet
        initrd /boot/initrd-2.6.11-1.1369_FC4.img

title Windows XP
        rootnoverify (hd0,0)
        chainloader +1

Однако после перезагрузки меню выбора ОС не будет если не была создана ссылка menu.lst на grub.conf, ссылка создается командой:
# cd /boot/grub
# ln -s grub.conf menu.lst

Рассмотрим подробнее строки из приведенного примера файла grub.conf:

root (hd0,2) указывает что файы kernel и initrd.img расположены в 3-й партиции первого жесткого жиска
kernel /boot/vmlinuz-2.6.11-1.1369_FC4 ядро (kernel) есть файл /boot/vmlinuz-2.6.11-1.1369_FC4
ro root=/dev/sda3 -- корневая файловая система расположена в 3-й партиции первого жесткого диска /dev/sda3 и не доступна для записи
init=/sbin/init указывает что после загрузки ядра запустится программа иницализации /sbin/init и ей передается параметр :
цифра 3 которая задает 3-й runlevel
quiet - уменьшает вывод сообщений которые выводятся на дисплей во время загрузки ядра, тем самым тратится меньше времени
initrd /boot/initrd-2.6.11-1.1369_FC4.img файл грузящися в оперативную память и содержащий необходимые модули используемые ядром

Забегая вперед, уровень выполнения задается в файле /etc/inittab, однако мне больше нравится указывать уровень выполнения непосредсвенно при загрузке ядра. Это удобно когда необходимо загрузится в однопользовательский режим (runlevel=2) тогда достаточно при загрузке grub нажать клавишу "e" для редактирования параметров передаваемых ядру.

Подводя итоги:

  • Копируете в надежное место vmlinuz и initrd.img!
  • Если Linux не грузится, проверьте передаваемый ядру параметр root=/dev/ХХХ
  • Если при загрузке не появляется меню, то проверьте наличие файла grub.conf и ссылки menu.lst на него


    Поскольку сейчас мы немного разобрались на примере из Эпизода 1 с часто возникаемыми проблемеми связанными с загрузчиком grub, рассмотрим подробнее этапы загрузки grub

    Источником информации (для выяснения как грузится grub) для меня послужила статья Hacking Grub for fun and profit:
    http://www.phrack.org/show.php?p=63&a=10

[включение питания]
  |
  +---->[boot сектор, загрузка программы из MBR] 
           |
           Y
           +----< grub нету в MBR >----[переход на активную партицию]---+
           |                                                            |
           Y                                                            Y
           +----< grub есть в MBR >--------->---+---<-------------------+
                                                |
                                                Y
                                      +---------+----------+
                                      |  загрузка stage-1  |
                                      +---------+----------+
                                                Y
      +-----< stage-1.5 отконфигурирована >-----+
      |                                         |
      Y                                         |
+-----+-------------------+                     |
|  загрузка stage-1.5     |                     |
| (load embedded sectors )|                     |
+-----+-------------------+                     |
      |                                         |
      Y                                         Y
      +-----< stage-1.5 не настроена >----------+
      |
      Y
+-----+--------------+
| загрузка stage-2   |
+-----+--------------+
      |
      +----------------------+
                             |
                             Y
                 +-----------+-----------+
                 |   загрузка grub.conf  |
                 | отображение boot меню |
                 +-----------+-----------+
                             |
                             Y
                 +-----------+-----------+               
                 |  Выбор пользователкм  |
                 |  загружаемой системы  |
                 +-----------+-----------+
                             |
                             Y
                 +-----------+-----------+               
                 |        загрузка       |
                 |  vmlinuz & initrd.img |
                 +-----------------------+

stage1 занимает 512Байт, stage1 может быть установлен или в MBR, или в boot сектор. Поскольку stage1 устанавливается или в MBR или в boot сектор, то после установки grub файл /boot/grub/stage1 можно удалить. Как правило при установке в MBR grub c бOльшей вероятностью можно сказать что будет сконфигурирован/установлен stage1.5. По сути дела в stage1.5 нет большой необходимости, может быть именно поэтому с 2-ой версии grub в stage1.5 полностью пропадет необходимость. Как бы там не было, основной задачей stage1 является загрузка stage2. В stage1.5 был реализован доступ к файлу stage2 на уровне файловой системе, а если stage1.5 не был установлен, то месторасположение файла stage2 во время установки grub задавалась как номер сектора (поэтому при неустановленном stage1.5 можно было переименовать файл stage2 и иметь работоспособный grub). Следует отметить что в stage2 реализована поддержка файловых систем. По всей видимости в новых дистрибутивах будет устанавливаться grub2.

Надеюсь что теперь у читателя сформировалось законченное представление о загрузчике grub и Вы будете в состояние определить причины возможных ошибок связанных с началом загрузки grub и дальнейшей загрузки Linux (vmlinuz и initrd.img).


2.1. [Загрузка ядра]



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

Ради интереса, можете оценить размер ядра и модулей, по сути дела это есть минмально возможный размер занимаемый Linux на жестком диске.
Ядро: # ls -lh /boot/
Модули: # du -skh /lib/modules/2.6.11-1.1369_FC4/


3. [Запуск программы init]



После того как ядро загрузилось в память запускается самая первая программа (процесс), по умолчанию это /sbin/init, при желание эту программу можно переопределить, указав ядру параметр init=/path/to/init.

Программа /sbin/init поставляется с програмным пакетом SysVinit, об этом можно узнать выполнив команду:
# rpm -qf /sbin/init

Главной задачей /sbin/init является выполнение инструкций содержащихся в файле /etc/inittab




3.1. [Чтение инструкций из файла inittab]



Выведите содержимое /etc/inittab на экран, например командой:
# cat /etc/inittab

в моем (упрощенном) случае будет:

si::sysinit:/etc/rc.d/rc.sysinit

l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6

1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2

Ваш файл /etc/inittab можно упростить, ограничив количесво виртуальных терминалов двумя:
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
respawn -- указвает init запускать программу mingetty в случае если по какой либо из причин она не работает.

Так же из стандартного inittab убраана строка id:3:initdefault: поскольку легче указывать runlevel как параметр передаваемый ядру ( это описано в разделе 2. [Загрузчик] )

Для инициализации системы Linux, init запускает скрипт инициализации который указан в файле inittab в строке:
si::sysinit:/etc/rc.d/rc.sysinit


3.1.1. [Инициализация системы]



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

Эпизод 2: Упростим /etc/rc.d/rc.sysinit до минимума, который проверяет целостность файловой системы и перемонтирует корневую партицию для возможности изменения/записи на неё (вспомните, что при загрузке ядра передавался параметр ro root=/dev/sda3 делающий корневую партицию доступной только для чтения). По всей видимости логика здесь следующая, сначала загрузить систему только на чтение данных из корневого раздела, после чего проверить целостность файловой системы, и только в случае её целостности разрешить запись на неё.

минимальным файл /etc/rc.d/rc.sysinit:

#!/bin/bash
fsck -T -A -a
mount -n -o remount,rw /

после чего перезапустил Linux... и Linux запустился!

Пока сознательно закроем глаза на вывод сообщений связанных с отсутсвием псевдо файловой системы /proc !

Обратите внимание что сокращение оригинального файла /etc/rc.d/rc.sysinit содержащего в моем случае 664 строки (подсчитать кол-во строк можно командой: # cat /etc/rc.d/rc.sysinit.orig |wc -l) не привело к краху системы.

Отмечу отдельно тот факт, что сервис sshd работает, позволяя мне камфортно набирать текст статьи в WindowsXP.

Одной из самых распространенной ошибкой обучения является начало изучения материала на сложных примерах, в нашем случае объект изучения состоит их 3-х строк, разберем их:

самая первая строка файла /etc/rc.d/rc.sysinit:
#!/bin/bash      сообщает системе что обработка содержимого файла будет производится программой /bin/bash (той самой командой, которая называется command shell).

fsck -T -A -a      для проверки файловой системы, fsck позволяет поправить файловую систему, например для случая, когда запись данных на диск была прервана внезапным в ыключением из сети компьютера, рассмотирм передаваемые параметры:
-A      fcsk пытается проверить файловые системы перечисленные в /etc/fstab (этот файл мы далее расмотрим подробнее)
-a      избавляет нас от необходимости подтверждать запрос fsck на исправление ошибок, тем самым найденные ошибки исправляются автоматически.
-T      при запуске fsck на экран не выводится ненужная информация о запуске fcsk.

Осталась последняя строка:
mount -n -o remount,rw /      перемонтирование корневой файловой системы в режим чтения/записи, рассмотирм передаваемые параметры:
-n      результаты монтирования не будут записаны в файл /etc/mtab
-o      указывает что далее последуют опции (в нашем примере это remount,rw)
remount,rw      непосредственно переводит уже подмонтированную корневую файловую систему в режим чтения/записи

Эпизод 3: (можно сказать продолжение Эпизода 2) удалил все ссылки из директории /etc/rc.d/rc3.d и написал свой скрипт запуска сети и sshd.

После того как выполнены инструкции из файла /etc/rc.d/rc.sysinit осуществляется запуск скриптов, ссылки на которые содержатся в директории /etc/rc.d/rcX.d , где Х - номер runlevel (для расматриваемого примера это 3, директория /etc/rc.d/rc3.d ).

Прежде чем думать на тему, какие скрипты из тех что перечислены в директории /etc/rc.d/rc3.d нам нужные, а какие нет, сформируем свое требование: иметь удаленный доступ к системе, через ssh.
Сказано -- сделано, все что было в директории /etc/rc.d/rc3.d удалено, командой:
# rm -f *

Теперь пришло время, написать свой скрипт назовем его /etc/rc.d/rc.minFC, который поднимает сетевой интерфейс (задание TCP/IP - параметров) и запустит демон удаленного администрирования (sshd):

#!/bin/sh

modprobe 8139too
ifconfig eth0 192.168.10.101 netmask 255.255.255.0 up
route add default gw 192.168.10.5

/usr/sbin/sshd

теперь создадим в диреткории /etc/rc3.d/ символьную ссылку на него:
# cd /etc/rc.d/rc3.d
# ln -s ../rc.minFC S76minFC

После чего перезапустил Linux... и Linux запустился!
однако зайти удаленно оказалось не возможным, после ввода пароля вывелось сообщение:
Server refused to allocate pty

Это означает что не было создано устройства /dev/pts, все логично, ведь если посмотреть на схему загрузки Linux мы опустили монтирование файловых систем перечисленных в файле /etc/fstab, в котором есть строка:
/dev/devpts      /dev/pts      devpts    gid=5,mode=620      0   0
Поэтому сократил файл /etc/fstab до одной выше приведенной строки.

И для обработки интсрукций содержащихся в файле /etc/fstab в конец файла /etc/rc.d/rc.sysinit добавил строку:
mount -a
монтирования файловых систем из файла /etc/fstab, файл /etc/rc.d/rc.sysinit станет:

#!/bin/bash
fsck -T -A -a
mount -n -o remount,rw /
mount -a

Все в порядке, Linux запустился! и есть удаленный доступ через ssh

Резюме для Эпизод-2 и Эпизод-3:

  • Linux пишет информацию о событиях в системе в лог-файлы, для рассмотренных эпизодов лог-файлы остануться не измененным. Это легко проверить обнулив файлы: /var/log/messages и /var/log/dmesg командами:
    # > /var/log/messages
    # > /var/log/dmesg
    И убедится, что после перезапуска Linux, они останутся пустыми. При желание можно вывести информацию выводимую при загрузке ядра на экран можно командой:
    # dmesg |less
  • команды top, ps не работают, выдавая при из старте сообщение:
    /proc is not mounted, required for output data
    Связанное с тем, что псевдо файловая система proc не была смонтирована.
    Решением данной проблемы служить добавление в файл /etc/rc.d/rc.sysinit строки:
    mount -n -t proc /proc /proc
  • При малом количестве опреативной памяти, существует опасность падения системы, так как файл подкачки (swap) не включен, для этого необходимо добавить в файл /etc/rc.d/rc.sysinit строку:
    swapon /dev/sda2

    В итоге, минимальным скриптом иницализации системы станет файл: /etc/rc.d/rc.sysinit:

#!/bin/bash
mount -n -t proc /proc /proc
fsck -T -A -a
mount -n -o remount,rw /
mount -a
swapon /dev/sda2

Единственной попыткой описания содержимого rc.sysinit на момент написания этого материала была сатья "Linux rc.sysinit script" по адресу:
http://www.comptechdoc.org/os/linux/startupman/linux_surcsysinit.html
но к сожалению в ней не достаточно подробно освещены некоторые моменты, в связи с чем много советов типа "смотри man". Из этой "Linux rc.sysinit script" я узнал, что значения многих используемых переменных в /etc/rc.d/rc.sysinit устанавливаются в файле /etc/rc.d/init.d/functions !

После написания этой статьи, появилась хорошая статья описывающая аналог rc.sysinit для Slackware: "Система инициализации Slackware Linux "
http://wiki.kryukov.biz/wiki/

Итогом раздела "3.1.1. [Инициализация системы]" можно считать

  • Cократившееся приблизительно в два раза время загрузки системы, в моем случае с 16сек. (сервисы: syslogd,sshd,network,crond,gpm) оно сократилось до 7сек. для P4-2.8GHz., для более слабых компьютеров разница будет большей.
  • Простой и понятный скрипт инициализации системы /etc/rc.d/rc.sysinit

    Поскольку многие моменты были изложены немного сумбурно в Эпизодах 2 и 3 то далее продолжим изложение матреиала, согласно приведенной вначале статьи схемой.


3.1.1.1. [Cоздание псевдо файловых систем]



файловая система proc является pseudo-системой, содержащей информацию о процессах, памяти и так далее. Данные из этой псевдо-файловой системы активно используются системой и такими популярными программами как top и ps.

Монтирование псевдо-файловой системы proc выполняется командой:
mount -n -t proc /proc /proc
где параметр:
-n     сообщает не записывать информацию о смонтированной системы в файл /etc/mtab ;
-t     указывает тип файловой системы, в нашем случае это proc ;
/proc /proc     определяет, что подмонтированное устройство (device) /proc будет закрепленно за директорией /proc;

Ознакомление с /proc крайне полезно, ради интереса выполните ниже приведенные команды:
# cat /proc/cpuinfo
# cat /proc/meminfo
# cat /proc/1/cmdline


3.1.1.2. [Проверка файловой системы]



При запуске системы, корневая директория монтируется с доступом только на чтение, это можно узнать по передаваемому ядру параметру:
ro root=/dev/sda3
где ro      указвает что третья партиция /dev/sda3 доступна только для чтения данных.

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

Для проверки фаловой системы, в скрипте /etc/rc.d/rc.sysinit имеется строка:
fsck -T -A -a
Где параметры определяют действия выполняемые fsck:
-A      fsck пытается проверить файловые системы перечисленные в /etc/fstab (этот файл будет расмотрен в дальнейшем)
-a      избавляет нас от необходимости подтверждать запрос fsck на исправление ошибок, тем самым найденные ошибки исправляются автоматически.
-T      при запуске fsck на экран не выводится ненужная информация о запуске fcsk.


3.1.1.3. [Монтирование файловых систем]


В системе Linux существует специальный файл /etc/fstab содержащий список устройств, доступ к данным которых может быть получен. Синтаксис /etc/fstab следующий:

[filesystem]  [mount-point]  [fs-type]  [options]         [dump]  [fsck-order]

Например:

/dev/pts                /dev/pts                devpts  gid=5,mode=620  0 0
/dev/shm                /dev/shm                tmpfs   defaults        0 0

При конфигурации ядра (файл конфигурации ядра можете посмотреть здесь ) была отмечена опция "Virtual memory file system support (former shm fs)" которая повышает быстродействие системы.
Повышение быстродествия достигается засчет создания файловой системы по сути дела в оперативной памяти.
если Вы хотите использовать "Virtual memory file system" то в файл /etc/fstab необходимо добавить строку (сервер ISP-serv может работать и без этого):
/dev/shm      /dev/shm      tmpfs    defaults      0   0

Так же на опыте из Эпизода 3 для полноценной работы с терминалом необходимо подмонтировать устройство /dev/pts, для чего в файле /etc/fstab должна быть строка:
/dev/devpts      /dev/pts      devpts    gid=5,mode=620      0   0

Для выполнения монтирования устройств, перечисленных в файле /etc/fstab, в файле /etc/rc.d/rc.sysinit необходимо иметь следующую строку:
mount -a
Которая монтирует файловые системы указаные в файле /etc/fstab


3.1.1.4. [Монтирование swap]


В Linux, так же как и в Windows, существует понятие виртуальной памяти. Использование виртуальной памяти позволяет отводить процессам больше памяти, чем реально установлено оперативной памяти в компьютере.
Такая возможность достигается засчет использования swap раздела, в который "скидываются" данные из оперативной памяти принадлежащие малоактивным процессам.

Класическим примером использования swap, является команда:
# swapon -a
где параметр:  -a    указывает что для swap будет использоваться устройство у которого в файле /etc/fstab название точки монтирования есть swap, например:
/dev/sda2     swap     swap     defaults      0   0

Однако мне больше нравится явно передавать команде swapon параметр указывающий какой раздел жесткого диска является swap, поэтому в моем /etc/rc.d/rc.sysinit есть строка :
swapon /dev/sda2

Для вывода текущей информации об использование swap выполните команду:
# cat /proc/swaps


3.1.2. [Переход на указанный runlevel]


На тему уровней много написано, например все в той же статье "От включения питания до приглашения Bash":
http://www.opennet.ru/docs/RUS/FromPowerUpToBash/#s6

В самом начале стандартного файла /etc/inittab Вы наверняка найдете описание уровней работы Linux:

# Default runlevel. The runlevels used by RHS are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)

Обычно для Linux десктопа используют 5-й уровень, а для сервера 3-й который можно назвать консольным уровнем, поскольку в нем есть только текстовый режим дисплея. Отмечу что так принято, Вы же можете радикально изменить сложившиеся установки.
Что вам для этого надо? Только разместить в каталоге /etc/rc.d/rcX.d (Х - номер runlevel) ссылки на те cкрипты запуска сервисов, которые вы хотите использовать.

Поскольку в Linux можно переходить с одного runlevel на другой, например команда:
# init 5 ,     где 5 -- runlevel
то необходимо сначала останавливать сервисы того runlevel с которого уходишь и запускать те сервисы runlevel на который осуществляется переход. Для этого линки/ссылки на стартующие скрипты имеют названия начинающие с "S" после которого идет порядковый номер, аналогично для ссылок на те скрипты сервисов которые надо остановить. Посмотрите какие линки есть для 3 runlevel, командой:
# ls -l /etc/rc.d/rc3.d/

Отмечу, что Вас никто не органичивает так же сменить директорию где распложены ссылки на запускаемые скрипты сервисов, для этого надо изменить в файле /etc/inittab строки:

l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6

Как правило для сервера достаточно запуска следующих сервисов:
syslogd,sshd,network,crond


3.1.3. [Запуск виртуального терминала]


Виртуальный терминалом можно назвать консоль, где мы вводим команды, и переключаемся меду ними Alt+F1,Alt+F2,Alt+F3 или Alt+F4 respawn:/sbin/mingetty tty1 указывает программе /sbin/init в случае прекращения процесса связанного с программой /sbin/mingetty снова запустить пограммму /sbin/mingetty.

Для авторизации mingetty вызывает программу login, после ввода правильного login/password пользователь получает доступ к командному интерпретатору системы (command shell).


Заключительная настройка скриптов загрузки для ISP-serv


Поскольку основные моменты загрузки системы уже разобраны, то не буду многословным, а просто приведу листинги используемых скриптов:
/etc/rc.d/rc.ISP

#!/bin/bash

/sbin/syslogd

ifconfig lo 127.0.0.1
ifconfig eth0 xx.xx.xx.ip up
ifconfig eth1 192.168.0.1 up
route add default gw xx.xx.xx.gw

/usr/sbin/named -u named -t /var/named/chroot
/usr/sbin/sshd
/usr/sbin/crond
chmod 777 /dev/null

cd /ISP-serv 
./nat-firewall 
./mark-isp.sh
./traffic-isp.sh 

/etc/rc.d/rc.sysinit

#!/bin/bash
hostname ISP
mount -n -t proc /proc /proc
fsck -T -A -a
mount -n -o remount,rw /
mount -a
swapon /dev/hda2

/etc/fstab

/dev/pts                /dev/pts                devpts  gid=5,mode=620  0 0
/dev/shm                /dev/shm                tmpfs   defaults        0 0



Прокоментируем отельные строки из приведенных скриптов:

chmod 777 /dev/null     для того, что бы не было сообщений:
-bash: /dev/null: Permission denied

/usr/sbin/named -u named -t /var/named/chroot     запуск DNS сервера

/usr/sbin/crond     запуск планировщика задач

ifconfig lo 127.0.0.1     поднятие loopback интрефейса (ip: 127.0.0.1) поскольку в файле /etc/resolv.conf в качестве dns-сервера указан: 127.0.0.1 ( nameserver 127.0.0.1 )


обсуждение в форуме
http://www.opennet.ru/opennews/art.shtml?num=7025


Andrejs Spunitis: spunitis AT one.lv
ДАТА: 27 февраля, 2006 г.