Bilgisayarım birşeyleri diske nasıl depolar?

Unix'teki bir sabit diske baktığınız zaman, dosya ve dizin isimlerinin bir ağacını görürsünüz. Normalde, daha derinine bakma ihtiyacı duymayacaksınız, ancak bir disk arızası olduğunda ve dosyaları kurtarmaya ihtiyaç duyduğunuzda, aşağıda neler olup bittiğini bilmek faydalı olabilir. Ne yazık ki disk organizasyonunu, dosya seviyesinden yukarıdan aşağı doğru açıklamanın bir yolu yoktur. Bu yüzden bu durumu donanımdan yukarıya doğru açıklamak zorunda kalacağım.

Düşük seviyeli disk ve dosya yapısı

Diskinizin veriyi depolayan yüzey alanı, dart tahtasına benzer şekilde, pasta dilimleri şeklindeki sektörlerden oluşan dairesel izlere bölünmüştür. İzlerin dış tarafının, disk merkezindeki mile yakın olanlardan daha fazla alana sahip olmasından dolayı, dıştaki izler içerideki izlerden daha fazla sektör dilimlerine sahiptir. Herbir sektör (ya da disk bloğu), modern Unixlerde genellikle 1 ikili K (1024 8 bitlik kelime) olan, aynı boyutlara sahiptir. Her disk bloğu, tekil bir adrese ve disk blok sayısına sahiptir.

Unix, diski disk bölümlerine ayırır. Her bölüm, ya dosya sistemi ya da takas alanı olan, diğer bölümlerden ayrı olarak kullanılan devamlı bir blok zinciridir. Parçalamanın için asıl nedenleri; çok daha yavaş ve hata yapabilir disklerin dünyasındaki arızaları telafi etmek zorunda olmasıdır. Bunlar aralasındaki sınırlar, diskinizdeki herhangi bir kötü nokta tarafından erişilemez duruma getirilen veya bozulan muhtemel disk bölümlerinizi azaltır. Bu günlerde, parçalamanın salt okunur tanımlanabilecek (kritik sistem dosyalarını değiştiriken çıkan davetsiz misafirlere karşı korumak) veya burada ele almayacağımız çeşitli nedenlerden dolayı ağ üzerinde paylaştırılabilecek olması daha önemlidir. Diskteki en düşük numaralı bölüm çoğu zaman, önyükleme için çekirdeği yerleştirebileceğiniz önyükleme bölümü gibi davranılır.

Herbir bölüm ya takas alanı (sanal belleği gerçekleştirmede kullanılan) ya da dosyaları tutmada kullanılan dosya sistemidir. Takas alanı parçalarına, yalnızca doğrusal bir blok dizisiymiş gibi davranılır. Diğer bir taraftan, dosya sistemleri, dosya isimlerini disk bloklarına eşlemek için bir yola ihtiyaç duyar. Dosyaların büyümesinden, küçülmesinden ve zamanla değişmesinden dolayı, bir dosyanın veri blokları doğrusal bir dizi olmayacaktır, ancak kendi bölümünün tümüne dağıtılmış olabilir (işletim sisteminin ihtiyaç duyup bulabileceği boş bir veri bloğu her nerede ise). Bu dağıtmanın etkisi parçalama olarak adlandırılır.

Dosya isimleri ve dizinleri

Her dosya sisteminde, isimlerin bloklara eşlenmesi, i-node denilen bir yapı ile yürütülür. Her dosya sisteminin (en düşük olanları ev idaresi ve burda açıklamayacağımız amaçları sınıflandırmak için kullanılır) dibinin (en düşük numaralı bloklar) yanında bu nesnelerin bir havuzu vardır. Herbir i-node bir dosyayı tanımlar. Dosya veri blokları (dizinleri içeren) i-node'ların üzerinde bulunur (yüksek numaralı bloklarda).

Her i-node, tanımladığı dosyadaki disk blok sayılarınının bir listesini içerir. (Aslında bu yarı gerçektir, sadece küçük dosyalar için doğrudur, ancak burada diğer detaylar önemli değildir.) i-node'un dosyanın ismini içermediğine dikkat edelim.

Dosyaların isimleri dizin yapılarında bulunur. Bir dizin yapısı, yalnızca isimleri i-node numaralarına eşler. Bunun nedeni; Unix'te, bir dosya birden fazla gerçek isme (ya da sıkı bağa) sahip olabilir. Onlar sadece, aynı i-node'a işaret ederken oluşan çoklu dizin girdileridir.

Bağlama noktaları

En basit durumda, Unix dosya sisteminizin tamamı yalnızca bir disk bölümünde bulunur. Kimi ufak Unix sistemlerinde bu düzeni görseniz de, bu durum olağandışıdır. Daha tipik olarak, muhtemelen farklı fiziksel disklerdeki çeşitli disk bölümleri arasında yayılırlar. Bu yüzden, örneğin sisteminiz bulunduğu ufak, işletim sistemi altyapı hizmetlerinin bulunduğu biraz daha büyük ve kullanıcı ev dizinlerinin bulunduğu çok daha büyük bir bölüme sahip olabilir.

Sistem önyüklemesinden sonra doğrudan doğruya erişeceğiniz tek bölüm, (hemen hemen her zaman) önyüklemenizin yapıldığı yer olan kök bölümünüzdür. Bu bölüm, dosya sisteminizdeki öteki herşeyin bağlı bulunduğu, en üstteki düğüm olan kök dizinini tutar.

Çok bölümlü dosya sisteminizin tümünün erişilebilir olması için, sistemdeki diğer bölümlerin bu köke bağlanılması şarttır. Önyükleme işleminin yarısında, Unixiniz bu köksüz bölümleri erişilebilir yapacaktır. Her bir bölümü, kök bölümünün üzerindeki bir dizine bağlayacaktır.

Örneğin; /usr diye bir Unix dizinine sahipseniz, bu dizin muhtemelen Unix'inizle kurulmuş ancak, başlangıçtaki önyükleme sırasında gerekli görülmemiş, birçok programı içeren bir bölüme ait bir bağlama noktasıdır.

Bir dosya nasıl yoklanır?

Artık dosya sistemine yukarıdan aşağı doğru bakabiliriz. Bir dosyayı (mesela /home/esr/WWW/ldp/fundamentals.xml ) açtığınız zaman şunlar olur:

Çekirdeğiniz, Unix dosya sisteminizin kökünde çalışmaya başlar (kök bölümünde). 'home' adında bir dizini arar. Genellikle 'home', başka bir yerdeki daha büyük bir kullanıcı bölümüne ait bir bağlama noktasıdır. Böylece çekirdek oraya gider. Kullanıcı bölümünün en üst seviyedeki dizin yapısında, 'esr' adında bir girdiye bakar ve bir i-node numarası çıkarır. Çekirdek bu i-node'a gider, ilişkili dosya veri bloklarının bir dizin yapısında olduğunu farzeder ve 'WWW' a bakar. Bu i-node'u çıkararak, uygun olan altdizine gidecek ve 'ldp'ye bakacaktır. Bu ise çekirdeği, başka bir dizin i-node'una kadar götürecektir. Bu i-node'a giriş yaparak, 'fundamentals.xml' için bir i-node numarası bulacaktır. Bu i-node bir dizin değildir ancak, onun yerine dosya ile ilişkili olan disk bloklarının bir listesini tutar.

Dosya sahipliği, izinler ve güvenlik

Programları, üstüne basmamaları gereken kazara veya kötü niyetli verilerden korumak için, Unix izin özelliklerine sahiptir. Bunlar aslında, Unix'in çoğunlukla pahalı paylaşılmış minibilgisayarlarda çalıştığı günlerde, aynı makinelerdeki çoklu kullanıcıları birbirlerinden koruyarak, zaman paylaşımını desteklemek amacıyla tasarlanmıştır.

Dosya izinlerini anlamak için, Giriş yaptığınız zaman ne olur ? bölümündeki kullanıcıların ve grupların açıklamalarına yeniden bakmanız gerekir. Her dosyanın bir kullanıcısı ve grup sahibi olur. Bunlar, başlangıçta bu dosya oluşturucularınındır. chown(1) ve chgrp(1) programları ile değiştirilebilir.

Bir dosya ile ilişkilendirilebilecek temel izinler 'okuma' (dosyadan veri okuma izni), 'yazma' (dosyada değişiklik yapabilme izni) ve 'çalıştırma' (dosyayı bir program olarak çalıştırabilme izni) dır. Her dosya 3 izin kümesine sahiptir; birisi kullanıcı sahibi, birisi sahiplik grubundaki herhangi bir kullanıcı ve birisi de kalan tüm kullanıcılar içindir. Giriş yaptığınız zaman sahip olduğunuz haklar; sadece kullanıcı ID'niz ile eşleşen izin bitleri, yer aldığınız gruplardan birisi ya da diğerleri için erişebilebilir olan dosyalara okuma, yazma ve çalıştırma yapabilmektir.

Bunların birbirini nasıl etkileyebileceğini ve Unix'in bunları nasıl görüntüleyeceğine, varsayılan bir Unix sistemindeki dosya listelemesine bakarak görelim.

snark:~$ ls -l notes
-rw-r--r--   1 esr      users         2993 Jun 17 11:00 notes

Bu, sıradan bir veri dosyasıdır. Listeleme bize şunu gösterir ki: bu dosyanın sahibi 'esr' kullanıcısıdır ve sahip grup olan 'users' ile oluşturulmuştur. Muhtemelen bulunduğumuz makine, her sıradan dosyayı öntanımlı olarak bu gruba dahil eder; zaman paylaşımlı makinelerde yaygın olarak görülen diğer gruplar ise "staff", "admin" veya "wheel" grubudur (açıktır ki tek kullanıcılı iş istasyonları ve PC'lerde gruplar çok önemli değildir).

'-rw-r--r--' karakte dizisi, dosya için izin bitlerini temsil eder. En baştaki çizgi, dizin bitinin yeridir; eğer dosya bir dizin ise 'd', sembolik bir bağlantı ise 'l' göstermelidir. Bundan sonraki ilk üç alan kullanıcı izinleri, ikinci üçlü grup izinleri ve kalan üçlü ise diğerlerinin (sıklıkla 'diğer' izinleri denir) izinleridir. Bu dosyada, sahip kulanıcı 'esr' okuma veya yazma, diğer 'kullanıcılar' grubundakiler okuma ve 'diğer'deki herkes okuma yapabilir. Bunlar, sıradan bir dosya için tipik bir izin kümesidir.

Şimdi çok değişik izinlere sahip bir dosyaya göz atalım. Bu dosya, GNU C derleyicisi olan GCC'dir.

snark:~$ ls -l /usr/bin/gcc
-rwxr-xr-x   3 root     bin         64796 Mar 21 16:41 /usr/bin/gcc

Bu dosya, 'root' adında bir kullanıcıya ve 'bin' adındaki bir gruba aittir; yalnızca root tarafından yazılabilir (değiştirilebilir), ancak herhangi biri tarafından okunabilir veya çalıştırılabilir. Bu, kurulu olan sistem komutu için tipik bir sahipliği ve izin kümesidir. 'bin' grubu, bazı Unixlerdeki sistem komutları (ismi tarihi bir kalıntıdır, 'binary' nin kısaltmasıdır) ile birlikte bulunan gruplarda bulunur. Bunun yerine Unixiniz 'root' grubunu kullanabilir ('root' kullanıcısı tamamen aynı değildir!).

'root' kullanıcısı, sayısal kullanıcı ID 0'ın, özel, tüm haklarını geçersiz kılabilecek ayrıcalıklı hesabının klasikleşmiş ismidir. Root erişimi kullanışlıdır ancak tehlikelidir; root olarak giriş yaptığınızda yapılan hatalı bir yazım, aynı komutun sıradan bir kullanıcı hesabı tarafından çalıştırıldığında dokunamayacağı kritik sistem dosyalarını tahrip edebilir.

Root hesabının oldukça güçlü olmasından dolayı, ona yapılacak erişim çok dikkatlice korunmalıdır. Root parolanız, sisteminizdeki güvenlik bilgisinin en kritik tek parçasıdır ve sizden sonra gelen kırıcıların ve davetisiz misafirlerin ele geçirmeye çalışacağı şeydir.

Parolalar hakkında : Parolaları not etmeyiniz ve kız arkadaşınızın, erkek arkadaşınızın ya da eşinizin ismi gibi kolaylıkla tahmin edilebilen parolalar seçmeyiniz. Bu, kırıcılara sonuna kadar yardımcı olmayacak kadar, şaşılacak derecede genel olan kötü bir pratiktir. Genelde, sözlükten hiçbir kelime seçmeyiniz; kırıcıların, genel seçimlerden oluşan kelime listesini çalıştırarak olası parolaları araştırdığı, sözlük denilen programlar vardır. Bir kelimenin, rakamın ve başka bir kelimeden oluşan bir kelime kombinasyonunun seçilmesi iyi bir tekniktir. Örneğin: ‘shark6cider’ ya da ‘jump3joy’. Bu seçimler, bir sözlük kırıcısı için arama uzayını oldukça genişletecektir. Kırıcıların bu belgeyi okuduktan sonra bunları sözlüklerine ekleyebileceklerinden dolayı, bu örnekleri kullanmayınız.

Şimdi de üçüncü duruma göz atalım:

snark:~$ ls -ld ~
drwxr-xr-x  89 esr      users          9216 Jun 27 11:29 /home2/esr
snark:~$ 

Bu dosya bir dizindir (ilk izinler alanındaki 'd' dikkat ediniz). Şunu görüyoruz ki: bu dizin sadece esr tarafından yazılabilir, ancak herkes tarafından çalıştırılabilir.

Okuma izni, dizini listeleme imkanınını size sunar. Bu demek oluyor ki: dizinin içerdiği dosya ve dizinlerin isimlerini görebilirsiniz. Yazma izni, dizin içerisinde dosya oluşturma veya silme imkanı sunar. Bir dizinin içinde bulunan dosya ve dizin isimlerinin bir listesini içerdiğini hatırlayacak olursanız, bu kurallar bir anlam ifade edecektir.

Bir dizindeki çalıştırma izni, o dizinin altındaki dosya ve dizinleri açmak için, bu dizini geçebileceğiniz anlamına gelir. Aslında, dizin içerisindeki i-node'lara erişim iznini verir. Bir dizinin tamamen çalıştırılmaya kapalı olması yararsız olacaktı.

Kimi zaman bir dosyanın diğerleri tarafından çalıştırılabilir olduğunu ancak okunabilir olmadığını göreceksiniz. Bu demek oluyor ki: herhangi bir kullanıcı, bunun altındaki dosya ve dizinlere erişebilir, ancak sadece isimlerini bildiği taktirde (dizin listelenemez).

Bir dizin üzerinde okuma, yazma veya çalıştırma izninizin, onun altında bulunan dosya ve dizinlerin izinlerinde bağımsız olduğunun hatırlanması önemlidir. Özellikle, bir dizine yazma izni, orada yeni dosyalar oluşturabileceğiniz veya varolan dosyaları silebileceğiniz anlamına gelir. Ancak, otomatik olarak varolan dosyalara yazma erişim iznini size vermez.

Son olarak, giriş programının kendi izinlerine göz atalım.

snark:~$ ls -l /bin/login
-rwsr-xr-x   1 root     bin         20164 Apr 17 12:57 /bin/login

Bu, bir sistem komutu için bekleyeceğimiz izinleri içerir. 's' nin, sahibi çalıştırabilir bit olması gerektiğini hariç tutunuz. Bu, 'set-user-id' veya setuid bit denilen özel iznin açık bir görünümüdür.

Normalde setuid biti, sıradan kullanıcılara root haklarını vermesi gereken programlara eklenir. Ancak kontrollü bir yolla. Çalıştırılabilir bir programda bu bite atama yapıldığı zaman, size ait olanla eşleşse de eşleşmese de, sizin adınıza program çalışırken, program dosyasının sahibinin haklarına sahip olursunuz.

Root hesabının kendisine benzer şekilde, setuid programları kullanışlıdır, fakat tehlikelidir. Root sahipliğindeki bir setuid programını bozabilen veya değiştirebilen herhangi biri, bu durumu root hakları ile bir kabuk oluşturmak için kullanabilir. Bu nedenle, çoğu Unixlerde, bir dosyanın yazma için açılması, otomatik olarak setuid bitini kapalı hale getirir. Unix güvenliğine karşı yapılan çoğu saldırılar, onları bozmak için setuid programlarındaki hataları kullanırlar. Bilinçli sistem güvenlik yöneticileri bu sebepten dolayı, bu tarz programlar hakkında ekstra olarak dikkatli davranırlar ve yenilerini kurmak konusunda isteksizdirler.

İzinler konusunda konuşurken gizlediğimiz birkaç önemli detay var; şöyle ki, bir dosya veya dizin ilk defa yaratıldığında, sahip grup ve izinleri ataması nasıl yapılır. Grup bir sorundur, çünkü kullanıcılar birden fazla grubun üyeleri olabilirler, ancak onlardan birisi (kullanıcının /etc/passwd dosyasında belirtilmiş olan) kullanıcının öntanımlı grubudur ve normalde kendi dosyaları kullanıcı tarafından oluşturulur.

Başlangıç izin bitlerinin hikayesi biraz daha karışıktır. Normalde bir program, beraber çalışmaya başlaması için, izinlerini belirleyecek şekilde dosyayı oluşturur. Ancak bunlar, kullanıcı ortamında bulunan, umask denilen bir değer tarafından değiştirilecektir. Umask, bir dosya oluştururken hangi izin bitlerinin kapalı hale getirileceğini belirler; en genel ve çoğu sistemdeki öntanımlı olan değer, diğerlerinin yazabileceği biti kapalı hale getiren -------w- ya da 002 dir.

Başlangıçtaki dizin grubu da biraz karmaşıktır. Kimi Unixlerde, yeni bir dizin, oluşturan kullanıcının öntanımlı grubunu alır (System V kuralı); diğerlerinde, onun oluşturmuş olduğu üst dizinin sahip grubunu alır (BSD kuralı). Linux da dahil kimi modern Unixlerde, dizindeki set-group-ID'nin ataması yapılarak ikinci davranış seçilebilir (chmod g+s).

Hangi durumlarda birşeyler ters gidebilir

Daha önceleri, dosya sistemlerinin narin şeyler olabileceği bir ipucu idi. Artık şunu biliyoruz ki; bir dosyaya ulaşmak istediğinizde, keyfi olarak uzun olabilen bir dizin ve i-node başvuru zincirinin üzerinde seksek oynamanız şarttır. Artık sabit diskinizin kötü noktalar oluşturduğunu varsayınız.

Eğer şanslı iseniz, yalnızca bazı dosyalara zarar verecektir. Değilseniz, bir dizin ya da i-node yapısını bozabilir ve sistem altağacınızın tümünü zindanda asılı bir halde bırakabilir. Ya da daha kötüsü, aynı disk bloğu veya i-node'da bulunan birden fazla yola işaret eden bozulmuş bir yapı ile sonuçlanır. Bu tarz bozulmalar, aslında kötü noktada bulunmayan verilere zarar verilerek yapılan, normal dosya sistemi işlemleri yoluyla dağıtılabilir.

Neyse ki bu tarz beklenmedik olay, disk donanımının daha güvenilir olduğu için, çok nadiren oluşur. Gene de bu olay, hiçbirşeyin yanlış olmadığından emin olmak için, Unixinizin periyodik bütünlük denetimi isteyeceği anlamına gelir. Modern Unixler, bağlamadan hemen önce önyükleme zamanında, her bölümde hızlı bir bütünlük denetimi yapar. Yapacakları her birkaç yeniden başlatma, birkaç dakikalık zaman alan, çok daha titiz bir denetleme işlemi yaparlar.

Eğer tüm bunlar, Unixin korkunç derecede karmaşık ve bozulmaya meyilli olduğunu gösteriyorsa, bu önyükleme zamanı denetimlerinin, gerçekten feci bir hale gelmeden önce, tipik normal problemleri yakaladığını ve düzelttiğini bilmek güven verici olabilir. Diğer işletim sistemleri, önyüklemeyi bir nebze hızlandırmasına ve elle kurtarma yapmaya kalkıştığınızda çok ciddi derecede berbat etmesine rağmen bu tür araçlara sahip değildir (ve bu, ilk kısımda bulunan, Norton Utilities'in ya da her ne ise, bir kopyasına sahip olduğunuzu farzeder).

Bugünkü Unix tasarımlarındaki eğilimlerden biri; dosya sistemi günlüklemedir. Bunlar diskteki trafiği düzenler. Böylece sistem geri geldiğinde, tutarlı durumun kurtarılabilmesi güvence altına alınmış olur. Bu durum, önyükleme zamanındaki bütünlük denetimini oldukça hızlandıracaktır.