Saya mulai memikirkan masalah ini dalam konteks etiket pada Linux Mailing list Kernel. Sebagai proyek perangkat lunak bebas yang paling dikenal dan paling sukses di dunia dan paling penting, kernel Linux mendapat banyak tekanan. Dan pendiri dan pemimpin proyek, Linus Torvalds, jelas tidak perlu diperkenalkan di sini.
Linus sesekali menarik kontroversi dengan kobaran api pada LKML. Nyala api ini sering, menurut pengakuannya sendiri, harus dilakukan dengan memecahkan ruang pengguna. Yang membawa saya ke pertanyaan saya.
Bisakah saya memiliki perspektif historis tentang mengapa memecah ruang pengguna adalah hal yang sangat buruk? Seperti yang saya pahami, memecah ruang pengguna akan membutuhkan perbaikan pada level aplikasi, tetapi apakah ini hal yang buruk, jika meningkatkan kode kernel?
Seperti yang saya pahami, kebijakan Linus menyatakan bahwa tidak melanggar ruang pengguna mengalahkan segala sesuatu yang lain, termasuk kualitas kode. Mengapa ini sangat penting, dan apa pro dan kontra dari kebijakan semacam itu?
(Jelas ada beberapa kontra terhadap kebijakan semacam itu, yang diterapkan secara konsisten, karena Linus kadang-kadang memiliki "ketidaksepakatan" dengan para letnan topnya tentang LKML tentang topik ini. Sejauh yang saya tahu, ia selalu berhasil dalam masalah ini.)
sumber
Jawaban:
Alasannya bukan alasan historis tetapi alasan praktis. Ada banyak banyak banyak program yang berjalan di atas kernel Linux; jika antarmuka kernel merusak program-program itu maka semua orang perlu memutakhirkan program-program itu.
Sekarang memang benar bahwa sebagian besar program sebenarnya tidak bergantung pada antarmuka kernel secara langsung ( panggilan sistem ), tetapi hanya pada antarmuka perpustakaan standar C ( bungkus C di sekitar panggilan sistem). Oh, tapi perpustakaan standar apa? Glibc? uClibC? Dietlibc? Bionik? Musl? dll.
Tetapi ada juga banyak program yang mengimplementasikan layanan spesifik OS dan bergantung pada antarmuka kernel yang tidak diekspos oleh pustaka standar. (Di Linux, banyak di antaranya ditawarkan melalui
/proc
dan/sys
.)Dan kemudian ada binari yang dikompilasi secara statis. Jika upgrade kernel merusak salah satunya, satu-satunya solusi adalah mengkompilasi ulang. Jika Anda memiliki sumber: Linux juga mendukung perangkat lunak berpemilik.
Bahkan ketika sumber tersedia, mengumpulkan semua itu bisa menyebalkan. Terutama ketika Anda memutakhirkan kernel Anda untuk memperbaiki bug dengan perangkat keras Anda. Orang-orang sering memutakhirkan kernel mereka secara independen dari sisa sistem mereka karena mereka memerlukan dukungan perangkat keras. Dalam kata - kata Linus Torvalds :
Dia juga menjelaskan bahwa salah satu alasan untuk membuat ini aturan yang kuat adalah untuk menghindari ketergantungan di mana Anda tidak hanya harus memutakhirkan program lain untuk mendapatkan beberapa kernel yang lebih baru untuk bekerja, tetapi juga harus memutakhirkan program lain, dan yang lain, dan yang lain , karena semuanya tergantung pada versi segalanya.
Di userspace, saling ketergantungan itu biasanya diselesaikan dengan menjaga versi perpustakaan yang berbeda di sekitar; tetapi Anda hanya bisa menjalankan satu kernel, jadi itu harus mendukung semua orang yang mungkin ingin melakukannya.
Secara resmi ,
Namun dalam praktiknya,
Apa yang lebih sering berubah adalah antarmuka yang hanya dimaksudkan untuk digunakan oleh program yang terkait dengan perangkat keras, di
/sys
. (/proc
, di sisi lain, yang sejak diperkenalkannya/sys
telah dicadangkan untuk layanan yang tidak terkait dengan perangkat keras, hampir tidak pernah rusak dengan cara yang tidak kompatibel.)Singkatnya,
dan itu buruk karena hanya ada satu kernel, yang ingin ditingkatkan orang secara terpisah dari sisa sistem mereka, tetapi ada banyak banyak aplikasi di luar sana dengan saling ketergantungan yang kompleks. Lebih mudah untuk menjaga agar kernel stabil agar ribuan aplikasi tetap mutakhir di jutaan pengaturan yang berbeda.
sumber
Dalam setiap sistem yang saling tergantung pada dasarnya ada dua pilihan. Abstraksi dan integrasi. (Saya sengaja tidak menggunakan istilah teknis). Dengan Abstraksi, Anda mengatakan bahwa ketika Anda membuat panggilan ke API itu, sementara kode di belakang API dapat berubah, hasilnya akan selalu sama. Sebagai contoh ketika kita memanggil
fs.open()
kita tidak peduli apakah itu drive jaringan, SSD atau hard drive, kita akan selalu mendapatkan deskriptor file terbuka yang dapat kita lakukan. Dengan "integrasi" tujuannya adalah untuk menyediakan cara "terbaik" untuk melakukan sesuatu, bahkan jika caranya berubah. Misalnya, membuka file mungkin berbeda untuk berbagi jaringan daripada untuk file pada disk. Kedua cara digunakan cukup luas di desktop Linux modern.Dari sudut pandang pengembang, pertanyaannya adalah "bekerja dengan versi apa pun" atau "bekerja dengan versi tertentu". Contoh yang bagus untuk hal ini adalah OpenGL. Sebagian besar game diatur untuk bekerja dengan versi OpenGL tertentu. Tidak masalah jika Anda mengkompilasi dari sumber. Jika gim ini ditulis menggunakan OpenGL 1.1 dan Anda mencoba menjalankannya pada 3.x, Anda tidak akan bersenang-senang. Di ujung lain spektrum, beberapa panggilan, diharapkan berfungsi apa pun yang terjadi. Sebagai contoh, saya ingin menelepon
fs.open()
Saya tidak ingin peduli dengan versi kernel apa saya. Saya hanya ingin deskriptor file.Ada manfaat untuk setiap cara. Integrasi menyediakan fitur "yang lebih baru" dengan biaya kompatibilitas ke belakang. Sementara abstraksi memberikan stabilitas atas panggilan "baru". Meskipun penting untuk dicatat ini masalah prioritas, bukan kemungkinan.
Dari sudut pandang komunal, tanpa alasan yang sangat bagus, abstraksi selalu lebih baik dalam sistem yang kompleks. Sebagai contoh, bayangkan jika
fs.open()
bekerja secara berbeda tergantung pada versi kernel. Kemudian pustaka interaksi sistem file sederhana perlu mempertahankan beberapa ratus metode "file terbuka" yang berbeda (atau mungkin blok). Ketika versi kernel baru keluar, Anda tidak akan dapat "meningkatkan", Anda harus menguji setiap bagian dari perangkat lunak yang Anda gunakan. Kernel 6.2.2 (palsu) dapat merusak editor teks Anda.Untuk beberapa contoh dunia nyata OSX cenderung tidak peduli tentang melanggar User Space. Mereka bertujuan untuk "integrasi" lebih dari "abstraksi" lebih sering. Dan pada setiap pembaruan OS utama, banyak hal rusak. Itu bukan untuk mengatakan satu cara lebih baik dari yang lain. Ini pilihan dan keputusan desain.
Yang paling penting, sistem ekologi Linux dipenuhi dengan proyek opensource yang luar biasa, di mana orang atau kelompok bekerja pada proyek di waktu luang mereka, atau karena alat ini berguna. Dengan pemikiran itu, yang kedua berhenti menjadi menyenangkan dan mulai menjadi PIA, para pengembang itu akan pergi ke tempat lain.
Misalnya, saya mengirim tambalan ke
BuildNotify.py
. Bukan karena saya altruistik, tetapi karena saya menggunakan alat ini, dan saya menginginkan fitur. Itu mudah, jadi di sini, punya tambalan. Jika rumit, atau rumit, saya tidak akan menggunakanBuildNotify.py
dan saya akan menemukan sesuatu yang lain. Jika setiap kali pembaruan kernel keluar, editor teks saya rusak, saya hanya akan menggunakan OS yang berbeda. Kontribusi saya kepada komunitas (sekecil apa pun) tidak akan berlanjut atau ada, dan seterusnya.Jadi, keputusan desain dibuat untuk panggilan sistem abstrak, sehingga ketika saya melakukannya
fs.open()
hanya berfungsi. Itu berarti mempertahankanfs.open
lama setelahfs.open2()
mendapatkan popularitas.Secara historis, ini adalah tujuan dari sistem POSIX secara umum. "Ini satu set panggilan dan nilai pengembalian yang diharapkan, kamu tahu tengahnya." Lagi untuk alasan portabilitas. Mengapa Linus memilih untuk menggunakan metodologi itu adalah internal otaknya, dan Anda harus memintanya untuk tahu persis mengapa. Namun jika saya, saya akan memilih abstraksi daripada integrasi pada sistem yang kompleks.
sumber
Ini keputusan dan pilihan desain. Linus ingin dapat menjamin kepada pengembang ruang-pengguna bahwa, kecuali dalam keadaan yang sangat jarang dan luar biasa (misalnya terkait keamanan), perubahan pada kernel tidak akan merusak aplikasi mereka.
Pronya adalah bahwa pengguna devs tidak akan menemukan kode mereka tiba-tiba melanggar kernel baru karena alasan sewenang-wenang dan berubah-ubah.
Kontra adalah bahwa kernel harus menyimpan kode lama dan syscalls lama dll sekitar selamanya (atau, setidaknya, lama melewati tanggal penggunaan-oleh).
sumber