Neden kullanıcı alanını hiç bozmamak için bir Linux çekirdek politikası var?


38

Bu konuda Linux Çekirdek Posta Listesindeki görgü kuralları bağlamında düşünmeye başladım. Dünyanın en iyi bilinen ve tartışmalı olarak en başarılı ve önemli ücretsiz yazılım projesi olarak Linux çekirdeği çok fazla baskı alıyor. Ve proje kurucusu ve lideri Linus Torvalds, burada açıkça bir tanıtım gerektirmiyor.

Linus ara sıra LKML'deki alevleriyle ilgili çekişmeleri de çeker. Bu alevler sık ​​sık, kendi kabulleriyle, kullanıcı alanını kırmakla ilgilidir. Bu beni soruma getiriyor.

Kullanıcı alanını kırmanın neden bu kadar kötü bir şey olduğu konusunda tarihsel bir bakış açısına sahip olabilir miyim? Anladığım kadarıyla, kullanıcı alanını kırmak, uygulama düzeyinde düzeltmeler gerektirecek, fakat çekirdek kodunu iyileştirirse bu kötü bir şey mi?

Anladığım kadarıyla Linus'un belirttiği politika, kullanıcı alanını kırmamak kod kalitesi de dahil olmak üzere her şeyi trump etmek. Bu neden bu kadar önemli ve böyle bir politikanın artıları ve eksileri nelerdir?

(Sürekli olarak uygulanan böyle bir politikanın bazı olumsuzlukları vardır, çünkü Linus ara sıra LKML'deki en üst düzey teğmenleriyle tam olarak bu konuda “anlaşmazlıklar” yaşadı.


1
Giriş bölümünde Linus'un adını yanlış yazdınız.
Ismael Miguel,

Kesin olarak ben değildim, ama şimdi oy vermeyi unuttum ve oy vermeyi unuttum.
Ismael Miguel,

Yanıtlar:


38

Sebep tarihsel değil, pratik olandır. Linux çekirdeğinin üzerinde çalışan birçok program var; Bir çekirdek arayüzü bu programları kırarsa, o zaman herkesin bu programları yükseltmesi gerekir.

Şimdi, çoğu programın aslında doğrudan çekirdek arayüzlerine ( sistem çağrıları ) değil, yalnızca C standart kütüphanesinin ( sistem çağrıları etrafındaki C sarmalayıcıları ) arayüzlerine bağlı olmadığı doğrudur . Oh, ama hangi standart kütüphane? Glibc? uClibc? Dietlibc? Biyonik? Musl? vb.

Ancak, işletim sistemine özgü hizmetleri uygulayan ve standart kütüphane tarafından ortaya çıkmayan çekirdek arayüzlerine dayanan birçok program vardır. (Linux'ta bunların çoğu /procve aracılığıyla sunulur /sys.)

Ve sonra statik olarak derlenmiş ikili dosyalar var. Bir çekirdek yükseltme bunlardan birini kırarsa, tek çözüm onları yeniden derlemek olacaktır. Kaynağa sahipseniz: Linux da tescilli yazılımı destekler.

Kaynak mevcut olsa bile, hepsini toplamak bir acı olabilir. Özellikle donanımınızla ilgili bir hatayı düzeltmek için çekirdeğinizi yükseltirken. İnsanlar genellikle donanım desteğine ihtiyaç duydukları için çekirdeğini sistemlerinden bağımsız olarak yükseltirler. In Linus Torvalds sözleriyle :

Kullanıcı programlarını kırmak kabul edilemez. (…) İnsanların yıllarca eski ikilileri kullandıklarını ve yeni bir sürüm çıkarmanın bunu atmanız anlamına gelmediğini biliyoruz. Bize güvenebilirsin.

O da açıklıyor bir nedeni, sadece işe bazı yeni çekirdek almak için başka bir program yükseltmek zorunda değildir olurdum bu güçlü kural önlemek bağımlılık cehenneme yapmak değil, aynı zamanda bir başka programı yükseltmek zorunda olduğunu ve başka ve başka , çünkü her şey, her şeyin belirli bir sürümüne bağlıdır.

İyi tanımlanmış bir tek yönlü bağımlılığa sahip olmak biraz sorun değil. Üzgün, ama bazen kaçınılmaz. (…) Tamam değil, iki yönlü bir bağımlılığa sahip olmaktır. Eğer kullanıcı alanı HAL kodu yeni bir çekirdeğe bağlıysa, sorun yok, ancak kullanıcıların "haftanın çekirdeği" olacağını ummamalarına rağmen daha "son birkaç ayın çekirdeği" olacağından şüpheleniyorum.

Fakat İKİ YOL bağımlılığınız varsa, mahvolursunuz. Bu, kilit adımda yükseltme yapmanız gerektiği ve bu KABUL EDİLEMEZ demek anlamına gelir. Kullanıcı için korkunç, ama daha da önemlisi, geliştiriciler için korkunç, çünkü "bir hata oldu" diyemeyeceğiniz anlamına gelir ve bunu bisection veya benzeri bir şekilde daraltmaya çalışmak gibi şeyler yaparsınız.

Kullanıcı alanında, bu karşılıklı bağımlılıklar genellikle farklı kütüphane sürümleri tutularak çözülür; ama sadece bir çekirdeği çalıştırıyorsunuz, bu yüzden insanların onunla yapmak isteyebilecekleri her şeyi desteklemek zorunda.

Resmen ,

[kararlı olarak bildirilen sistem çağrıları] için geriye dönük uyumluluk en az 2 yıl garantilidir.

Uygulamada olsa,

Çoğu arayüzün (sistemler gibi) asla değişmemesi ve her zaman erişilebilir olması beklenir.

Daha sık değişiklik yapan şey, in /sys. ( /procdiğer taraftan, tanıtımı /sysdonanımla ilgili olmayan servisler için ayrıldığından beri , hemen hemen hiçbir zaman uyumsuz yollardan kopmaz.)

Özetle,

kullanıcı alanını kırmak, uygulama düzeyinde düzeltmeler gerektirecektir

ve bu kötü, çünkü insanların sistemlerinin geri kalanından bağımsız olarak yükseltme yapmak isteyen tek bir çekirdek var, ancak karmaşık karşılıklı bağımlılıklara sahip birçok uygulama var. Milyonlarca farklı kurulumda binlerce uygulamayı güncel tutmak için çekirdeği sabit tutmak daha kolaydır.


1
Cevap için teşekkür ederim. Öyleyse, kararlı olarak bildirilen arayüzler POSIX sistem çağrılarının bir üst kümesidir? Tarih hakkındaki sorum, bu uygulamanın nasıl geliştiğidir. Muhtemelen Linux çekirdeğinin orijinal versiyonları, en azından başlangıçta, kullanıcı alanı kırılmasından endişe duymuyordu.
Faheem Mitha

3
@FaheemMitha Evet, 1991'den beri yaptılar . Linus'un yaklaşımının geliştiğini sanmıyorum, her zaman “normal uygulamaların değişmediği arayüzler, çekirdek değişikliklerine çok nadiren bağlı olan yazılımlar için arayüzler” oldu.
Gilles 'SO- kötü olmaktan vazgeç'

24

Bağımlı herhangi bir sistemde temel olarak iki seçenek vardır. Soyutlama ve entegrasyon. (Ben bilerek teknik terimler kullanmıyorum). Soyutlama ile, bir API’yi aradığınızda, API’nin arkasındaki kod değişse de sonucun daima aynı olacağını söylersiniz. Örneğin, aradığımızda fs.open()ağ sürücüsü, SSD veya sabit disk olup olmadığına aldırmıyoruz, her zaman birlikte yapabileceğimiz açık bir dosya tanıtıcısı alırız. "Bütünleşme" ile amaç, değişse bile bir şeyi yapmanın "en iyi" yolunu sağlamaktır. Örneğin, bir dosyayı açmak, bir ağ paylaşımı için diskteki bir dosyadan farklı olabilir. Her iki yol da modern Linux masaüstünde oldukça yaygın olarak kullanılmaktadır.

Geliştiriciler açısından "herhangi bir sürümle çalışır" veya "belirli bir sürümle çalışır" meselesidir. Buna güzel bir örnek OpenGL'dir. Çoğu oyun belirli bir OpenGL sürümü ile çalışmak üzere ayarlanmıştır. Kaynaktan derleyip derlemeniz önemli değil. Oyun OpenGL 1.1 kullanacak şekilde yazılmışsa ve oyunu 3.x'de çalıştırmaya çalışıyorsanız, iyi vakit geçirmeyeceksiniz. Spektrumun diğer ucunda, bazı aramaların ne olursa olsun çalışması bekleniyor. Örneğin, fs.open()hangi çekirdeğin üzerinde olduğum umrumda değil. Sadece bir dosya tanımlayıcısı istiyorum.

Her yönden fayda var. Entegrasyon geriye dönük uyumluluk pahasına "daha yeni" özellikler sunar. Soyutlama, "daha yeni" aramalara göre stabilite sağlarken. Her ne kadar önemli olduğunu belirtmek önemli olsa da, bir olasılık meselesi değil.

Toplumsal bir bakış açısından, gerçekten çok iyi bir neden olmadan, soyutlama karmaşık bir sistemde her zaman daha iyidir. Örneğin, fs.open()çekirdek sürümüne bağlı olarak farklı çalışıp çalışmadığını düşünün . O zaman basit bir dosya sistemi etkileşim kütüphanesinin birkaç yüz farklı "açık dosya" yöntemini (veya muhtemelen engellemeyi) sürdürmesi gerekir. Yeni bir çekirdek sürümü çıktığında "yükseltme" yapamazsınız, kullandığınız her bir yazılımı test etmek zorunda kalırsınız. Çekirdek 6.2.2 (sahte) sadece metin editörünüzü kırabilir.

Bazı gerçek dünya örnekleri için OSX, Kullanıcı Alanını kırma umrunda değil. Daha çok "soyutlama" yerine "entegrasyon" u hedefliyorlar. Her büyük işletim sistemi güncellemesinde de işler bozuluyor. Bu, bir yolun diğerinden daha iyi olduğunu söylemez. Bu bir seçim ve tasarım kararı.

En önemlisi, Linux eko sistemi, insanların ya da grupların boş zamanlarında projede çalıştıkları ya da aracın faydalı olması nedeniyle harika açık kaynak projeleriyle doludur. Bunu akılda tutarak, ikinci eğlenmeyi bırakıp PIA olmaya başlar, bu geliştiriciler başka bir yere gider.

Mesela ben bir yama gönderdim BuildNotify.py. Fedakar olduğum için değil, aracı kullandığım için ve bir özellik istediğim için değil. Kolaydı, işte burada bir yamanın olması. Karmaşık veya hantal olsaydı, kullanmazdım BuildNotify.pyve başka bir şey bulurdum. Ne zaman bir çekirdek güncellemesi ortaya çıkarsa, metin düzenleyicim bozulursa, farklı bir işletim sistemi kullanırdım. Topluma katkılarım (ancak küçük) devam etmeyecek veya olmayacaktı.

Böylece, tasarım kararı soyut sistem çağrıları için verildi, böylece yaptığım fs.open()zaman işe yarıyor. Bu popülerlik kazandıktan fs.opensonra uzun süre korumak demektir fs.open2().

Tarihsel olarak, bu genel POSIX sistemlerinin amacıdır. “Burada bir dizi çağrı ve beklenen geri dönüş değerleri var, ortadakileri anlıyorsunuz.” Tekrar taşınabilirlik nedeniyle. Linus neden bu metodolojiyi kullanmayı seçti, beyninin içindesin ve nedenini tam olarak bilmesini istemelisin. Ancak ben olsaydım, karmaşık bir sistemde entegrasyon yerine soyutlamayı seçerdim.


1
Kullanıcı alanına yönelik API, 'sistem çağrısı' API'si iyi tanımlanmıştır (özellikle POSIX altkümesi) ve kararlıdır, çünkü herhangi bir bölümünü kaldırmak insanların kurmuş olabileceği yazılımları kıracaktır. Sahip olmadığı şey kararlı bir sürücü API'si.
pjc50

4
@FaheemMitha, tersi bu. Çekirdek geliştiricileri, bir sonraki sürümden önce tüm çekirdek sürücülerini düzelttikleri sürece, istedikleri zaman sürücü API'sini kırabilirler. Kullanıcı alanı API'sini kırıyor, hatta Linus'tan epik reaksiyonlar üreten, kullanıcı alanını kırabilecek API dışı şeyler yapıyor.
Mark

4
Örneğin, birileri bazı durumlarda ioctl () işlevinden farklı bir hata kodu döndürerek değiştirmeye karar verirse: lkml.org/lkml/2012/12/23/75 (sorumlu geliştiriciye küfür ve kişisel saldırılar içerir). Bu yama, PulseAudio'yu ve dolayısıyla GNOME sistemlerindeki tüm sesleri bozacağı için reddedildi.
pjc50

1
@FaheemMitha, temel olarak, def add (a, b); a + b döndür; son --- def add (a, b); c = a + b; c dönüşü; son --- def add (a, b); c = a + b +10; dönüş c - 10; son - tüm "aynı" eklenti uygulamasıdır. Onu bu kadar üzen şey, insanların def eklemesini yaptığı zaman (a, b); dönüş (a + b) * -1; Sonunda, özünde, "iç" şeylerin çekirdeğe göre değişmesi tamamdır. Tanımlı ve "genel" bir API çağrısına döndürülenleri değiştirmek değildir. "Private" ve "public" olmak üzere iki tür API çağrısı vardır. Genel API çağrılarının hiçbir sebep olmadan asla değişmemesi gerektiğini düşünüyor.
coteyr

3
Kod dışı bir örnek; Dükkana girersin, 87 Oktan gazı alırsın. Siz, tüketici olarak, gazın nereden geldiğini veya nasıl işlendiğini "umursamıyorsunuz". Sadece benzin almanı önemsiyorsun Gaz farklı bir arıtma işleminden geçmişse, umursamıyorsunuz. Rafinasyon işleminin değişebileceğinden emin olun. Farklı yağ kaynakları bile var. Ama umursadığın şey 87 Oktan gazı almak. Bu nedenle konumu, kaynakları değiştir, rafinerileri değiştir, her şeyi değiştir, pompadan çıkanlar 87 Oktan gazı olduğu sürece. Tüm "perde arkasında" şeyler önemli değil. 87 Oktan gazı olduğu sürece.
coteyr

8

Bu bir tasarım kararı ve seçim. Linus, oldukça nadir ve istisnai (örn. Güvenlikle ilgili) durumlar haricinde, çekirdekteki değişikliklerin uygulamalarını bozmayacağına dair kullanıcı alanı geliştiricilerine garanti vermek istiyor.

Artıları, kullanıcı alanı geliştiricilerin kodlarını keyfi ve kaprisli nedenlerle aniden yeni çekirdekleri kırarak bulamamalarıdır.

Dezavantajları, çekirdeğin eski kodu ve eski sistem çağrılarını sonsuza dek (veya en azından kullanım tarihlerini çok geçmeden) tutması gerektiğidir.


Cevabınız için teşekkür ederim. Bu kararın nasıl geliştiğinin tarihinin farkında mısınız? Biraz farklı bir bakış açısı alan projelerin farkındayım. Örneğin, Mercurial projesi sabit bir API'ye sahip değildir ve ona dayanan kodu kırabilir ve kırabilir.
Faheem Mitha

Hayır, üzgünüm, nasıl olduğunu hatırlayamıyorum. Linus veya LKML'ye e-posta gönderebilir ve ona sorabilirsiniz.
Cas

2
Mercurial bir işletim sistemi değil. Bir işletim sisteminin tüm amacı, üstünde başka bir yazılımın çalışmasını sağlamak ve diğer yazılımların çok popüler olmamasını sağlamaktır. Buna kıyasla, Windows çok uzun bir süredir geriye dönük uyumluluk da sağlamıştır; 16-bit Windows kodu sadece son zamanlarda kullanılmıyordu.
pjc50

@ pjc50 Orada, Mercurial bakılmaksızın bir OS değil, doğrudur olduğu diğer yazılım sadece komut dosyaları bağımlı olduğunu bile. Ve potansiyel olarak değişiklikler tarafından kırılabilir.
Faheem Mitha
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.