Назва

init, telinit - започатковує контроль над процесами

Звід

/sbin/init [ -a ] [ -s ] [ -b ] [ -z xxx ] [ 0123456Ss ]
/sbin/telinit [ -t секунд ] [ 0123456sSQqabcUu ]

Опис

Init

Init є батьківським для всіх процесів. Його головне завдання полягає у створенні інших процесів, перелічених у файлі /etc/inittab (див. inittab(5)). Цей файл, як правило, містить записи що призводять до запуску багатьох ?getty для кожної (комунікаційної) лінії по якій користувачі можуть входити до системи. Також він керує автономними процесами, необхідними кожній окремій системі.

Робочі рівні

Робочі рівні - це програмна конфігурація системи, яка дозволяє існування лишень певних груп процесів. Процеси запускаються init у відповідності з кожним робочим рівнем, означеним у /etc/inittab. Init може знаходитись у одному з восьми робочих рівнів: 0-6 і S або s. Робочий рівень може бути змінено якщо привілейований користувач виконає telinit, який в свою чергу пошле відповідний сигнал init, вказуючи до якого саме робочого рівня потрібно перейти.

Робочі рівні 0, 1 і 6 резервовані. Рівень 0 використовується для зупинки системи, 6 - для її рестарту, тоді як 1 - для того щоб помістити систему в однокористувацький режим. Робочий рівень S не є для безпосереднього вжитку, скоріше його створено для скриптів що буде виконано під час входу до 1-го робочого рівня. Для додаткової інформації також перегляньте сторінки ?shutdown(8) та inittab(5).

Робочі рівні 7-9 також чинні, але їх не документовано. Традиційні варіанти Юніксів не послуговуються ними. Для цікавих, робочі рівні S і s, насправді, являються одним і тим самим. Внутрішньо, вони розглядаються як синоніми для того самого робочого рівня.

Завантаження

Останнім кроком завантаження ядра буде виклик init, який розгляне /etc/inittab щоб з'ясувати чи присутній там рядок із initdefault (див. inittab(5)). Запис initdefault вказує на робочий рівень системи за замовчуванням. Якщо такий рядок відсутній (або немає /etc/inittab взагалі), робочий рівень необхідно буде ввести у системній консолі.

Робочий рівень S призначено для того щоб ввести систему у однокористувацький режим і не вимагає файлу /etc/inittab. У однокористувацьому режимі буде викликано /sbin/sulogin на /dev/console.

Під час входу у однокористувацький режим, init прочитає ioctl(2) консолі з /etc/ioctl.save. Якщо цей файл відсутній, init встановить лінію до 9600 бод із CLOCAL параметрами. Під час виходу з однокористувацкого режиму, init збереже ioctl-параметри консолі у цьому файлі для пізнішого використання у однокористувацьких сесіях.

Перший раз входячи у багатокористувацький режим, init виконає boot та bootwait пункти (з /etc/inittab) щоб забезпечити монтування файлових систем до того як користувачі зможуть зареєструватись. Потім усі пункти що відповідають встановленому робочому рівневі будуть переглянуті.

Під час започатковування нових процесів, init перевіряє на наявність файлу /etc/initscript. Якщо такий присутній, init використає його для запуску процесу.

Кожний раз як дочірній процес завершується, init занотовує це разом з причиною чому він припинив свою роботу у /var/run/utmp та /var/log/wtmp, за умови що ці файли існують.

Зміна робочого рівня

Після запуску всіх вказаних йому процесів, init очікує припинення роботи одного з дочірних процесів, сигналу втрати живлення або доки telinit не вкаже змінити системний робочий рівень. Якщо відбудеться одна з вищевказаних умов, він перегляне знову файл /etc/inittab. Нові пункти можуть бути доданими до цього файлу у будь-який момент, тим не менш, init очікує одну з трьох вказаних нами умов щоб його переглянути. При необхідності негайної реакції, нам потрібно заставити init перечитати inittab командою telinit Q або telinit q.

Якщо init, не знаходячись у однокористувацькому режимі, отримає сигнал втрати живлення (SIGPWR), він прочитає файл /etc/powerstatus. Після цього він виконає команду, основуючись на вмістові цього файлу:

F(AIL) : Живлення відсутнє, UPS (резервна батарея) підтримує живлення. Буде виконано пункти. powerwait і powerfail.

O(K) : Живлення відновлено, виконає пункт powerokwait.

L(OW) : Живлення виходить з ладу і батарея UPS недостатньо заряджена. Буде виконано пункт powerfailnow.

Якщо /etc/powerstatus відсутній або містить щось інше замість літер F, O або L, init поводитиметься так ніби він прочитав літеру F.

Використання SIGPWR і /etc/powerstatus не заохочується. Якщо необхідна взаємодія з init, краще скористатися контрольним каналом /dev/initctl (подивіться вихідний код пакету sysvinit щодо документації).

Коли від init вимагають поміняти робочий рівень, він посилає попереджувальний сигнал SIGTERM всім процесам, не означеним у новому рівні. Після цього почекає 5 секунд до того як примусово припинити ці процеси з допомогою SIGKILL. Зауважте що init припускає що всі ці процеси (і їхні нащадки) знаходяться у тій самій групі процесів що була створена для них init. Якщо якийсь процес змінить власну належність до групи, він не отримає цих сигналів. Такі процеси необхідно завершити окремо.

Telinit

/sbin/telinit є лише посиланням на /sbin/init. telinit візьме лише один знак як аргумент і вкаже init здійснити відповідну дію. Наступні аргументи служать вказівкою telinit:

0,1,2,3,4,5 або 6 : Вкаже init перейти до відповідного робочого рівня.

рівень як a, b або c. (?)

a,b,c : Вкаже init обробити лише ті пункти з /etc/inittab що мають робочий

Q або q : Вкаже init перечитати /etc/inittab.

S або s : Вкаже init перейти до окднокористувацького режиму.

U або u : Вказує init перезапустити самого себе (зберігаючи стан (?)). Перегляд /etc/inittab не відбудеться. Поточний робочий рівень повинен бути одним з Ss12345, в протилежному випадку запит буде просто ігноровано.

telinit може також вказати init скільки часу потрібно почекати між посланням сигналів SIGTERM і SIGKILL. За замовчуванням, час дорівнюватиме 5-и секундам, але його можна змінити з допомогою опції -t секунд.

telinit може бути викликаним лише користувачами з відповідними привілеями.

Бінарій init перевіряє чи він був викликаний як init чи telinit подивившись на власний ідентифікатор процесу (process ID). ID справжнього init завжди дорівнюватиме 1. З цього також слідує що замість виклику telinit можна безпечно викликати init, просто як синонім-скорочення.

Середовище

Init встановлює наступні змінні середовища для всіх свої нащадків:

PATH : /usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin

був запущений безпосередньо з init.

INIT_VERSION : Зберігає версію init. Корисне також для вияснення чи певний скрипт

RUNLEVEL : Поточний робочий рівень системи.

PREVLEVEL : Попередній робочий рівень (після зміни робочих рівнів).

CONSOLE : Вказує на системну консоль. Насправді успадковується від ядра; тим не менш, якщо не є встановленою, init надасть цій змінній значення `/dev/console'.

Прапорці завантаження

У вас є можливість передати певну кількість прапорців init з керівника завантаження (напр. LILO). Init розпізнає наступні прапорці:

-s, S, single : Завантаження у однокористувацький режим. У цьому режимі, буде прочитано /etc/inittab і відповідні стартові rc-скрипти буде виконано перед тим як надати оболонку однокористувацького режиму.

1-5 : Робочий рівень у який завантажитись.

-b, emergency : Завантажитись безпосередньо у однокористувацьку оболонку без виконання жодних стартових скриптів.

-a, auto : LILO автоматично додає слово "auto" як параметр init на командній лінії, якщо завантаження ядра пройшло без втручання користувача. В такому випадку init також встановить змінну середовища AUTOBOOT до "yes". Зауважте, це не використовується як засіб безпеки, - користувач сам може внести "auto" або -a на командній лінії.

-z xxx : Аргументи до -z буде ігноровано. Ви можете використовувати це просто щоб продовжити трохи рядок команди, тож вона займе трохи більше місця у стеку. У такому разі init може маніпулювати командний рядок таким чином щоб ?ps(1) показувала поточний робочий рівень.

Пристрої

Init слухає fifo-файл з /dev каталогу - /dev/initctl, на предмет повідомлень. telinit також використовує цей пристрій для комунікації з init. Даний інтерфейс недостатньо документовано. (Ті хто зацікавлений, повинні передивитись файл initreq.h з src/ підкаталогу у ієрархії вихідного коду init/)

Сигнали

Init відповідає на наступні сигнали:

SIGHUP : При отриманні цього сигналу, init прочитає /etc/initrunlvl і /var/log/initrunlv. Якщо хоч один з цих файлів присутній і містить знак робочого рівня у ASCII формі (звичайний текст), init перейде до нового рівня. Ця поведінка збережена лише для сумісності зі старшими системами. За нормальних обставин (тобто ці файли відсутні), init поводитиметься так ніби telinit q було виконано.

SIGUSR1 : При отриманні цього сигналу, init закриє і відкриє назад власний контролюючий fifo-файл, /dev/initctl. Може використовуватись із стартовими скриптами у випадку перемонтовування /dev.

SIGINT : Як правило, ядро пошле цей сигнал init після притиску клавіш CTRL-ALT-DEL. Це активує дію ctrlaltdel з /etc/inittab.

SIGWINCH : Ядро пошле цей сигнал після притиску клавіші KeyboardSignal. Це активує дію kbrequest з /etc/inittab.

Відповідність

Init є сумісним з System V init. Працюватиме разом з скриптами з /etc/init.d і /etc/rc{рівень}.d каталогів. Якщо ваша система використовує цю умовність, каталог /etc/init.d повинен містити файл README, який пояснюватиме як ці скрипти працюють.

Файли

/etc/inittab
/etc/initscript
/dev/console
/etc/ioctl.save
/var/run/utmp
/var/log/wtmp
/dev/initctl

Попередження

Init припускає що процеси і їхні нащадки залишаються у тій самій групі процесів яка була для них створена init. Якщо процеси поміняють групу, init не зможе припинити їх і ви можете опинитись у ситуації коли два різні процеси зчитуватимуть з тієї самої лінії терміналу. (?)

Діагностика

Якщо init виявить що він постійно перезапускає один з пунктів з /etc/inittab більше ніж 10 раз за 2 хвилини, він вважатиме що з'явилась помилка у командному рядку. Init виведе повідомлення про помилку на системній консолі і відмовиться перезапускати цей рядок на протязі 5-и хвилин, або до отримання сигналу. Це запобігає споживанню системних ресурсів у випадку якщо хтось зробить синтаксичну помилку у /etc/inittab або якась програма, вказана там, не присутня більше.

Автор

Miquel van Smoorenburg (miquels@cistron.nl), оригінальна сторінка посібника була написана Michael Haardt (u31b3hs@pool.informatik.rwth-aachen.de).

Переклав Віталій Цибуляк (vi@uatech.atspace.com).