Ders 19 / 22
Takma ve Kalıcı Takma
Aygıt adına yazılmış bir kalıcı takma girdisi altmış önyüklemenin yalnız on üçünde doğru dosya sistemini takıyor ve yirmi yedisinde sessizce yanlışını takıyor; erişim zamanını güncellemeyen bir takma seçeneği temizlik görevine 787 dosyayı yanlışlıkla sildiriyor.
İçindekiler
Önceki ders bir dosya sisteminin iki sınırını ayırdı ve bütün ölçümlerini tek bir varsayımın üzerine kurdu: bakılan dizin gerçekten o dosya sisteminin dizini. Bu varsayım bedava değildir. Bir dosya sistemi ağaçta bir noktaya takılır ve o nokta takmadan önce de sonra da yazılabilir bir dizindir.
Bu ders takmanın kendisini ve önyüklemede otomatik takmayı ölçer. İki sayı çıkacak: bir kalıcı takma girdisinin kaç önyüklemede yanlış dosya sistemini takabileceği ve tek bir takma seçeneğinin bir bakım görevine kaç dosyayı yanlışlıkla sildirebileceği. İkisi de hata iletisi üretmez.
Takma Bir Ekleme İşlemidir
Bu sistemde her dosya sistemi ayrı bir harf altında değil, tek bir ağacın bir dalında durur. Takma (mount), bir blok aygıtındaki dosya sistemini bu ağacın bir noktasına bağlamaktır; o noktaya takma noktası (mount point) denir ve takma noktası her zaman var olan bir dizindir.
Takma çekirdekteki bir tabloya girdi ekler; aygıtta hiçbir şey değişmez. Aynı aygıt birden
çok noktaya takılabilir, bir nokta üst üste iki kez takılabilir ve takmayı kaldırmak veriyi
etkilemez. Takılı olanlar findmnt ile ağaç biçiminde, mount ile düz liste hâlinde
okunur. Aşağıdaki döküm findmnt çıktısının biçimini gösteren bir örnek dökümdür;
çalıştırılmamıştır ve bu derste hiçbir sayı iddiası buradan gelmez.
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sdb1 ext4 rw,relatime
├─/veri /dev/sdb2 xfs rw,noatime,nodev
└─/gunluk
/dev/sdb3 ext4 rw,relatime,noexec,nosuid
Takma noktasının takmadan önceki içeriği, dersin ilk tuzağıdır. /veri dizini boş olmak
zorunda değildir; içinde dosya varsa, aygıt oraya takıldığı anda o dosyalar görünmez olur.
Silinmezler, taşınmazlar ve altta kalan dosya sisteminde yer tutmaya devam ederler; yalnız
adlarına ulaşılamaz. Bunun en sık görülen biçimi şudur: bir birim, aygıt henüz takılmadan
çalışmaya başlar ve çıktısını takma noktasına yazar; aygıt sonradan takılır ve o veri kök
dosya sisteminin içinde gömülü kalır. du takma noktasını gezdiğinde onu göremez, çünkü artık
ağaçta yoktur; df kök dosya sisteminde açıklanamayan bir doluluk gösterir. İki çıktı arasındaki
bu fark, önceki dersteki adı silinmiş dosyanın ikizidir ve aynı biçimde bulunur — takmayı
geçici olarak kaldırıp aynı dizine yeniden bakmak yeter.
Kalıcı Takma ve Aygıt Adı
Elle yapılan takma yeniden başlatmada kaybolur. Önyüklemede otomatik takma, aygıtı takma noktasına, dosya sistemi türüne ve seçenek listesine bağlayan bir kalıcı takma (persistent mount) girdisiyle tanımlanır. Girdinin ilk alanı aygıtı adlandırır ve bu alanın nasıl yazıldığı bu bölümün ölçüsüdür.
Aygıt adları keşif sırasına göre verilir. Bir denetleyici diğerinden önce yanıt verirse adlar yer değiştirir; bir aygıt eklendiğinde ya da arızalandığında sıra tümüyle kayar. Aygıtın kimliği ise dosya sistemi kurulurken yazılır ve aygıt nereye takılırsa takılsın değişmez.
- DP20 — Kurgu sunucuda beş blok aygıtı vardır; üçü aynı türde veri dosya sistemi, biri takas alanı, biri farklı türde bir dosya sistemi taşır.
- DP21 — Her önyüklemede keşif sırası değişebilir; sıra ortak tanımın üretecinden çekilir ve adlar bu sıraya göre dağıtılır. 60 önyükleme gözlenir.
- DP22 —
/verigirdisiaygit-badına yazılmıştır ve tür alanı veri dosya sistemidir. Girdi doğru kimliği taktığında doğru, başka bir aygıtı aynı türde olduğu için sorunsuz taktığında sessiz yanlış, tür uyuşmadığı için başarısız olduğunda gürültülü hata sayılır.
"""Onyuklemede aygit adi ile aygit kimligi ayni sey degil.""" TOHUM = 20260218 ONYUKLEME = 60 # gozlenen onyukleme sayisi AYGIT = ({"kimlik": "k1", "tur": "ext4", "icerik": "kok"}, {"kimlik": "k2", "tur": "ext4", "icerik": "veri"}, {"kimlik": "k3", "tur": "ext4", "icerik": "gunluk"}, {"kimlik": "k4", "tur": "swap", "icerik": "takas"}, {"kimlik": "k5", "tur": "xfs", "icerik": "yedek"}) AD = ("aygit-a", "aygit-b", "aygit-c", "aygit-d", "aygit-e") KAYIT = {"ad": "aygit-b", "kimlik": "k2", "tur": "ext4"} # /veri girdisi def uretec(tohum): d = tohum def sonraki(n): nonlocal d d = (d * 1103515245 + 12345) % 2147483648 return d % n return sonraki def kesif_sirasi(r): """Aygitlar bulunma sirasina gore adlandirilir; sira degisebilir.""" kalan, sira = list(AYGIT), [] while kalan: sira.append(kalan.pop(r(len(kalan)))) return sira def onyukle(tohum=TOHUM, sayi=ONYUKLEME): r = uretec(tohum) ada_gore = {"dogru": 0, "sessiz_yanlis": 0, "gurultulu_hata": 0} kimlige_gore = {"dogru": 0, "sessiz_yanlis": 0, "gurultulu_hata": 0} for _ in range(sayi): secilen = dict(zip(AD, kesif_sirasi(r)))[KAYIT["ad"]] if secilen["kimlik"] == KAYIT["kimlik"]: ada_gore["dogru"] += 1 elif secilen["tur"] == KAYIT["tur"]: ada_gore["sessiz_yanlis"] += 1 else: ada_gore["gurultulu_hata"] += 1 kimlige_gore["dogru"] += 1 return ada_gore, kimlige_gore A, K = onyukle() print("kayit bicimi dogru sessiz yanlis gurultulu hata yanlis tani") for ad, s in (("aygit adi", A), ("aygit kimligi", K)): print(f" {ad:12s} {s['dogru']:6d} {s['sessiz_yanlis']:13d}" f" {s['gurultulu_hata']:14d} {s['sessiz_yanlis']:11d}") print("onyukleme sayisi:", ONYUKLEME) print() for tohum in (TOHUM, 20260219): a, _ = onyukle(tohum) print(f"tohum {tohum}: dogru {a['dogru']:3d} sessiz yanlis" f" {a['sessiz_yanlis']:3d} gurultulu hata {a['gurultulu_hata']:3d}")
kayit bicimi dogru sessiz yanlis gurultulu hata yanlis tani aygit adi 13 27 20 27 aygit kimligi 60 0 0 0 onyukleme sayisi: 60 tohum 20260218: dogru 13 sessiz yanlis 27 gurultulu hata 20 tohum 20260219: dogru 10 sessiz yanlis 27 gurultulu hata 23
Üç sayı yan yana. Kâhin: /veri noktasına takılması gereken dosya sistemi her önyüklemede
aynı kimliktir. Araç çıktısı: takma tablosu her önyüklemede /veri için bir kaynak
gösterir ve gösterdiği ad her seferinde aygit-b’dir; tabloya bakan biri hiçbir fark
görmez. Yanlış tanı: altmış önyüklemenin yirmi yedisinde yanlış dosya sistemi hatasız
takılıyor.
Yirmi hatalı önyükleme aslında iyi haberdir: tür uyuşmadığı için takma başarısız olur, arıza görülür ve düzeltilir. Tehlikeli olan yirmi yedi sessiz durumdur — birim çalışır, veri yazılır, hiçbir günlük satırı üretilmez ve yazılan veri beklenen yerde durmaz. Kimliğe yazılmış girdide bu sayı sıfırdır; ikinci tohumda doğru önyükleme 13 yerine 10 çıkıyor, sessiz yanlış yine 27. Kimliğe yazmanın kazandırdığı şey bir başarım değil, bir belirlilik.
Kimlik yazmanın da bir maliyeti vardır ve saklanmaz: kimlik okunaksızdır, elle yazılması hataya açıktır ve aygıt yeniden biçimlendirildiğinde değişir. Bu yüzden girdiler çoğunlukla elle değil, aygıttan okunarak üretilir. Bir ara yol, dosya sistemine kurulurken verilen etikettir; etiket okunabilir bir addır ve aygıt adı gibi keşif sırasına bağlı değildir, ama iki aygıta aynı etiket verilirse belirlilik yine kaybolur.
Girdinin son alanları da tanıyı etkiler. Bir girdi başarısız olduğunda önyükleme durabilir ve makine yalnız kurtarma kabuğuna açılır; bunu engelleyen seçenek arızayı görünmez kılar ve sistem eksik dosya sistemiyle çalışmaya devam eder. İkisi arasındaki seçim bir tercihtir: gürültülü durmak mı, sessiz eksik çalışmak mı.
Sessizce Anlam Değiştiren Seçenek
Seçenek listesi takmanın en az okunan alanıdır. Bir bölümü salt okunur takmak ya da program çalıştırmaya kapatmak gürültülü sonuçlar üretir: yazma reddedilir, çalıştırma reddedilir, hata iletisi görünür. Erişim zamanını güncellemeyen seçenek ise hiçbir şey reddetmez; yalnız kaydedilen bir sayıyı dondurur.
- DP23 —
/veribölümünde 2000 dosya vardır; oluşturma, son yazma ve son okuma anları 600 saniyelik pencerede üreteçten çekilir. - DP24 — Kaydedilen erişim zamanı seçeneğe bağlıdır: tam güncellemede gerçek okuma anı, gevşek güncellemede yalnız yazma anı, güncellemesiz seçenekte oluşturma anı yazılır.
- DP25 — Temizlik görevi, kaydedilen erişim zamanı 300 saniyeden eski olan dosyaları siler. Kâhin, dosyanın gerçek son okunma anıdır.
"""Takma secenegi erisim zamanini degistiriyor , temizlik gorevi yanlis siliyor.""" TOHUM = 20260218 DONEM = 600 ESIK = 300 DOSYA = 2000 def uretec(tohum): d = tohum def sonraki(n): nonlocal d d = (d * 1103515245 + 12345) % 2147483648 return d % n return sonraki def dosyalar(tohum=TOHUM, sayi=DOSYA): """Kahin: her dosyanin GERCEK son okunma ani.""" r = uretec(tohum) liste = [] for _ in range(sayi): olusturma = r(400) son_yazma = olusturma + (r(DONEM - olusturma) if r(10) < 3 else 0) taban = max(olusturma, son_yazma) son_okuma = taban + (r(DONEM - taban) if r(10) < 6 else 0) liste.append({"olusturma": olusturma, "son_yazma": son_yazma, "son_okuma": son_okuma}) return liste def kaydedilen(d, secenek): if secenek == "atime": return d["son_okuma"] if secenek == "relatime": return d["son_yazma"] return d["olusturma"] # noatime: hic guncellenmez def temizlik(liste, secenek, esik=ESIK): """Gorev , kaydedilen erisim zamani esikten eskiyse siler.""" yanlis_silme = yanlis_koruma = silinen = 0 for d in liste: sil = kaydedilen(d, secenek) < esik eski = d["son_okuma"] < esik # kahin silinen += sil yanlis_silme += sil and not eski yanlis_koruma += eski and not sil return {"silinen": silinen, "yanlis_silme": yanlis_silme, "yanlis_koruma": yanlis_koruma, "yanlis": yanlis_silme + yanlis_koruma} L = dosyalar() print("kahin: gercekten eskimis dosya:", sum(d["son_okuma"] < ESIK for d in L), "/", DOSYA) print() print("secenek silinen yanlis silme yanlis koruma yanlis tani") for s in ("atime", "relatime", "noatime"): t = temizlik(L, s) print(f" {s:9s} {t['silinen']:7d} {t['yanlis_silme']:12d}" f" {t['yanlis_koruma']:13d} {t['yanlis']:11d}") print() for tohum in (TOHUM, 20260219): l2 = dosyalar(tohum) print(f"tohum {tohum}: eskimis {sum(d['son_okuma'] < ESIK for d in l2):4d}" f" atime {temizlik(l2, 'atime')['yanlis']:4d}" f" relatime {temizlik(l2, 'relatime')['yanlis']:4d}" f" noatime {temizlik(l2, 'noatime')['yanlis']:4d}")
kahin: gercekten eskimis dosya: 717 / 2000 secenek silinen yanlis silme yanlis koruma yanlis tani atime 717 0 0 0 relatime 1204 487 0 487 noatime 1504 787 0 787 tohum 20260218: eskimis 717 atime 0 relatime 487 noatime 787 tohum 20260219: eskimis 728 atime 0 relatime 502 noatime 821
Üç sayı yan yana. Kâhin: 2000 dosyanın 717’si gerçekten üç yüz saniyeden beri okunmamıştır. Araç çıktısı: güncellemesiz seçenekte dosyaların erişim zamanı okunduğunda 1504’ü eski görünür. Yanlış tanı: temizlik görevi 787 dosyayı yanlışlıkla siler ve tek bir hata iletisi üretmez.
Üç satır arasındaki fark bir tasarım ödünleşmesidir. Erişim zamanını her okumada güncellemek, salt okuma iş yükünü bir yazma iş yüküne çevirir; her dosya okuması bir meta veri yazması üretir. Gevşek güncelleme bu maliyeti düşürür ve 487 yanlış silme getirir; güncellemesiz seçenek maliyeti sıfırlar ve 787 yanlış silme getirir. Yanlış koruma sütununun her üç satırda da sıfır olması yanılgının tek yönlü olduğunu gösteriyor: kaydedilen zaman gerçeğin gerisinde kalır, ilerisine geçmez. İkinci tohumda sayılar 502 ve 821 oluyor, sıralama değişmiyor.
Buradan çıkan kural şudur: bir takma seçeneği, üzerinde çalışan görevlerin varsayımını
değiştirir. Seçenek listesi findmnt çıktısında görünür ve o listeye bakan biri hangi görevin
hangi alana güvendiğini bilmiyorsa, gördüğü satırdan hiçbir tanı çıkaramaz.
Hata Anında Salt Okunura Geçme
Takma seçeneklerinin bir bölümü işlemleri değil, arıza davranışını belirler. Bir dosya sistemi kendi defterlerinde tutarsızlık ya da aygıttan hata algıladığında ne yapacağını takma anında öğrenir: yok sayıp devam edebilir, kendini salt okunura çevirebilir ya da makineyi durdurabilir. Yaygın öntanımlı davranış ortadakidir.
Salt okunura geçmenin operatör açısından tuhaf bir yanı vardır. Aygıt hâlâ takılıdır, ağaçta
görünür, okumalar çalışır ve df doluluk göstermeye devam eder; yalnız yazmalar reddedilir.
Yazan birimler bu reddi bir hata olarak alır ve yeniden başlatma politikası bu hatayı örter —
servisler konusunda ölçülen durum burada da geçerlidir ve tekrarlanmaz. Sonuç, çalışıyor
görünen ama hiçbir şey yazmayan bir sistemdir.
Bu geçişin kaydı yalnız bir yerde durur: sistem günlüğüne düşen tek bir satır. Satır, geçiş
anında yazılır ve sonra bir daha yazılmaz; günlük döndürüldüğünde ortadan kalkar. Günlükler
konusundaki üçüncü iddianın en pahalı örneği budur — arızanın tek kanıtı, kendisi kanıt
silen bir düzende tutuluyor. Takma tablosundaki seçenek listesinde ise ro ibaresi görünür
ve o ibare, dosya sisteminin bu duruma sonradan geçtiğini söylemez; girdiye salt okunur
yazılmış olsa da aynı görünürdü.
Yanlış Girdi ve Geri Dönüş
Kalıcı takma girdilerini tutan dosya, sistemin en az yazılan ve en çok zarar veren dosyalarından biridir. Yanlış yazılmış bir satır önyüklemeyi durdurabilir; sistem uzaktaysa ve konsol erişimi yoksa makine ulaşılamaz duruma gelir. Bu yüzden girdiyi yazan işlem tek başına değil, üç adımlı bir yordamla yapılır.
Birincisi söz dizimi ve hedef doğrulamasıdır: findmnt --verify girdileri okur, aygıt
kimliklerinin karşılığı olup olmadığına bakar ve takma noktalarının var olup olmadığını
denetler; hiçbir şey takmaz. İkincisi denemedir: girdiler yeniden okunup henüz takılmamış
olanlar takılır ve sonuç aynı oturumda görülür. Üçüncüsü geri dönüş yoludur: değişiklik
yapılmadan önce dosyanın bir kopyası alınır ve yeniden başlatma, kurtarma kabuğuna erişimin
mümkün olduğu bir zamanda denenir.
Girdinin okunma sırası da bir tuzaktır. Takma noktaları iç içe olabilir ve içteki bir nokta, dıştaki takılmadan önce takılamaz; sıra bozulduğunda içteki dosya sistemi kök dosya sistemi üzerindeki bir dizine takılır ve beklenen yerde durmaz. Bağımlılığı çözen şey girdilerin dosyadaki sırası değil, takma noktalarının yol derinliğidir; araçlar bu sıralamayı kendileri yapar ama elle verilen bir takma komutu yapmaz.
Takmayı kaldırmak da düşünüldüğü kadar zararsız değildir. Bir dosya sistemi, üzerinde açık tanıtıcısı olan bir süreç varken ayrılamaz ve zorlayan seçenekle ayrılması, o süreçlerin yazmakta olduğu veriyi yarıda bırakır. Bu ders zorlayan ayırma komutunu tam biçimde vermez; doğru sıra, önce dosya sistemini kullanan birimlerin durdurulması, sonra açık tanıtıcı kalmadığının doğrulanması, en son ayırmadır.
Özet
- Takma, bir aygıttaki dosya sistemini tek ağacın bir noktasına bağlar; takma noktasının önceki içeriği silinmez, görünmez olur ve altta kalan dosya sisteminde yer tutmaya devam eder.
- Aygıt adları keşif sırasına göre verilir:
aygit-badına yazılmış bir kalıcı takma girdisi altmış önyüklemenin yalnız 13’ünde doğru dosya sistemini takıyor, 27’sinde sessizce yanlışını takıyor, 20’sinde gürültülü hata veriyor. Kimliğe yazıldığında yanlış tanı sıfır. - Erişim zamanını güncellemeyen takma seçeneği hiçbir işlemi reddetmez; yalnız kaydedilen zamanı dondurur. 717 dosya gerçekten eskiyken görev 1504 dosya siliyor ve bunların 787’si yanlış silme.
- Yanılgı tek yönlüdür: kaydedilen erişim zamanı gerçeğin gerisinde kalır, ilerisine geçmez; bu yüzden yanlış koruma sütunu üç seçenekte de sıfırdır.
- Kalıcı takma girdisi yanlış yazıldığında önyükleme durabilir; doğrulama komutu, aynı oturumda deneme ve dosyanın kopyası bu riski ölçülebilir biçimde düşürür.
Sonraki Adım
Bu dersin bütün ölçümleri bir bölümün sınırlarının sabit olduğunu varsaydı: aygıtta çizilmiş bir aralık ve içine kurulmuş bir dosya sistemi. Dolduğunda yapılabilecek tek şey silmekti. Sonraki ders bu sabitliği kaldıran bir katman ekler — bölümü birimlerden oluşan bir havuza çeviren, birimi çalışırken büyütebilen ve bir anın kopyasını tutabilen bir katman. O katmanın da kendi sınırı vardır ve ölçülecek şey, anlık görüntünün dolduğu andır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.