Bagaimana sistem shutdown dari kernel linux bekerja secara internal?

28

Entah bagaimana saya memiliki gambaran kasar tentang bagaimana userspace dan init-system (baik itu init klasik sysV / pemula / systemd) bekerja pada sistem shutdown. (Pada dasarnya ada urutan suksesi "Stop!", "Tolong hentikan sekarang benar-benar", "Proses saya perlu membunuh Anda untuk Berhenti" dan menunggu ... hal-hal yang terjadi).

Bagaimanapun saya sangat tidak menyadari bagaimana sistem shutdown bekerja di kernel (di mana pasti ada juga banyak hal yang harus dilakukan)?

Saya mencoba melihat ke dalam dokumentasi kernel https://www.kernel.org/doc/htmldocs/ dan bahkan menggunakan alat pencarian sahabat NSA untuk memberi saya langkah awal untuk mengetahui cara kerjanya.

Saya juga mencari di SE U + L dan tidak menemukan apa-apa (apakah saya mengabaikannya?)

Bagaimanapun pertanyaannya, meskipun berpotensi sedikit menantang, akan pantas dijawab dalam jaringan tanya jawab ini karena saya berasumsi lebih banyak orang tertarik untuk mendapatkan sketsa untuk apa yang terjadi pada kernel linux saat shutdown.

Berpotensi ada juga perubahan untuk menghubungkan ke beberapa penjelasan yang lebih rinci.

Sebuah jawaban mungkin mencakup panggilan sistem dan sinyal kernal apa yang digunakan?

https://github.com/torvalds/linux/blob/b3a3a9c441e2c8f6b6760de9331023a7906a4ac6/arch/x86/kernel/reboot.c tampaknya merupakan file x86 yang digunakan terkait dengan reboot (sudah dekat dengan shutdown, eh?)

mungkin cuplikan yang ditemukan di sini http://lxr.free-electrons.com/source/kernel/reboot.c#L176 dapat digunakan untuk memberikan penjelasan

176 void kernel_power_off (void)
177 {
178 kernel_shutdown_prepare (SYSTEM_POWER_OFF);
179 if (pm_power_off_prepare)
180 pm_power_off_prepare ();
181 migrate_to_reboot_cpu ();
182 syscore_shutdown ();
183 pr_emerg ("Matikan \ n");
184 kmsg_dump (KMSG_DUMP_POWEROFF);
185 machine_power_off ();
186}
187 EXPORT_SYMBOL_GPL (kernel_power_off);
humanityANDpeace
sumber
8
semoga unicorn menyertai Anda
Kiwy
1
@ Kyiwy terima kasih atas sarannya. Saya akan menerima setelah beberapa waktu berlalu untuk kemungkinan jawaban yang lebih baik muncul. Tetapi setidaknya beberapa jawaban sekarang ada di sana.
humanityANDpeace
Jangan berterima kasih padaku, terima kasih Unicorn!
Kiwy
Perlu diketahui bahwa ada / adalah lompatan keluar opsi jendelashutdown(8) yaitu yang sudah usang -n yang saya pikir dalam dokumentasi unix lama yang digunakan untuk membaca " mematikan sistem sendiri - unit inti adalah PADA KEBAKARAN! " Secara efektif sistem mematikan-switch yang berantakan akan / bisa meninggalkan bit tersebar di lantai (atau setidaknya sistem file dalam keadaan korup) - orang membayangkan ini akan digunakan untuk sistem tipe kerangka utama di mana seseorang baru saja menangkap tangan mereka di kipas pendingin. 🕱
SlySven

Jawaban:

26

Sumber daya utama untuk memahami cara kerja kernel Linux adalah:

  1. Dokumentasi .
  2. Artikel Linux Weekly News .
  3. Sumber. Ini adalah binatang yang kompleks yang sedikit lebih mudah untuk ditangkap melalui LXR , referensi silang Linux. Varian LXR yang berjalan di lxr.linux.no lebih bagus daripada yang lain, tetapi sering turun.

Dalam hal ini, saya tidak dapat menemukan apa pun yang relevan secara terpusat dalam dokumentasi atau pada LWN, jadi LXR itu.

Hal terakhir yang dilakukan oleh kode pengguna adalah memanggil panggilan rebootsistem . Dibutuhkan 4 argumen, jadi cari SYSCALL_DEFINE4(rebootdi LXR, yang mengarah ke kernel/reboot.c. Setelah memeriksa hak pemanggil dan argumen, entry point syscall menyebut salah satu dari beberapa fungsi: kernel_restartuntuk reboot, kernel_haltberhenti pada lingkaran yang ketat, kernel_poweroffuntuk matikan sistem, kernel_kexecuntuk mengganti kernel dengan yang baru (jika disusun dalam), atau hibernateuntuk menyimpan memori ke disk sebelum mematikan.

kernel_restart, kernel_haltdan kernel_power_offcukup mirip:

  1. Pergi melalui reboot_notifier_list, yang merupakan daftar kait yang komponen kernel dapat mendaftar untuk mengeksekusi kode pada powerdown. Hanya beberapa driver yang perlu menjalankan kode pada tahap ini, kebanyakan pengawas.
  2. Atur system_statevariabelnya.
  3. Nonaktifkan usermode-helper , untuk memastikan bahwa tidak ada kode pengguna yang akan dimulai lagi. (Masih ada proses yang ada pada tahap ini.)
  4. Panggilan device_shutdownuntuk melepaskan atau mematikan semua perangkat di sistem. Banyak driver yang terhubung ke tahap ini.
    Perhatikan bahwa setiap sistem file yang masih di-mount pada saat ini secara efektif dilepas secara paksa. Penelepon panggilan sistem bertanggung jawab atas semua unmount bersih.
  5. Hanya untuk daya mati, jika ACPI dikonfigurasikan, mungkin jalankan kode untuk bersiap masuk ke kondisi ACPI S5 (soft power off).
  6. Dalam mesin multi-CPU, kode dapat dijalankan pada CPU apa pun, yang mana yang memanggil sistem panggilan. migrate_to_reboot_cpuberhati-hati untuk beralih ke satu CPU tertentu dan mencegah penjadwal mengirim kode pada CPU lain. Setelah titik ini, hanya satu CPU yang berjalan.
  7. syscore_shutdownmemanggil shutdownmetode operasi syscore terdaftar . Saya pikir ini sebagian besar tentang menonaktifkan interupsi; beberapa kait punya shutdownmetode.
  8. Catat pesan informasi - lagu angsa.
  9. Akhirnya pergi beristirahat dengan cara yang tergantung pada mesin dengan menelepon machine_restart, machine_haltatau machine_power_off.

The hibernasi kode berjalan melalui langkah-langkah berikut:

  1. Iterasi melalui kait manajemen daya .
  2. Sinkronkan sistem file.
  3. Bekukan semua kode pengguna .
  4. Cegah hotplugging perangkat .
  5. Membuang status sistem ke ruang swap.
  6. Jika semuanya berhasil, hibernasi perangkat keras . Ini dapat melibatkan panggilan kernel_restart, kernel_haltatau kernel_power_off, atau metode hibernasi khusus platform.

Cara berbeda untuk mematikan sistem adalah machine_emergency_restart. Ini dipanggil oleh kunci SysRq ajaibB . The Okey bekerja secara berbeda: itu panggilankernel_power_off .

Sistem juga dapat dimatikan karena panik , yaitu kesalahan yang tidak dapat dipulihkan. Panik mencoba mencatat pesan, kemudian mem-boot ulang sistem (baik melalui pengawas perangkat keras atau restart darurat).

Gilles 'SANGAT berhenti menjadi jahat'
sumber
+1 terima kasih! @Gilles jika Anda ingin menerapkan beberapa kode yang akan menghapus / membersihkan RAM mesin sebagai langkah terakhir, Anda akan mendaftarkan operasi syscore untuk syscore_shutdown(yaitu yang akan menyelesaikan pertanyaan saya yang lain unix.stackexchange.com/q/122540/24394 ) . Langkah (1) dan langkah (7) keduanya memungkinkan untuk mendaftarkan hal-hal yang akan dieksekusi pada saat shutdown, bukan shure apa + + Saya mendapat kesan bahwa urutan eksekusi dari callback tersebut di (1) dan (7) tidak dapat dipengaruhi! Saya akan dokumen yang Anda sebutkan, tetapi jika Anda tahu! Terima kasih!
humanityANDpeace
Saya terkejut pertanyaan dan jawaban ini tidak memiliki lebih banyak suara.
2

Ini hanya sebagian jawaban dan saya pasti mengundang jawaban lain, yang mungkin lebih lengkap dan jelas.

Isi dari jawaban ini diambil dari kernel/reboot.cfile kernel Linux 3,13 (yang mungkin bukan tebakan pertama karena namanya bukan shutdown.c tetapi reboot.c)

Ngomong-ngomong, di sana kita pada dasarnya memiliki tiga fungsi yang menggambarkan proses mematikan sistem

  • void kernel_halt(void) // yang berakhir dengan sistem dalam keadaan berhenti
  • void kernel_power_off(void) // yang diakhiri dengan sistem dimatikan
  • void kernel_restart(char *cmd) // yang mengakhiri sistem untuk belum me-restart itu

Fungsi-fungsi tersebut sangat singkat dan karenanya dapat ditempelkan di sini secara lengkap. Kode mereka menunjukkan langkah-langkah apa yang harus diambil untuk mematikan kernel. (Komentar saya dan mungkin tidak 100% ideal dan benar, periksa diri Anda untuk memastikan. Sederhana saja.

void kernel_halt(void)

batal kernel_halt (batal)
{
    // Langkah 1:
    // a) fungsi panggilan / panggilan balik terdaftar untuk dijalankan saat reboot / shutdown
    // b) atur system_sate ke SYSTEM_HALT
    // c) hentikan interaksi userspacetool
    // d) panggil fungsi device_shutdown ()
    kernel_shutdown_prepare (SYSTEM_HALT);

    // Langkah ke-2: Saya pikir ini sebagian besar kebutuhan untuk sistem multi-CPU
    migrate_to_reboot_cpu ();

    // langkah ketiga:
    // syscore_shutdown - Jalankan semua callback shutdown inti sistem terdaftar 
    syscore_shutdown ();

    // pesan ke-4
    pr_emerg ("Sistem terhenti \ n");
    kmsg_dump (KMSG_DUMP_HALT);

    // Panggilan 5 lengkung kode cpu-halt-spesifik
    machine_halt ();
}

semuanya dimulai dengan sys_rebootsystem call yang, mengingat bahwa itu tidak hanya reboot tetapi juga shutdown, bukan hal langsung untuk terhubung dengan proses shutdown.

humanityANDpeace
sumber