İçeriğe geç
academia.sh

Ders 08 / 11

Konuk ve Konak Sistem

Kaçış riskinin paylaşılan kalem sayısıyla ölçülmesi: konuk ile konağın paylaştığı on bir kalem, her kalemin açtığı yol ve yolun geçiş, veri ya da bilgi etkisiyle sınıflanması, seçime bağlı paylaşımların kapatılmasıyla kapanan yol ile bunun iş adımı ve konak belleği cinsinden bedeli, konuk koştuğu sürece kapatılamayan altı yol.

İçindekiler

Önceki ders katmanları üst üste saydı: konuk, hipervizör, konak, donanım. O sıralamada her katman bir öncekini taşıyordu. Ama konuk ile konak arasında yalnız bir yığın yok; ikisi çalışırken bir dizi kalemi aynı anda kullanıyor. Aynı zamanlayıcı iki tarafın iş parçacıklarını sıraya diziyor, aynı fiziksel bellek sayfaları paylaştırılıyor, konuğun gördüğü disk ve ağ kartı konakta koşan bir öykünme kodudur, üstüne bir de rahatlık için açılmış paylaşılan dizin, pano ve ajan kanalı var.

Kaçış, konuk sınırının bir kez geçilip konak tarafında bir şeye ulaşılmasıdır. Bu ders kaçışı bir olasılık olarak değil, paylaşılan kalem sayısı olarak ölçer: konuk ile konak kaç kalemi paylaşıyor, paylaşılan her kalem kaç yol açıyor ve o yolların kaçı kapatılabiliyor. Kaçış adımının kendisi yazılmaz; yolun adı, etkisi ve karşılığı yazılır. Bir kaçış yolunun gerçek bir sistemde denenmesi, yazılı yetki ve tanımlı kapsam olmadan hem yasadışı hem de meslek dışıdır.

SA7 — Paylaşılan kalem, konuk çalışırken konakla ortak kullanılan bir bileşendir; kurgu şube sunucusundaki liste modeldir, sayım gerçektir. SA8 — Bir yol, tek bir paylaşılan kalem üzerinden konak tarafında ulaşılan sonuçtur. SA9 — Yolun etkisi üç sınıftan biridir: geçiş (konak sürecinde kod çalıştırma), veri (konak verisine dokunma), bilgi (yalnız çıkarım). SA10 — Zorunlu kalem, konuk koştuğu sürece kapatılamayan kalemdir. SA11 — Bedel iki birimde yazılır: değişen meşru iş adımı ve konakta ek bellek. SA12 — Şube sunucusunda dört konuk vardır ve iki güven düzeyine ayrılır.

Paylaşılan Kalemler

Paylaşılan kalemler iki türdür. Bir bölümü konuk çalıştığı sürece vardır: konuk bir işlemci zamanı almak, bir disk görmek ve bir ağ kartına yazmak zorundadır, o disk ve ağ kartı da konakta koşan bir öykünme kodudur. Öteki bölüm rahatlık için açılır ve bir yapılandırma kalemiyle kapatılabilir.

// paylasim.mjs — konuk ile konagin paylastigi kalemler ve her kalemin actigi yol (MODEL).
// Yollar savunma ekseninde adlandirilir; istismar kodu degil, yol adi ve etkisi yazilir.
// etki: gecis = konak surecine gecme, veri = konak verisine dokunma, bilgi = bilgi cikarimi.

// [kalem, zorunlu mu, [[yol, etki], ...], [degisen mesru is adimi, konakta ek bellek MiB]]
export const PAYLASIM = [
  ['zamanlayici', true, [['komsu konugun etkinlik zamanlamasi', 'bilgi']], [0, 0]],
  ['islemci onbellegi', true, [['paylasilan satirdan erisim deseni', 'bilgi']], [0, 0]],
  ['saat kaynagi', true, [['konak bakim penceresinin cikarimi', 'bilgi']], [0, 0]],
  ['disk denetleyicisi oykunmesi', true, [['oykunme kusuruyla konak surecine gecis', 'gecis']], [0, 0]],
  ['ag arayuzu oykunmesi', true, [['oykunme kusuruyla konak surecine gecis', 'gecis'],
    ['konak ag yiginina konuk paketi', 'veri']], [0, 0]],
  ['bellek sayfasi birlestirme', false, [['ayni sayfanin varligini olcme', 'bilgi'],
    ['yazma gecikmesinden sayfa paylasimi', 'bilgi']], [0, 1856]],
  ['ekran denetleyicisi oykunmesi', false, [['oykunme kusuruyla konak surecine gecis', 'gecis']], [2, 0]],
  ['paylasilan dizin', false, [['konak dosya sistemine yazma', 'veri'],
    ['konaktan gelen dosyanin konukta calismasi', 'veri']], [2, 0]],
  ['pano', false, [['konak panosunu okuma', 'veri'], ['konuga konaktan veri gecirme', 'veri']], [1, 0]],
  ['konuk ajani kanali', false, [['konaktan konukta komut calistirma', 'veri'],
    ['konuk dosya sistemini konaktan okuma', 'bilgi']], [4, 0]],
  ['usb gecirme', false, [['takilan aygitin konak surucusune ulasmasi', 'gecis']], [1, 0]],
];
export const ETKI = ['gecis', 'veri', 'bilgi'];
export const yol = (liste) => liste.reduce((t, [, , y]) => t + y.length, 0);
export const etkiSay = (liste, e) => liste.reduce((t, [, , y]) => t + y.filter(([, k]) => k === e).length, 0);

if (import.meta.url === `file://${process.argv[1]}`) {
  const s = (x, n) => String(x).padStart(n);
  const T = yol(PAYLASIM);
  console.log(`${PAYLASIM.length} paylasilan kalem, ${T} yol; kalem basina ortalama `
    + `${(T / PAYLASIM.length).toFixed(2)} yol`);
  console.log(`\n${'kalem'.padEnd(30)}${'tur'.padEnd(14)}${s('yol', 4)}${s('gecis', 7)}${s('veri', 6)}`
    + `${s('bilgi', 7)}${s('ek adim', 9)}${s('ek bellek', 11)}`);
  for (const k of PAYLASIM) {
    const [ad, zorunlu, y, [adim, mib]] = k;
    console.log(`${ad.padEnd(30)}${(zorunlu ? 'zorunlu' : 'secime bagli').padEnd(14)}${s(y.length, 4)}`
      + ETKI.map((e) => s(etkiSay([k], e), e === 'veri' ? 6 : 7)).join('')
      + `${s(zorunlu ? '-' : adim, 9)}${s(zorunlu ? '-' : mib, 11)}`);
  }
  for (const [ad, f] of [['zorunlu toplam', true], ['secime bagli toplam', false]]) {
    const g = PAYLASIM.filter(([, z]) => z === f);
    const [adim, mib] = g.reduce(([a, m], [, , , [x, y]]) => [a + x, m + y], [0, 0]);
    console.log(`${ad.padEnd(44)}${s(yol(g), 4)}` + ETKI.map((e) => s(etkiSay(g, e), e === 'veri' ? 6 : 7)).join('')
      + `${s(f ? '-' : adim, 9)}${s(f ? '-' : mib, 11)}`);
  }
}
11 paylasilan kalem, 16 yol; kalem basina ortalama 1.45 yol

kalem                         tur            yol  gecis  veri  bilgi  ek adim  ek bellek
zamanlayici                   zorunlu          1      0     0      1        -          -
islemci onbellegi             zorunlu          1      0     0      1        -          -
saat kaynagi                  zorunlu          1      0     0      1        -          -
disk denetleyicisi oykunmesi  zorunlu          1      1     0      0        -          -
ag arayuzu oykunmesi          zorunlu          2      1     1      0        -          -
bellek sayfasi birlestirme    secime bagli     2      0     0      2        0       1856
ekran denetleyicisi oykunmesi secime bagli     1      1     0      0        2          0
paylasilan dizin              secime bagli     2      0     2      0        2          0
pano                          secime bagli     2      0     2      0        1          0
konuk ajani kanali            secime bagli     2      0     1      1        4          0
usb gecirme                   secime bagli     1      1     0      0        1          0
zorunlu toplam                                 6      2     1      3        -          -
secime bagli toplam                           10      2     5      3       10       1856

On bir kalem on altı yol açıyor; kalem başına ortalama 1,45. Bu ortalama tek başına bir uyarıdır: paylaşılan bir kalemi kapatmak bir yolu değil, çoğu zaman iki yolu kapatır — ve açık bırakmak da öyle.

Etki sütunları listeyi ikiye ayırıyor. Zorunlu beş kalem altı yol açıyor ve bunların üçü yalnız bilgi çıkarımıdır: komşunun ne zaman çalıştığı, hangi bellek sayfasının ortak olduğu, konağın bakım penceresi. İki tanesi geçiştir ve ikisi de bir öykünme kodundan gelir. Konuk bir disk ve bir ağ kartı görmek zorunda olduğuna göre o iki öykünme kodu her koşumda konakta çalışır; bu iki geçiş yolu kapatılabilir bir kalem değildir.

Seçime bağlı altı kalem on yol açıyor ve dağılım tersine dönüyor: beş veri yolunun beşi de bu grupta. Pano, paylaşılan dizin ve ajan kanalı — üçü de bir kişinin işini kolaylaştırmak için açılmış kalemlerdir — konak verisine dokunan yolların tamamını taşıyor. Sağ iki sütun bunun karşılığını yazıyor: on iş adımı ve 1.856 MiB konak belleği.

Kapatmanın Kapattığı ve Bıraktığı

Aşağıdaki koşum seçime bağlı kalemleri tek tek kapatıyor — önce çok yol açanı, eşitlikte ucuz olanı — ve her adımda kapanan yolu bedelle birlikte yazıyor.

// kapatma.mjs — secime bagli paylasimlar tek tek kapatilir; kapanan yol ve bedel birlikte sayilir.
import { PAYLASIM, ETKI, yol, etkiSay } from './paylasim.mjs';

const T = yol(PAYLASIM);
const secmeli = PAYLASIM.filter(([, z]) => !z)
  .sort((a, b) => b[2].length - a[2].length || a[3][0] - b[3][0]);   // once cok yol, sonra ucuz
const s = (x, n) => String(x).padStart(n);
console.log(`${'kapatilan kalem'.padEnd(30)}${s('kapanan', 8)}${s('toplam', 7)}${s('kalan', 6)}`
  + `${s('ek adim', 9)}${s('ek bellek', 11)}`);
let kapanan = 0, adim = 0, mib = 0;
for (const [ad, , y, [a, m]] of secmeli) {
  kapanan += y.length; adim += a; mib += m;
  console.log(`${ad.padEnd(30)}${s(y.length, 8)}${s(kapanan, 7)}${s(T - kapanan, 6)}${s(adim, 9)}${s(mib, 11)}`);
}

const kalan = PAYLASIM.filter(([, z]) => z);
console.log(`\nkapatilabilen ${secmeli.length}/${PAYLASIM.length} kalem, kapanan ${kapanan}/${T} yol `
  + `(%${((100 * kapanan) / T).toFixed(1)}); bedel ${adim} is adimi ve ${mib} MiB konak bellegi`);
console.log(`${'etki'.padEnd(10)}${s('bastaki yol', 12)}${s('kalan yol', 11)}`);
for (const e of ETKI)
  console.log(`${e.padEnd(10)}${s(etkiSay(PAYLASIM, e), 12)}${s(etkiSay(kalan, e), 11)}`);
console.log(`konuk kostugu surece kapatilamayan ${kalan.length} kalem ${yol(kalan)} yol birakiyor`);

// Yerlesim: ayni konaktaki dort kurgu konuk, iki guven duzeyi.
const KONUK = [['toplayici', 'yuksek'], ['dogrulayici', 'yuksek'], ['saha portali', 'dusuk'], ['sinama', 'dusuk']];
const cift = KONUK.flatMap((a, i) => KONUK.slice(i + 1).map((b) => [a[1], b[1]]));
const karisik = cift.filter(([a, b]) => a !== b).length;
console.log(`\ntek konak: ${KONUK.length} konuk, ${cift.length} komsu cifti, farkli duzeyden ${karisik} cift`);
console.log(`duzey basina ayri konak: ${cift.length - karisik} cift, farkli duzeyden 0; `
  + `kalan yol yine ${yol(kalan)}, bedel 1 makine daha`);
kapatilan kalem                kapanan toplam kalan  ek adim  ek bellek
bellek sayfasi birlestirme           2      2    14        0       1856
pano                                 2      4    12        1       1856
paylasilan dizin                     2      6    10        3       1856
konuk ajani kanali                   2      8     8        7       1856
usb gecirme                          1      9     7        8       1856
ekran denetleyicisi oykunmesi        1     10     6       10       1856

kapatilabilen 6/11 kalem, kapanan 10/16 yol (%62.5); bedel 10 is adimi ve 1856 MiB konak bellegi
etki       bastaki yol  kalan yol
gecis                4          2
veri                 6          1
bilgi                6          3
konuk kostugu surece kapatilamayan 5 kalem 6 yol birakiyor

tek konak: 4 konuk, 6 komsu cifti, farkli duzeyden 4 cift
duzey basina ayri konak: 2 cift, farkli duzeyden 0; kalan yol yine 6, bedel 1 makine daha

Altı kalem kapatıldığında on altı yolun onu kapanıyor, altısı kalıyor. Birinci satır ilk bakışta bedava görünüyor: bellek sayfası birleştirme iki bilgi yolunu kapatıyor ve değişen iş adımı sıfır. Bedel iş akışında değil, bellektedir — 1.856 MiB konak belleği, çünkü birleştirilmiş sayfalar artık ayrı ayrı tutulur. Bedeli sıfır görünen kalemin bedeli genelde başka bir sütundadır.

Etki tablosu asıl kazancı gösteriyor. Veri yolları altıdan bire iniyor; kalan tek veri yolu ağ öykünmesinin taşıdığı yoldur. Yani konak verisine dokunan yolların beşte dördü, kapatılabilir rahatlık kalemlerinin içindeydi. Geçiş yolları dörtten ikiye, bilgi yolları altıdan üçe iniyor. Toplam bedel on iş adımıdır: dosya aktarımı ağ üzerinden yapılır, kapatma ve açılış yordamları elle yürütülür, saha cihazı okuması şube istemcisine taşınır.

Kalan altı yol bu dersin sınırıdır. Konuk koştuğu sürece bir zamanlayıcı, bir işlemci önbelleği, bir saat kaynağı, bir disk ve bir ağ arayüzü paylaşılır. Bunlar kapatılamaz, çünkü kapatıldıklarında konuk da çalışmaz. Geriye o altı yolun ne kadar kolay işlediğini sormak kalıyor.

Yol Başına Gereken Kalem

Buraya kadar her yol tek bir paylaşılan kalemle eşleştirildi. Bu, yolun tek koşulu paylaşımın varlığıymış gibi okunur; çoğu yolda böyle değildir. Aşağıdaki koşum her yola paylaşımın üstüne gereken ek koşulları veriyor ve sınırı geçmek için aynı anda doğru olması gereken kalem sayısını çıkarıyor.

// kosul.mjs — her yol icin ayni anda dogru olmasi gereken kalem sayisi (MODEL).
// Paylasilan kalemin varligi bir kalemdir; asagidaki liste ona EK kosullari verir.
import { PAYLASIM } from './paylasim.mjs';

const EK = {
  'komsu konugun etkinlik zamanlamasi': [],
  'paylasilan satirdan erisim deseni': ['komsuyla ayni cekirdege yerlesme'],
  'konak bakim penceresinin cikarimi': [],
  'oykunme kusuruyla konak surecine gecis': ['yamalanmamis oykunme kusuru'],
  'konak ag yiginina konuk paketi': ['konak arayuzunun konuk agina bagli olmasi'],
  'ayni sayfanin varligini olcme': ['komsuda ayni sayfa icerigi'],
  'yazma gecikmesinden sayfa paylasimi': ['komsuda ayni sayfa icerigi'],
  'konak dosya sistemine yazma': ['takmanin yazilabilir olmasi'],
  'konaktan gelen dosyanin konukta calismasi': ['konukta calistirma izni', 'dosyanin acilmasi'],
  'konak panosunu okuma': [], 'konuga konaktan veri gecirme': [],
  'konaktan konukta komut calistirma': ['konak tarafinda ajan yetkisi'],
  'konuk dosya sistemini konaktan okuma': ['konak tarafinda ajan yetkisi'],
  'takilan aygitin konak surucusune ulasmasi': ['fiziksel erisim', 'yamalanmamis surucu kusuru'],
};
// [gereken kalem, yol adi, zorunlu kalemden mi]
const YOL = PAYLASIM.flatMap(([, z, y]) => y.map(([ad]) => [1 + EK[ad].length, ad, z]));

const s = (x, n) => String(x).padStart(n);
console.log(`${'gereken kalem'.padEnd(15)}${s('yol', 4)}   ornek`);
for (const g of [...new Set(YOL.map(([n]) => n))].sort()) {
  const k = YOL.filter(([n]) => n === g);
  console.log(`${String(g).padEnd(15)}${s(k.length, 4)}   ${k[0][1]}`);
}
const zorunlu = YOL.filter(([, , z]) => z);
console.log(`\nkapatilamayan ${zorunlu.length} yolda gereken kalem: `
  + [...new Set(zorunlu.map(([n]) => n))].sort()
    .map((g) => `${g} -> ${zorunlu.filter(([n]) => n === g).length} yol`).join(', '));
const ikinci = YOL.flatMap(([, ad]) => EK[ad]);
const sayim = [...new Set(ikinci)].map((k) => [k, ikinci.filter((x) => x === k).length])
  .sort((a, b) => b[1] - a[1]);
console.log(`en sik ek kosul: ${sayim[0][0]} (${sayim[0][1]} yol); toplam ${ikinci.length} ek kosul, `
  + `${sayim.length} ayri kalem`);
gereken kalem   yol   ornek
1                 4   komsu konugun etkinlik zamanlamasi
2                10   paylasilan satirdan erisim deseni
3                 2   konaktan gelen dosyanin konukta calismasi

kapatilamayan 6 yolda gereken kalem: 1 -> 2 yol, 2 -> 4 yol
en sik ek kosul: yamalanmamis oykunme kusuru (3 yol); toplam 14 ek kosul, 10 ayri kalem

On altı yolun dördü tek kalemle işliyor: paylaşım açıksa yol açıktır, başka hiçbir koşul gerekmiyor. Bu dördü zamanlayıcı, saat kaynağı ve panonun iki yönüdür; üçü de bir kusura ya da bir yerleşime bağlı değil, paylaşımın tanımı gereği vardır. On yol iki kalem, iki yol üç kalem istiyor.

Kapatılamayan altı yolun ikisi tek kalemle işliyor ve ikisi de bilgi yoludur. Kalan dördü ikinci bir kalem ister ve en sık istenen ikinci kalem yamalanmamış öykünme kusurudur — üç yolda aynı koşul. Bu, sınırı geçmenin ölçüsünü yamaya bağlıyor: öykünme kodunun yamalı olduğu bir konakta o üç yol iki kalem ister ve ikincisi yerinde değildir. Yama programının kendisi bu kursun konusu değil, ama buradaki sayı onun neyi değiştirdiğini yazıyor: üç geçiş yolunun ikinci kalemini o kapatıyor.

Kapatılamayan Altı Yol

Kapatılamayan bir yol için yapılabilecek şey, o yolun ulaştığı yeri değiştirmektir. Son iki satır bunu ölçüyor. Dört konuk aynı konakta koşarken altı komşu çifti oluşuyor ve bunların dördü farklı güven düzeyinden geliyor: sayaç okumasını toplayan konuk ile sınama konuğu, doğrulayıcı ile saha portalı. Kalan altı yol bu dört çiftin arasında işliyor.

Konukları güven düzeyine göre iki ayrı konağa dağıtmak yolların hiçbirini kapatmıyor — her konakta yine altı yol var — ama farklı düzeyden çiftin sayısını dörtten sıfıra indiriyor. Kalan iki çiftte komşular zaten aynı veriye erişen sistemlerdir; bir komşunun ötekinden çıkardığı bilgi, kendi sınırları içinde zaten sahip olduğu bilgidir. Bedeli bir makinedir.

Bu ölçüm bir tercih değil, bir sıralama veriyor. Önce seçime bağlı altı kalem kapatılır: on yol gider, bedeli on iş adımı ve 1.856 MiB. Sonra yerleşim düzeltilir: hiçbir yol gitmez, ama kalan altı yolun uçları aynı güven düzeyine bağlanır ve bedeli bir makinedir. Üçüncü bir adım yoktur; konuk koştuğu sürece o altı yol açıktır ve savunmanın oradaki karşılığı kapatmak değil, görmektir — hangi öykünme kodunun beklenmedik bir hata döndürdüğü, hangi konuğun komşusunun bakım penceresinde etkinlik gösterdiği.

Özet

  • Konuk ile konak on bir kalem paylaşıyor ve bu kalemler on altı yol açıyor; kalem başına ortalama 1,45 yol düşüyor.
  • Zorunlu beş kalem altı yol açar: iki geçiş, bir veri, üç bilgi. İki geçiş yolu disk ve ağ öykünmesinden gelir ve konuk koştuğu sürece kapatılamaz.
  • Seçime bağlı altı kalem on yol açar ve altı veri yolunun beşini taşır; kapatılınca veri yolu altıdan bire, geçiş dörtten ikiye, bilgi altıdan üçe iner.
  • Bedel iki sütunda yazılır: on değişen iş adımı ve 1.856 MiB konak belleği. Bellek sayfası birleştirmenin iş adımı bedeli sıfırdır, bedeli bellektedir.
  • On altı yolun dördü tek kalemle işler; kalan altı yolun ikisi tek, dördü iki kalem ister ve en sık istenen ikinci kalem yamalanmamış öykünme kusurudur.
  • Yerleşimi güven düzeyine ayırmak yol sayısını değiştirmez, farklı düzeyden komşu çiftini dörtten sıfıra indirir; bedeli bir makinedir.

Sonraki Adım

Bu iki dersin ölçümü hep koşan bir konuk üzerineydi: hangi katman altında duruyor, hangi kalemi konakla paylaşıyor. Ama sanal makinenin asıl ayırt edici özelliği koşarken değil, durdurulup kopyalanırken ortaya çıkıyor. Bir konuk anlık görüntüsü alınıp saklanabiliyor, bir imaj otuz kez klonlanıp otuz makineye dağıtılabiliyor, bir hafta önceki duruma birkaç saniyede dönülebiliyor. Sonraki ders bu üç işlemi sınır kalemi cinsinden ölçer: klon kaç sır kalemini kaç kopyaya taşıyor, anlık görüntü zinciri uzadıkça geri dönüş için kaç sağlam halka gerekiyor ve bir hafta önceye dönmek kaç kapalı açığı yeniden açıyor.

İ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