İçeriğe geç
academia.sh

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/veri girdisi aygit-b adı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/veri bö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-b adı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.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat