Hancur saat startup di komputer perusahaan baru-baru ini

63

Setelah beberapa pembaruan terakhir, komputer saya tidak lagi melakukan boot! Inilah yang bisa saya tentukan:

  • Ini adalah komputer yang sangat baru yang diberikan kepada saya oleh IT perusahaan. Ini memiliki CPU Intel terbaru (generasi Skylake).
  • Komputer menjalankan Ubuntu 16.04.
  • Komputer terakhir kali boot dengan benar pada bulan Maret. Masalahnya mungkin karena pembaruan perangkat lunak atau bug perangkat keras.
  • Saya memiliki komputer lain yang menjalankan 16,04 dengan cukup banyak perangkat lunak yang sama diinstal (saya gunakan apt-clone), dan itu berfungsi dengan baik. Ini memiliki perangkat keras yang berbeda (juga amd64, tetapi CPU berbeda, GPU berbeda, dll.).
  • Kernel mulai, initrd berfungsi dengan benar. Ketika saya boot dengan splash screen dalam mode grafik, saya diminta untuk memasukkan kata sandi untuk volume dm-crypt saya, dan hal terakhir yang saya lihat adalah berhasil dipasang.
  • Gantung terjadi sebelum saya mendapatkan prompt masuk. Ketika komputer hang, itu sulit diatasi. Bahkan Alt+ SysRqtidak merespons. CPU jelas dipatok pada 100% sejak kipas menyala penuh.
  • Saya masih memiliki kernel yang saya jalankan sebelum reboot. Ketika saya memilih kernel ini di menu Grub, saya mendapatkan penguncian yang sama. Jadi sepertinya ini adalah bug kernel yang sudah ada sebelumnya yang dipicu oleh sesuatu yang lain - tapi apa?
  • Jika saya mematikan layar splash (hapus splashdari linuxbaris perintah di Grub), saya melihat sejumlah layanan dimulai, kemudian terkunci.
  • Saya bisa mendapatkan shell root dengan menambahkan init=/bin/shke linuxbaris perintah di Grub. Saya bahkan bisa melangkah lebih jauh dengan menambahkan

    systemd.unit=basic.target systemd.shell
    

    Ini memulai sejumlah layanan dan menjalankan shell root pada tty9.

  • Jika saya lari systemctl start multi-user.targetdari shell root, komputer terkunci. Jadi mungkin masalahnya dipicu oleh salah satu layanan ini.
  • Saya berlari systemctl list-dependencies multi-user.targetuntuk melihat layanan apa yang memulai. Saya secara manual memulai dependensi yang tercantum satu per satu, dan semuanya dimulai dengan baik.

Jadi ini terlihat seperti bug perangkat keras (karena terjadi pada satu komputer tetapi tidak pada yang lain) yang dipicu oleh beberapa perangkat lunak. Tapi perangkat lunak apa? Karena komputer terkunci sangat keras, saya tidak bisa mendapatkan log. Saya bahkan tidak bisa mendapatkan output konsol yang berguna.


Teknik debugging yang berguna:

  • Alt+ SysRq: kunci SysRq ajaib , yang memungkinkan Anda melakukan hal-hal seperti reboot darurat. Ini mengakses kernel pada tingkat yang sangat rendah, sehingga bekerja di semua kecuali yang terburuk crash. Dalam kasus saya, Alt+ SysRqtidak merespons, yang menunjukkan seberapa dalam kecelakaan itu berlangsung.
  • Untuk memodifikasi parameter boot, tekan dan tahan Shiftbeberapa detik setelah menyalakan power. Anda perlu menekannya setelah BIOS menginisialisasi keyboard, tetapi sebelum sistem operasi melakukan boot. Ini membuat menu Grub muncul.
  • Di menu Grub, tekan euntuk mengedit baris perintah untuk entri menu. Untuk mengubah parameter boot Linux, navigasikan ke baris yang dimulai dengan linux. Pada Ubuntu modern, Anda akan menemukan kernel lama di bawah "Opsi lanjutan untuk Ubuntu". Setelah Anda membuat perubahan yang diinginkan pada baris perintah, tekan Ctrl+ xuntuk mem-boot. Setiap perubahan yang Anda lakukan di sini hanya untuk boot ini, mereka tidak disimpan ke disk.
  • Beberapa opsi berguna pada linuxbaris perintah:
    • quiet nosplashmenyembunyikan hampir semua pesan booting. Hapus mereka untuk mendapatkan pesan di konsol saat boot, yang perlu memiliki peluang untuk mendiagnosis masalah.
    • recoverymemberi Anda shell root dengan hampir tanpa layanan. Anda harus mengetahui kata sandi root. Entri menu "mode pemulihan" menggunakan ini.
    • init=/bin/shmemberi Anda shell root tanpa layanan sama sekali. Untuk melanjutkan boot normal, jalankan exec init. Anda dapat melewati opsi systemd pada titik ini, misalnya exec init --unit=basic.targetuntuk memulai init dan beberapa layanan (perhatikan bahwa ini tidak memulai cara untuk masuk, jadi Anda sebaiknya menjalankan shell di konsol lain). Perhatikan bahwa sistem file root di-mount hanya-baca; jalankan mount -o remount,rw /untuk dapat menulis untuk itu.
    • systemd.unit=basic.targetmemulai serangkaian layanan yang sangat mendasar. Perhatikan bahwa ini tidak termasuk cara untuk masuk! Anda bisa menjadikan ini sebagai default dengan menjalankan systemctl set-default basic.targetprompt root. Untuk mengembalikan target default asli, jalankan systemctl set-default graphical.target(atau systemctl set-default multi-user.targetuntuk server tanpa GUI).
    • systemd.debug-shellmemulai shell root pada tty9. Anda dapat mengaktifkan ini untuk setiap boot dengan menjalankan systemctl enable debug-shellprompt root. Jangan lupa untuk menonaktifkan ini setelah Anda menyelesaikan masalah dengan systemctl disable debug-shell. Tekan Alt+ F9untuk beralih ke tty9.
    • Lihat juga tips Fedora systemd , kiat masalah boot Arch Linux .
Gilles 'SANGAT berhenti menjadi jahat'
sumber

Jawaban:

71

Masalah

Ternyata masalah saya adalah masalah yang diketahui antara mikrokode Intel terbaru pada (beberapa?) Skylake CPU dan kernel Linux baru-baru ini, yang terutama dipicu oleh sssd . Lihat bug Ubuntu # 1759920 “intel-microcode 3.20180312.0 menyebabkan penguncian pada layar login (w / linux-image-4.13.0-37-generic)” , dan juga sejumlah bug lain yang ternyata memiliki masalah yang sama , seperti bug Ubuntu # 1746806 "sssd tampaknya crash instance AWS c5 dan m5, menyebabkan 100% CPU" dan bug Ubuntu # 1746418 "Sistem membeku ketika memulai Xorg setelah menginstal linux-image-4.13.0-32-generic" . Anda mungkin menemukan bug ini jika:

  • Anda memiliki CPU Intel yang sangat baru. Sejauh yang saya tahu, bug ini hanya muncul pada CPU Skylake .
  • Anda memiliki paket intel-mikrokode yang diinstal. Mengembalikan ke kernel yang lebih awal dan teruji tidak berhasil karena saya hanya menjalankan kernel itu dengan mikrokode sebelumnya.
  • Komputer Anda terhubung ke jaringan perusahaan (biasanya LDAP atau Direktori Aktif) untuk otentikasi pengguna. Meskipun ada cara lain untuk memicu bug, menjalankan sssd tampaknya menjadi penyebab paling umum. Ada juga laporan tentang Xorg yang mogok .

Bug ini disebabkan oleh mitigasi untuk masalah keamanan Specter yang diterbitkan pada Januari 2018. Ada ketidakcocokan antara beberapa kode kernel dan beberapa mikrokode prosesor yang menyebabkan penguncian dalam keadaan tertentu.

Cara memperbaiki

  1. Jika Anda tidak dapat melakukan boot secara normal, Anda harus mengedit baris perintah kernel pada prompt Grub. Lihat pertanyaan untuk penjelasan dan kemungkinan cara untuk mendapatkan shell root.
  2. Solusi untuk bug khusus ini adalah menambahkan noibpbparameter ke baris perintah kernel ( 1746418/14 , 1759920/56 ). Ini akan membuat Anda bisa boot dengan normal dan melakukan beberapa perbaikan.
    Ini menonaktifkan mitigasi kerentanan yang menyebabkan masalah, yang berarti bahwa komputer Anda sekarang rentan terhadap beberapa serangan. Itu adalah serangan lokal, yaitu penyerang perlu menjalankan kode pada mesin Anda, tetapi serangan ini mungkin berpotensi dilakukan misalnya melalui JavaScript di browser web.
    Jika Anda tidak memiliki cara lain, Anda dapat membuat ini permanen dengan menambahkan noibpbke baris perintah kernel sampai Anda bisa mendapatkan kernel yang diperbaiki.
  3. Di Ubuntu, perbaikannya diharapkan pada minggu 23 April 2018 , yang kemungkinan adalah kernel 4.4.0-117 dan 4.13.0-39. Sementara itu, Tyler Hicks telah menerbitkan kernel uji untuk 4.4 dan 4.13 .

Bagaimana saya mendiagnosis masalah ini

Saya mencoba beberapa hal (lihat pertanyaan) dan memastikan bahwa bug itu dipicu di suatu tempat antara mencapai basic.targetdan mencapai multi-user.target. Jadi saya menetapkan target systemd default ke basic.target( systemctl set-default basic.target) dan mengaktifkan debug-shelllayanan ( systemctl enable debug-shell) untuk mendapatkan shell root.

Saya berlari systemctl list-dependencies multi-user.targetdan secara manual memulai dependensi yang tercantum satu per satu. Ini tidak memicu crash.

Tidak semua layanan dikelola langsung oleh systemd . Beberapa dikelola sebagai Upstart layanan dan beberapa dikelola sebagai script SysVinit . Script shell di bawah ini menjalankan semuanya. Catatan: Saya hanya mengujinya satu kali, dan jatuh karena desain.

#!/bin/sh
wants=$(systemctl show -p Wants multi-user.target | sed 's/^Wants=//' | tr ' ' '\n' | sort)
log=/var/tmp/multi-user-steps-$(date +%Y%m%d-%H%M%S)

log () {
  echo "$* ..." | tee -a "$log"
  sync
  "$@"
  ret=$?
  echo "$* -> $ret" | tee -a "$log"
  sync
  return $ret
}

# systemd services
for service in $wants; do
  log systemctl start $service
  sleep 2
done

# upstart services
for conf in /etc/init/*.conf; do
  service=${conf##*/}; service=${service%.conf}
  log service ${service} start
  sleep 2
done

# sysvinit services
for service in /etc/rc3.d/S*; do
  log ${service} start
  sleep 2
done

Komputer saya mogok setelah mulai sssd. Dari sana, pencarian web pada "sssd linux kernel hang" membawa saya ke https://bugs.launchpad.net/cloud-images/+bug/1746806 dan ke diagnosis dan solusi.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Saya bertemu dengan yang ini juga. Saya menghapus paket intel-mikrokode dan memasukkannya ke dalam daftar hitam agar tidak diinstal ulang. Kode mikro yang menyebabkan masalah tidak ditambahkan secara permanen ke CPU. Itu dimuat ulang setiap waktu. Jadi tidak memuatnya juga akan bertindak sebagai solusi. Noipbp tidak diperlukan dalam kasus itu dan Anda masih akan mendapatkan mitigasinya. Dalam kasus saya suatu keharusan karena sistem ini adalah sebagian besar waktu yang langsung dihadapi internet tanpa perlindungan tambahan dari server proxy perusahaan.
Tonny
3
@Tonny Microcode memperbaiki bug lain, seperti ini , serta masalah yang tidak diungkapkan oleh Intel. Walaupun ini memang sebuah solusi, saya merasa tidak nyaman untuk tidak menerapkan pembaruan mikrokode - kecuali bahwa Spectre / Meltdown tampaknya telah sedikit keluar. Saya mengusulkan noipbpsebagian besar sebagai cara untuk boot ke sistem yang mempengaruhi. Saya pikir perbaikan terbaik di sini adalah meng-upgrade kernel.
Gilles 'SO- stop being evil'
Saya tahu dan saya setuju. Tetapi kernel baru belum ada di sini dan untuk saat ini saya lebih suka sistem kerja dengan sebagian besar mitigasi (kecuali mikrokode) daripada sistem dengan mikrokode, tetapi tidak ada mitigasi perangkat lunak (yang mencakup lebih dari mikrokode) sama sekali. Mengenai pembaruan mikrokode: Untuk Skylakes baru ini, sepertinya perbaikan Spectre / Meltdown adalah satu-satunya pembaruan mikrokode sejauh ini sehingga kami sepertinya tidak akan kehilangan banyak tanpa mereka. Untuk CPU yang lebih tua itu masalah lain. Ada banyak errata CPU yang diperbaiki dengan pembaruan mikrokode. Dan aku benar-benar enggan pergi tanpa itu.
Tonny