Як системне відключення ядра Linux працює внутрішньо?


28

У мене є якось приблизне уявлення про те, як користувальний простір та init-система (будь то класичний init sysV / upstart / systemd) працюють при відключенні системи. (По суті, є послідовне замовлення "Стоп!", "Будь ласка, припини зараз реально", "Процес, я повинен вбити тебе, щоб зупинити", і чекаємо ... все триває).

Я все одно не знаю, як працює відключення системи в ядрі (де, звичайно, також є багато чого робити)?

Я спробував заглянути в документацію ядра https://www.kernel.org/doc/htmldocs/ і навіть застосував інструмент пошуку NSA для того, щоб допомогти мені дізнатися, як це працює.

Також я шукав на SE U + L і нічого не знайшов (я його не помічав?)

У будь-якому випадку питання, хоч і може бути трохи складним, заслуговує на відповідь у цій Q&A мережі, оскільки я припускаю, що більше людей зацікавлені отримати ескіз до того, що відбувається в ядрі Linux при відключенні.

Потенційно також можливі зміни, що стосуються деяких більш детальних пояснень.

Відповідь, можливо, може включати, які системні дзвінки та які сигнали ядра використовуються?

https://github.com/torvalds/linux/blob/b3a3a9c441e2c8f6b6760de9331023a7906a4ac6/arch/x86/kernel/reboot.c здається, що використовується файл x86, пов’язаний із перезавантаженням (вже близький до завершення роботи, так?)

може бути, фрагмент, знайдений тут http://lxr.free-electrons.com/source/kernel/reboot.c#L176, може бути використаний для пояснення

176 недійсний kernel_power_off (недійсний)
177 {
178 kernel_shutdown_prepare (SYSTEM_POWER_OFF);
179, якщо (pm_power_off_prepare)
180 pm_power_off_prepare ();
181 migrate_to_reboot_cpu ();
182 syscore_shutdown ();
183 pr_emerg ("Вимкнення живлення \ n");
184 kmsg_dump (KMSG_DUMP_POWEROFF);
185 machine_power_off ();
186}
187 EXPORT_SYMBOL_GPL (kernel_power_off);

8
нехай єдиноріг буде з вами
Ківі

1
@Kiwy дякую за пропозицію. Я прийму, коли пройде якийсь час, щоб з’явитись потенційні кращі відповіді. Але принаймні якась відповідь зараз є.
humanityANDpeace

Не дякую, дякую Єдинорогу!
Ківі

Будьте в курсі, що існує / був варіант вистрибування вікна,shutdown(8) тобто застарілий, -n який, я думаю, у старій документації на Unix, який використовується для читання " відключення системи самі - основний блок на ВОГНІ! ", Фактично безладний перемикач системи вбивства, який міг / міг би залишити біти, розкидані по підлозі (або принаймні файлові системи в корумпованому стані) - можна уявити, що це буде використано для системи основного кадру, де хтось щойно потрапив їх рукою у вентилятор охолодження. 🕱
SlySven

Відповіді:


26

Основні ресурси для розуміння того, як працює ядро ​​Linux, це:

  1. Документація .
  2. Статті про щотижневі новини Linux .
  3. Джерело. Це складний звір, якого трохи легше зрозуміти через LXR , Linux-перехресне посилання. Варіант LXR, який працює на lxr.linux.no , приємніший за інші, але він часто знижується.

У цьому випадку я не можу знайти нічого важливого в документації чи на LWN, тому LXR це.

Останнє, що робить код userland, - це виклик rebootсистемного виклику . Це займає 4 аргументи, тому шукайте SYSCALL_DEFINE4(rebootпо LXR, що призводить до kernel/reboot.c. Після перевірки привілеїв абонента і аргументи, точка входу системного виклику викликає один з декількох функцій: kernel_restartдля перезавантаження, kernel_haltщоб зупинити на тугою петлею, kernel_poweroffщоб вимкнути живлення системи, kernel_kexecщоб замінити ядро на новий (якщо скомпільований в), або hibernateщоб зберегти пам'ять на диску перед відключенням живлення.

kernel_restart, kernel_haltі kernel_power_offдосить схожі:

  1. Пройдіть reboot_notifier_list, це список гачків, які компоненти ядра можуть зареєструвати для виконання коду при відключенні живлення. На цьому етапі лише кілька водіїв повинні виконувати код, в основному сторожові собаки.
  2. Встановити system_stateзмінну.
  3. Вимкніть помічник користувальницького режиму , щоб переконатися, що більше не буде запущено код користувача. (На цьому етапі ще можуть бути існуючі процеси.)
  4. Зателефонуйте, device_shutdownщоб випустити або вимкнути всі пристрої в системі. Дуже багато водіїв зачіпають цей етап.
    Зауважте, що будь-які файлові системи, які все ще встановлені в цей момент, фактично примусово відключаються. Абонент системного дзвінка несе відповідальність за будь-яке чисте відключення.
  5. Тільки для вимкнення живлення, якщо ACPI налаштовано, можливо, виконати код для підготовки до переходу в стан ACPI S5 (м'яке відключення живлення).
  6. У машині з декількома процесорами код може працювати на будь-якому процесорі, залежно від того, що викликало системний виклик. migrate_to_reboot_cpuдбає про перехід на один конкретний процесор і не дозволяє планувальникові розсилати код на інших процесорах. Після цього пункту працює лише один процесор.
  7. syscore_shutdownназиває shutdownметод зареєстрованих операцій syscore . Я думаю, що це здебільшого стосується відключення перерв; кілька гачків мають shutdownметод.
  8. Введіть інформаційне повідомлення - пісню лебедя.
  9. Нарешті, перейдіть на відпочинок якимсь машинним способом, зателефонувавши machine_restart, machine_haltабо machine_power_off.

Глибокого сну код проходить через наступні етапи:

  1. Ітерація через гачки управління живленням .
  2. Синхронізація файлових систем.
  3. Заморозити весь код користувача .
  4. Запобігайте гарячому підключенню пристрою .
  5. Скиньте стан системи до місця обміну.
  6. Якщо все вдалося, перезимуйте обладнання . Це може включати в себе виклик kernel_restart, kernel_haltабо kernel_power_off, або які - або конкретна платформи метод глибокого сну.

Інший спосіб вимкнення системи - це machine_emergency_restart. На це викликається чарівна клавіша SysRqB . OКлюч працює по- іншому: він викликаєkernel_power_off .

Система також може відключитися до паніки , тобто непоправної помилки. Панікуючи спроби зареєструвати повідомлення, а потім перезавантажити систему (через апаратну сторожову собаку або екстрений перезапуск).


+1 спасибі! @Gilles, якщо ви хочете реалізувати якийсь код, який би стирав / санаціонував оперативну пам’ять машини як lasttep, ви зареєструєте операцію syscore для syscore_shutdown(тобто це вирішило б моє інше питання unix.stackexchange.com/q/122540/24394 ) . Крок (1) і крок (7) дозволяють реєструвати речі, які будуть виконуватися при відключенні, не враховуючи, що це + У мене склалося враження, що на порядок виконання цих зворотних викликів у (1) та (7) не може вплинути! Я буду документами, про яких ви згадали, але якщо знаєте! Спасибі!
humanityANDpeace

Я здивований цим запитанням, і відповідь не має більших відгуків.

2

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

Вміст цієї відповіді взято з kernel/reboot.cфайлу ядра Linux 3,13 (що може бути не першим здогадком, оскільки ім'я не shutdown.c, а reboot.c)

У будь-якому випадку у нас є три функції, які накреслюють процес вимкнення системи

  • void kernel_halt(void) // яка закінчується системою у стані зупинки
  • void kernel_power_off(void) // що закінчується вимкненою системою
  • void kernel_restart(char *cmd) // яка закінчує систему, щоб все-таки її перезапустити

Ці функції дуже короткі, тому їх можна вставити в повному обсязі. Їх код найкраще показує, які кроки зроблені на шляху до відключення в ядрі. (коментарі є мною і, можливо, не на 100% ідеальні та правильні, перевірте себе на впевненість. Спроба проста.

void kernel_halt(void)

недійсний kernel_halt (недійсний)
{
    // 1-й крок робить:
    // a) Функції виклику / зворотний дзвінок зареєстровані для запуску при перезавантаженні / відключенні
    // b) встановіть system_sate на SYSTEM_HALT
    // c) припинити взаємодію з користувацьким простором
    // d) викликати функцію device_shutdown ()
    kernel_shutdown_prepare (SYSTEM_HALT);

    // Другий крок: Я думаю, що це в основному необхідність для систем з декількома процесорами
    migrate_to_reboot_cpu ();

    // 3-й крок:
    // syscore_shutdown - Виконання всіх зареєстрованих зворотних викликів відключення ядра системи 
    syscore_shutdown ();

    // 4-е повідомлення
    pr_emerg ("Система зупинена \ n");
    kmsg_dump (KMSG_DUMP_HALT);

    // 5-й специфічний cpu-halt-код для арки викликів
    machine_halt ();
}

вся справа ініціюється із sys_rebootсистемним викликом, який, враховуючи, що він не тільки перезавантажує, але й відключає, а не пряму річ, щоб зв’язатись із процесом відключення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.