İçeriğe geçmek için "Enter"a basın

Debian GNU/Linux ile ZFS Kullanımı

Son güncelleme tarihi 10 Nisan 2022

Bilgisayar ve veri depolama üzerine kısaca;

Bilgi teknolojileri ve bunların kullanımı lisedeyken ( 1997 – 2000 ) sıradan vatandaşlar için olmasa da olur durumdaydı. Aradan geçen 20 yıl ile birlikte bilgisayar, akıllı telefon, otomasyonların gelişimi öyle bir seviyeye ulaştı ki, sıradan işlerimizin içerisine öyle bir seviyede girdi ki, bu teknolojileri kullanmayana artık taş devri insanı olarak bakılabiliyor. Kısacası, toplumun hangi kesiminde olursaka olalım, görevimiz sorumluluğumuz ne olursa olsun bilgi teknolojilerini gündelik hayatımızda kullanmak durumundayız, mecburuz.

Bilgisayar bu teknolojilerden bir tanesi, bilgisayar kullanım kabiliyeti 90lı yıllarda var olan büyük şirketler için kilit rol konumundaydı, günümüzde bilgisayar kullanımını özetlemek gerekirse; “yeğenim 3 yaşlarındayken klavyeye birkaç defa vurduktan sonra kafasını kaldırıp ekrana baktı 🙂 tekrarlayınca bilinçli hareket ettiği kanaatine vardım.” Genetik aktarımla bilgi aktarılıyor sanki. Klavyeye basınca ekranda bir şeyler görüntüleniyor… Akıllı telefon kullanımı ise benzer.

Lafı daha fazla uzatmadan, bilgisayar kullanımı gündelik hayatımızın vazgeçilmez bir parçası konumunda peki, soru şu;

Bilgisayarımızda işimizi yapıyorsak veya bir adım ötesinde bu bilgisayar sistemi bizim geçim kaynağımız ise, üzerinde çalıştığımız veriler ne kadar kıymetli ?

Kaybetmek istemeyeceğimiz kadar şeklinde şahsım adına cevaplayabilirim.

Bir bilgisayar sisteminde veri kaybetmemek için fazla seçeneğimiz yok, bir şeyleri kısıtlamak veya kopyasını bulundurmak durumundayız. Veri Depolama sistemleri, yedekleme sistemleri, veri kurtarma gibi alt sektörler de bu ihtiyacın karşılığında ortaya çıkmış sektörler dersek eksik olur ama yanlış olmaz.

Veri Depolama yöntemleri ve Yedekleme sistemleri başka yazıların konuları o yüzden burada bırakıyorum, buradan bu konu hakkında yazdığım yazılara erişebilirsiniz, eğer yoksa merak etmeyin hazırlık aşamasındadır.

Bu yazı kimler için?

Meraklı ev ve ofis kullanıcıları ile ağırlıklı olarak ZFS nedir duymuş ama benim gibi kıyısından köşesinden incelemiş veya hiç incelememiş sistem yöneticileri için diyebilirim, bu yazıda ZFS dosya sisteminin bir bilgisayar sistemi üzerinde bize sunduklarına kısmen değineceğim.

İllaki RAIDZ ile 8 adet diski birbirine bağladığınız, PetaByte seviyesinde cluster yaptığınız üniteler olmak zorunda değil, bu yazıyı yazdığım dizüstü bilgisayar ile de bu dosya sisteminin avantajları kullanılabilir, ama nasıl?

Önceki yazılarımda Dosya Sistemi, ZFS, RAID, RAIDZ gibi kavramlara değinerek fiziksel bir sistemde ZFS dosya sistemi kullanılarak RAID uygulamalarından, ardından bir dökümana dayanarak hazırladığım installer scriptten bahsettim. Aşağıda paylaştığım linklerden bu yazıları inceleyebilirsiniz.


RAID ve RAIDZ yapılandırmaları


ZFS dosya sistemi üzerine İşletim Sistem Kurulumu

Veri kaybetmek istemiyoruz demiştik, peki ZFS bize bunu nasıl sunuyor ?

Versiyon Kontrol Sistemi (VCS) hakkında kısaca;

Yazılım geliştirmede versiyon kontrolü olarak nitelendirilen bir kavram vardır, hiçbir yazılım kusursuz değildir yalnızca birisi o kusuru tespit edip çıkarına kullandığı tespit edilene kadar farkına varılmaz, biz yazılım geliştiriciler için geliştirilen sistemlerden bir tanesine verilen isim “bug takip” sistemidir. Yazılımın kalite kontrol ve bakım süreçleri diye özetleyebiliriz. Versiyon ise geliştirdiğimiz yazılıma yeni bir özellik eklediğimizde veya hata tespiti sonrası hata giderdiğimizde hangi sürümde olduğumuzu, nerede olduğumuzu belirlememizi sağlar. Versiyon Kontrol Sistemi ise bir yazılımın geliştirilmeye başlanıldığı andan itibaren güncel sürüme kadar hangi adımda ne değişti sorularının cevaplarını almamızı sağlayan sistemdir.

Versiyon kontrolü ile bir yazılımı nasıl takip ediyorsak hareket özgürlüğümüz de o miktardadır. Yanlış bir adım atıp önceki geliştirmeleri silerek kopya, kopyanın kopyası … gibi bir yapıdan ziyade git bahsettiğim kavrama güzel bir örnektir, kavram olarak ZFS özelinde anlatacağım ve veri güvenliği noktasında üst seviyede işlevsel olan snapshot ve clone özellikleri versiyon kontrol sistemlerinin tanıttığına oldukça yakındır.

Yukarıdaki ekran görüntüsünde geliştirdiğim bir yazılımın basit versiyon gelişimi yer almakta, normalde tek bir zaman çizgisi bize üzerine eklenerek gidildiğini belirtirken, birden fazla zaman çizgisi ise aynı zaman diliminde aynı dosyanın farklı durumlarını işaret eder, versiyon kontrolünde buna branch ismi verilir ve bir ağacın dal yapısına benzetebiliriz.

Dikkat çekmek istediğim nokta: Dilediğimiz zaman o branch üzerindeki kod yapısına geri dönebileceğimiz gibi o noktadan başlangıç alıp yepyeni bir yapı da kurabiliriz.

Hangi konularda örnekleme yapacağımı belirtmeden önce ZFS üzerinde filesystem ve pool kavramlarını gözden geçirelim.

pool : sanal (vdev) veya fiziksel (dev) bir depolama aygıtını işaret eder.

filesystem : rpool/home/yasin/Deneme1 gibi herhangi bir pool içerisindeki bir dizini işaret eder.
Hangisini kullanayım ? filesystem ile dosya sistemi arasında gidip geliyordum ama zfs dizin yapısı şeklinde kullanacağım, birebir çeviri yapacak olursak dosya sistemi şeklinde çeviriliyor ancak o kullanım şekli terimsel olarak ana kavramı işaret ettiğinden kafa karıştıracaktır.

ZFS dizin yapısı şeklinde kullanacak olursak en azından ne şekilde kullanıldığı gözümüzde canlandırabiliriz. Yabancı kaynaklarda filesystem olarak göreceksiniz, kastettiği şey zfs create ile oluşturulan dizin yapısı.

Her pool bir zfs dizin yapısıdır ama her zfs dizin yapısı bir pool değildir ! Uygulamalarda olabildiğince iki taraf için de örnekleme yapmaya çalışacağım.

Yazımızın örnekleri ile içereceği uygulama alanları;

  1. zfs ve zpool sistem yönetim komutları ve alt komutları.
  2. zfs dizin yapısı ve pool oluşturma / yok etme işlemleri (create, destroy)
  3. zfs ile mantıksal disk birimleri oluşturmak (zvol)
  4. pool import ve export işlemleri
  5. zfs dizin yapısı ve pool için tanımlı dosya sistemi özelliklerini okuma ve değiştirme işlemleri (get, set)
  6. zfs dizin yapısı kullanıcı/grup yetkilendirmelerini açma ve kapama (allow, unallow)
  7. zfs dizin yapısı ve pool mount ve unmount işlemleri
  8. zfs dizin yapısı ve pool isim değiştirme (rename)
  9. zfs dizin yapısı bazlı kota yönetimi (quota)
  10. zfs dizin yapısı veri sıkıştırma (compression [gzip[1-9], lz4 …] )
  11. zfs dizin yapısı çoklu kopya tespiti ve engellenmesi (dedup)
  12. zfs dizin yapısı ve pool anlık görüntü alma ve geri yükleme (snapshot, rollback | checkpoint)
  13. zfs dizin yapısı klonlama işlemi (clone)
  14. Klonlanmış zfs dizin yapısı görüntüsünü zfs dizin yapısına yeni dal olarak dahil etmek (promote)
  15. Yazarken kopyalama (copy on write)
  16. Sürekli veri bütünlüğü kontrolü ve veri bozulmalarına karşı otomatik onarım (scrubbing)
  17. Mirror yapıdaki disklerde ayna kopyalama (resilver)
  18. Kriptolama (encryption)
  19. Uzak sunucu gönderme ve alma (send, receive)
  20. zfs dizin yapısı paylaşımı (share)

Sıfırdan makine kurmak istemeyen GNU / Linux Kullanıcısı arkadaşları unutmadım.

GNU / Linux Sistem Üzerinde ZFS Yönetimi İçin Temel Yapılandırma

Eğer sıfırdan bir sistem oluşturmadıysanız ama Linux kullanıcısıysanız ve bu örnekleri yapmak isterseniz iki adet paket kurulumu ile sisteminiz üzerinde zfs dosya sistemini yönetebilirsiniz.

Debian ve türevi sistemler üzerinde gdisk ve zfsutils-linux paketlerini kurarak yukarıdaki uygulamaların büyük kısmını test edebilirsiniz, apt dışındaki paket yöneticisine sahip dağıtımlarda da paketlerin isimleri benzerdir, root kullanıcı ileapt install gdisk zfsutils-linux, kurulum bittikten sonramodprobe zfs komutlarını vererek sistemimizde zfs dosya sistemine erişebileceğimiz uygulamaları ve modülleri kurmuş oluruz.

root olarak aşağıdaki komutu çalıştırın, zpool bash completion çalışması için önce zfs completion tetiklenmeli, bu sıkıntıyı gidermek için zfs dosyasını zpool completion olarak sisteme kopyalıyoruz, kirli ama hızlı çözüm 🙂

root@uxn-workstation:~# cd /usr/share/bash-completion/completions/

root@uxn-workstation:/usr/share/bash-completion/completions# cp zfs zpool

ZFS dosya sistemine sahip disk biçimlendirme adımları ilk yazımda mevcut ama burada tekrarlamış olalım.

Örneğimizdeki disk /dev/sdb olsun (kendi sisteminizde hangi diski kullanacaksanız o disk üzerinde işlemleri yapmalısınız!).

Disk üzerinde varsa label, disk yüzeyi ve partition yapısı temizleme işlemi.
root@debian:~# for i in $(lsblk grep -iPo "sdb[0-9]+"); do zpool labelclear -f "/dev/$i"; done
root@debian:~# wipefs -a /dev/sdb
root@debian:~# sgdisk --zap-all /dev/sdb
Disk GPT ve partition yapısı oluşturma işlemi.
root@debian:~# sgdisk -n1:0:0 -t1:BF00 "/dev/sdb"

Yukarıdaki temizlik ve zfs dizin yapısı oluşturma adımlarından sonra diskimizi kullanarak bir pool oluşturup üzerinden uygulamalarımızı yapabiliriz. 128GB Kingston (usb 3.0) flash diskimi test için kullanayım, usb 2.0 tavsiye edilmez.

root@zfs-mirror:~# zpool labelclear /dev/sde1 # eğer zfs part yoksa hata döner.
failed to clear label for /dev/sde1

root@zfs-mirror:~# wipefs -a /dev/sde
...

root@zfs-mirror:~# sgdisk --zap-all /dev/sde
...

root@zfs-mirror:~# lsblk /dev/sde 
NAME MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sde    8:64   1 115.2G  0 disk 

root@zfs-mirror:~# sgdisk -n1:0:0 -t1:BF00 "/dev/sde" 
...
The operation has completed successfully.

root@zfs-mirror:~# lsblk /dev/sde 
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sde      8:64   1 115.2G  0 disk 
└─sde1   8:65   1 115.2G  0 part 

root@zfs-mirror:~# blkid -s PARTUUID -o value /dev/sde1 
0957c154-86f9-45b8-b8dc-77cb3d8996ad

root@zfs-mirror:~# zpool create -f kingston128 0957c154-86f9-45b8-b8dc-77cb3d8996ad

Şahsen burada yapacağım işlemleri bir önceki yazımda kurulumunu yaptığım ZFS kök dosya sistemine sahip Debian Bullseye sistem üzerinden yapacağım.

1. zfs ve zpool Komutları ile Alt Komutları

Benim gibi gazete kuponu ile alınan ansiklopedi veya kitaplar veya arkadaşlar arasında değiş-tokuş edilen dökümanlar ile birlikte e-lapis, byte, chip gibi dergiler ve ekleri üzerinden eğitim görerek büyümüş arkadaşların vazgeçilmezi man komutu, en azından aklıma gelen ilk 3 seçenekten birisi her zaman man, Balıkesir Üniversitesi’nden Alp İmrek hocama saygılarımla, ilk öğreten 2001 yılında kendisidir.

man zfs-[TAB][TAB]

zfs komutları ile zfs dizin yapısı işlemlerini,
zpool komutları ile pool işlemlerini gerçekleştireceğiz. Bu komutları root kullanıcısı ile çalıştıracağız.

OpenZFS için hazırlanmış man dökümanlarının tümüne OpenZFS System Administration Commands sayfasından erişebilirsiniz, terminal üzerinden okumaktan daha kolay olacaktır.

zfs komutunun alt komutları aşağıdaki gibidir.

allow bookmark change-key clone create destroy diff get groupspace hold holds inherit list load-key mount program project projectspace promote receive redact release rename rollback send set share snapshot unallow unload-key unmount unshare upgrade userspace wait

Alt komutlar hakkında yardım almak istediğinizde zfs diff --help veya zfs diff -? bu şekilde hem komut kullanımı hem de o komuta hangi argümanları girmeliyiz bu bilgiye erişebiliriz. Terminal üzerinden manuel -e erişebilmek için man zfs-diff şeklinde girilmesi yeterlidir.

Kullanacaklarımızın kısa açıklamalarını yapalım.

Alt komutAçıklama
allowSistemdeki kullanıcılara zfs özellikleri ile ilgili yetki delegasyon verme işlemi.
unallowSistemdeki kullanıcılardan zfs özellikleri ile ilgili yetki delegasyon kaldırma işlemi.
createFilesystem oluşturmak için kullanılır.
destroyVar olan filesystem veya snapshot, bookmark yoketmek için kullanılır.
mountVar olana Filesystem için kendisi için ayarlanan dizine mount işlemi yapar.
unmountmount edilmiş Filesystem sistemden ayırılır.
getBelirtilen filesystem için istenilen özelliklerini getirir.
setBelirtilen filesystem için istenilen özelliklerini ayarlar.
listBelirtilen filesystem ve snapshot, bookmark gibi değerlerini listeler.
snapshotFilesystem üzerinde o ana ait anlık görüntü oluşturulur. (versiyon)
rollbackFilesystem üzerinde belirtilen anlık görüntüye geri döner. (versiyon)
cloneSeçilen snapshot üzerinden clone oluşturulur (branch)
diffİki snapshot arası veya snapshot ile güncel durum arası filesystem değişikliklerini listeler.
promoteClone alınan snapshot dosya sistemine yeni bir filesystem olarak eklenir.
renameFilesystem ismi değiştirilir.
sendFilesystem uzak sunucu zfs üzerine gönderilir.
receiveUzak sunucudaki filesystem yerel sisteme çekilir.

zpool komutunun alt komutları aşağıdaki gibidir.

add attach checkpoint clear create destroy detach events export get history import initialize iostat labelclear list offline online reguid remove reopen replace resilver scrub set split status sync trim upgrade wait
Alt komutAçıklama
listEkli pool listesi gösterilir.
statuspool durumları gösterilir
historyzpool komut geçmişi gösterilir
iostatHerbir pool için I/O istatistiği gösterilir.
eventsKernel tarafından pool için oluşturulan olaylar görüntülenir.
clearpool için kaydedilen hata durumları temizlenir.
labelclearpool üzerinde ekli fiziksel aygıtın ZFS etiket bilgisi silinir.
importpool ve içerdiği filesystem aktive edilir.
exportpool ve içerdiği filesystem devre dışı bırakılır.
addpool içerisine seri şekilde vdev eklenir
removepool içerisinden, seri şekilde eklenmiş vdev silinir.
attachpool içerisine mirror olarak vdev eklenir.
detachpool içerisine mirror olarak eklenmiş vdev ayırılır.
resilvermirror aygıtların ayna olanların tekrar eşitlenmesi sağlanır.
splitmirror olarak yapılandırılmış pool bölünerek yeni pool oluşturulur.
createYeni pool oluşturulur.
destroyVar olan pool yok edilir.
checkpointpool için güncel geri dönüş noktası oluşturulur.
getpool özellikleri getirilir.
setpool özellikleri set edilir.
onlinepool üzerindeki fiziksel aygıt online konuma getirilir.
offlinepool üzerindeki fiziksel aygıt offline konuma getirilir.
reguidpool eşsiz tanımlama bilgisi yeniden oluşturulur
replacepool üzerindeki aygıt bir diğeri ile değiştirilir.
scrubpool üzerinde dosya bütünlüğü kontrolü yapılır.
syncHatalı dosyaları pool içerisindeki ilk aygıta yazar.
trimpool üzerindeki aygıt üzerinde bulunan boş yüzeydeki data temizlenir.
waitpool aktifliği bitene kadar bekler.

Sonunda uygulama yapmaya başlayabiliriz…

2. zfs dizin yapısı ve pool oluşturma ve yok etme işlemleri (create, destroy)

İlk olarak zpool ile pool oluşturalım, ardından o pool içerisine zfs ile zfs dizin yapısı oluşturalım sonra ikisini de yok edelim.

zpool ile pool oluşturabilmek için bir adet bile olsa vdev ihtiyacımız var, önceki yazımda oluşturduğum VM üzerine 1 adet 4GB disk ekleyip uygulamamı yapacağım.

root@zfs-mirror:~# blkid -s PARTUUID -o value /dev/sdf1 
d285002f-09d4-4298-bf61-18cd1c923a18

root@zfs-mirror:~# zpool create newpool d285002f-09d4-4298-bf61-18cd1c923a18

root@zfs-mirror:~# zpool status newpool 
  pool: newpool
 state: ONLINE
config:

	NAME                                    STATE     READ WRITE CKSUM
	newpool                                 ONLINE       0     0     0
	  d285002f-09d4-4298-bf61-18cd1c923a18  ONLINE       0     0     0

errors: No known data errors

newpool isminde bir pool sisteme eklendi, bir pool oluştururken mountpoint özelliğini belirtmezsek / (kök) dizine pool ismi ile otomatik olarak bağlanıyor. Aşağıdaki komut çıktılarını incelediğimizde 4G diskimiz otomatik olarak /newpool klasörüne mount edilmiş durumda, mount-unmount örneğinde farklı dizine bağlanılması konusunun detayına girilecek.

root@zfs-mirror:~# zfs list newpool
NAME      USED  AVAIL     REFER  MOUNTPOINT
newpool   105K  3.62G       24K  /newpool

root@zfs-mirror:~# df -h /newpool/
Filesystem      Size  Used Avail Use% Mounted on
newpool         3.7G  128K  3.7G   1% /newpool

root@zfs-mirror:~# 

Burada oluşan newpool, pool yapısının kendisi, zfs create ile birlikte pool içerisine alt zfs dizin yapısı oluşturalım.

root@zfs-mirror:~# zfs create newpool/yasin
root@zfs-mirror:~# zfs create newpool/yasin/deneme1
root@zfs-mirror:~# zfs create newpool/yasin/deneme2
root@zfs-mirror:~# zfs create newpool/yasin/deneme3

root@zfs-mirror:~# zfs list newpool
NAME      USED  AVAIL     REFER  MOUNTPOINT
newpool   260K  3.62G       24K  /newpool

root@zfs-mirror:~# zfs list -r newpool
NAME                    USED  AVAIL     REFER  MOUNTPOINT
newpool                 260K  3.62G       24K  /newpool
newpool/yasin            98K  3.62G       26K  /newpool/yasin
newpool/yasin/deneme1    24K  3.62G       24K  /newpool/yasin/deneme1
newpool/yasin/deneme2    24K  3.62G       24K  /newpool/yasin/deneme2
newpool/yasin/deneme3    24K  3.62G       24K  /newpool/yasin/deneme3

root@zfs-mirror:~# 

zfs list komutunda -r argümanı herzamanki anlamda recursive.

create ve destroy komutlarında hiyerarşi herzaman gözetilmekte, örnekteki newpool/yasin/deneme1 zfs dizin yapısı oluşturulurken önce yasin ardından deneme1 oluşturuldu. Yok etme işleminde de aynı mantık geçerli -r argümanı kullanırsak en alt dizine kadar bütün zfs dizin yapısı yok edilecektir! dikkatli kullanın.

zfs destroy komutu ile zfs dizin yapısını yok edelim.

root@zfs-mirror:~# zfs list -r newpool
NAME                    USED  AVAIL     REFER  MOUNTPOINT
newpool                 260K  3.62G       24K  /newpool
newpool/yasin            98K  3.62G       26K  /newpool/yasin
newpool/yasin/deneme1    24K  3.62G       24K  /newpool/yasin/deneme1
newpool/yasin/deneme2    24K  3.62G       24K  /newpool/yasin/deneme2
newpool/yasin/deneme3    24K  3.62G       24K  /newpool/yasin/deneme3

root@zfs-mirror:~# zfs destroy newpool/yasin
cannot destroy 'newpool/yasin': filesystem has children
use '-r' to destroy the following datasets:
newpool/yasin/deneme1
newpool/yasin/deneme2
newpool/yasin/deneme3

root@zfs-mirror:~# zfs destroy newpool/yasin/deneme1

root@zfs-mirror:~# zfs list -r newpool
NAME                    USED  AVAIL     REFER  MOUNTPOINT
newpool                 239K  3.62G       24K  /newpool
newpool/yasin            74K  3.62G       26K  /newpool/yasin
newpool/yasin/deneme2    24K  3.62G       24K  /newpool/yasin/deneme2
newpool/yasin/deneme3    24K  3.62G       24K  /newpool/yasin/deneme3

root@zfs-mirror:~# zfs destroy -r newpool

root@zfs-mirror:~# zfs list -r newpool
NAME      USED  AVAIL     REFER  MOUNTPOINT
newpool   168K  3.62G       24K  /newpool

root@zfs-mirror:~# 

Yukarıdaki kodları incelediğinizde -r argümanı ne iş yapıyor algılanacaktır. zpool ile destroy işlemini de yaparsak pool ve zfs dizin yapısı create-destroy işlemlerimizi tamamlamış olacağız.

zpool destroy pool yokedelim.

root@zfs-mirror:~# zfs list -r newpool
NAME                    USED  AVAIL     REFER  MOUNTPOINT
newpool                 264K  3.62G       24K  /newpool
newpool/yasin            96K  3.62G       24K  /newpool/yasin
newpool/yasin/deneme1    24K  3.62G       24K  /newpool/yasin/deneme1
newpool/yasin/deneme2    24K  3.62G       24K  /newpool/yasin/deneme2
newpool/yasin/deneme3    24K  3.62G       24K  /newpool/yasin/deneme3

root@zfs-mirror:~# zpool destroy newpool 

root@zfs-mirror:~# zfs list -r newpool
cannot open 'newpool': dataset does not exist

root@zfs-mirror:~# 

Yukarıda zpool destroy komutu ile newpool yok edildi, komutlara dikkat edecek olursanız az önce zfs ile yok ettiğim zfs dizin yapılarını yeniden oluşturduğumu göreceksiniz, bir pool içerisinde ne olduğundan bağımsız olarak o pool yok edilirse içerisindeki veriler de gider ! dikkatli kullanın.


3. zfs ile mantıksal disk birimleri oluşturmak (zvol)

Hazırda rpool bizim sistemimizin kurulduğu pool, kendisi zfs dosya sistemine sahip. Peki bizim swap için disk alanına veya duruma göre ext4, ntfs, fat32, xfs … gibi dosya sistemlerini kullanma ihtiyacımız doğdu diyelim. Her seferine yeni disk alıp onu formatlayamayız değil mi… ZFS dosya sisteminde zvol ismi verilen volume management yapısı var hadi kullanalım.

İlk olarak sistemimde bir swap alanı yok, bu alanı oluşturayım. OpenZFS dökümanını kullanacağım, bu döküman içerisinde zfs dizin yapısı özellikleri belirtilerek işlem yapılmış, sonrasında daha da basite indirgeyerek örnekler yapmaya çalışacağım.

zfs create -V 4G -b $(getconf PAGESIZE) -o compression=zle \
    -o logbias=throughput -o sync=always \
    -o primarycache=metadata -o secondarycache=none \
    -o com.sun:auto-snapshot=false rpool/swap

Komut detaylarını ve -o argümanını ve alacağı parametreleri get-set kavramını anlatırken açıklayacağım. Yukarıdaki komutta odaklanmamız gereken argüman zfs create -V 4GB ... rpool/swap bu komut rpool üzerinde swap isminde 4GB alan kaplayan bir zfs dizin yapısı oluşturuyor, bunu diğerlerinden ayıran şey /dev/zdX veya /dev/zvol/rpool/swap şeklinde sanki sisteme takılı bir disk aygıtıymış gibi görebiliyor oluşumuz, üzerinde fdisk çalıştırabileceğimiz manasına geliyor. Bu şekilde dilediğimiz kadar mantıksal birim oluşturup dilediğimiz şekilde kullanabiliriz demek oluyor.

root@zfs-mirror:~# ls -l /dev/zvol/rpool/swap 
lrwxrwxrwx 1 root root 9 Mar 29 18:39 /dev/zvol/rpool/swap -> ../../zd0

root@zfs-mirror:~# lsblk /dev/zd0 
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
zd0  230:0    0   4G  0 disk 

root@zfs-mirror:~# fdisk -l /dev/zd0 
Disk /dev/zd0: 4 GiB, 4294967296 bytes, 8388608 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

root@zfs-mirror:~# 

Swap alanımız için mantıksal birimi (zvol) oluşturduk, sırada biçimlendirmek ve swap alanı olarak sisteme eklemek var.

Dikkat ! /dev/sdX yapısındaki disk isimleri her sistem açılışında değiştiğini daha önceden belirtmiştik bu sebepten disk-id, path-name, partuuid, uuid gibi sistem yeniden başladığında değişmeyen isimlendirmeler kullanmaya dikkat etmek zorundayız, /dev/zdX için de durum benzer. Bu sebepten full path yani /dev/zvol/rpool/swap kullanacağız.

# zvol ile oluşturduğumuz birimi swap olarak ekliyoruz
mkswap -f /dev/zvol/rpool/swap

Setting up swapspace version 1, size = 4 GiB (4294963200 bytes)
no label, UUID=bb2eaccf-357f-406b-b9a6-9587d39378f6

# /etc/fstab içerisine swap alanımızı ekliyoruz, sistem açlışında otomatik mount edilebilsin.
echo /dev/zvol/rpool/swap none swap discard 0 0 >> /etc/fstab

# pool fstab işlendiğinde aktif olmadığından hazırda bekleme konumundan çıkmayı başaramayacağından RESUME=none değeri initramfs ekleniyor.
echo RESUME=none > /etc/initramfs-tools/conf.d/resume

swapon -av
swapon: /dev/zd0: found signature [pagesize=4096, signature=swap]
swapon: /dev/zd0: pagesize=4096, swapsize=4294967296, devsize=4294967296
swapon /dev/zd0

free -h
               total        used        free      shared  buff/cache   available
Mem:           3.8Gi       782Mi       2.9Gi       2.0Mi       164Mi       2.9Gi
Swap:          4.0Gi          0B       4.0Gi

root@zfs-mirror:~# 

zfs root dosya sistemi üzerinde zvol kullanarak hazırladığımız swap alanımız hazır ve kullanılır durumda.

Uygulama olarak Fat32, NTFS, ext4 içeren yeni mantıksal birimler oluşturup sisteme bağlayalım. Yukarıda da belirttiğim gibi bu dosya sistemlerinde belirli özellikleri açıp kapatmamız gerekiyor, şimdilik oluşturacağım zfs get-set kısmında ise detaylandıracağım.

İlk örneğimde 1GB boyutunda mantıksal birim oluşturup bu birimi fdisk kullanarak bölümleyip FAT32 olarak formatlayacağım. İşlem adımları aşağıdaki gibidir.

zfs create -s -V 4G newpool/fat1G

mkfs.fat /dev/zvol/newpool/fat1G 
mkfs.fat 4.2 (2021-01-31)

mount -t vfat /dev/zvol/newpool/fat1G /mnt/

mount | grep /mnt
/dev/zd16 on /mnt type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro)

umount /mnt

Yukarıdaki komutu biraz açalım;

zfs create hali hazırda zfs dizin yapısı oluşturmak için kullandığımız komut.

-s argümanı sparse yani otomatik genişleyen, disk üzerinde tek seferde belirtilen alanı rezerve etmeyen alan ayır manasına geliyor, alanımız kıstlı değilse -s kullanmadan da devam edebiliriz.

-V volume (mantıksal bölüm) alanı ne kadar olacak onu belirtiyor

ardından hangi pool üzerinde yer alacak, ismi ne olacak onu belirtiyoruz ve mantıksal bölümümüz hazır.

mkfs.fat komutu ile bölümümüzü vfat formatlıyoruz.

mount -t vfat komutu ile mantıksal bölümümüzü /mnt dizinine mount ediyoruz. Dilersek partuuid bilgisini okuyarak fstab içerisine de bu bölümü ekleyip sistem açılışında kullanılabilir hale getirebiliriz.

Sonraki örneklerde fstab ve sistem üzerinde mount kısmına zfs mount ile karışmaması için değinmeyeceğim, sadece gerçek bir disk gibi yönetebileceğimizi örneklemek istedim.

NTFS Mantıksal Bölüm oluşturalım.

zfs create -s -V 1G newpool/ntfs1G

mkfs.ntfs /dev/zvol/newpool/ntfs1G 
Cluster size has been automatically set to 4096 bytes.
Initializing device with zeroes: 100% - Done.
Creating NTFS volume structures.
mkntfs completed successfully. Have a nice day.

mount.ntfs /dev/zvol/newpool/ntfs1G /mnt/ntfs/

ext4 Mantıksal Bölüm oluşturalım

zfs create -s -V 1G newpool/ext4-1G

mkfs.ext4 /dev/zvol/newpool/ext4-1G 
mke2fs 1.46.2 (28-Feb-2021)
Discarding device blocks: done                            
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: 26e4b8bd-31a7-4902-8439-6e1eb8bb4d71
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

mount /dev/zvol/newpool/ext4-1G /mnt/ex4

4. pool import ve export işlemleri

Kısaca özetlemek gerekirse oluşturulan pool ve içerisindeki zfs dizin yapısına “ihtiyaç varsa argümanlar” ile dahil edilir (import) veya sistemde aktif durumdaki pool sistemden sökülür (export)

“İhtiyaç varsa argümanlar” şeklinde belirtmemin sebebini mount,unmount ve checkout örneklerinde göstereceğimden bu başlık altında sadece import ve export işlemini gerçekleştireceğim.

zpool import

newpool isminde bir pool oluşturmuştuk, kingston128 isminde de bir pool oluşturmuştum, kök dizinimde ise rpool mevcuttu, rpool haricinde hangisi olursa olsun sistemden çıkartıp sisteme ekleyebiliriz. Örneklemeyi tam yapabilmek için ben flashdisk üzerinde tuttuğum kingston128 isimli pool üzerinden gideceğim. kingston128 üzerinde test için zfs dizin yapısı oluşturdum ve şu anda sistemin dışında.

Sisteme import edelim

yalnızca zpool import komutunu verecek olursak karşımıza sisteme dahil edilmemiş pool listesini dökecektir. kingston128 şu anda karşımızda. pool ismi (kingston128) veya id bilgisi ile import işlemini gerçekleştirebiliriz.

import işleminden sonra zfs list -r kingston128 yazarak içerisindeki zfs dizin yapısını alt dizinleri ile birlikte listeleyebiliriz.

zpool export kingston128 komutu ile pool sistemden ayrılacaktır (eğer sistem üzerinde bu dizinlerden birinde işlem yapan bir uygulama yoksa!)

Farklı bir dizine import etmek için komutumuz zpool import -N -R <poolname> şeklinde
-N pool içerisindeki hiçbir zfs dizin yapısı mount edilmesin
-R pool için cachefile özelliğini kapat, belirtilen dizine bağlan.
Bu komut işlendikten sonra pool import edilir ancak içerisindeki dosyaları mount etmeden erişemeyiz. zfs mount kingston

pool import ve export işlemleri bu şekilde, şimdi de get-set ile özelliklerimizi görelim ve düzenleyelim.


5. zfs dizin yapısı ve pool için tanımlı dosya sistemi özelliklerini okuma ve değiştirme işlemleri (get, set)

Aslına bakarsanız, ZFS üzerine şimdiye kadar yazdığım bu yazı ile birlikte 3 yazının amacı, aşağıdaki 2 tablonun kısmi açıklamalarını yapabilmek…

zfs get yazıp Enter bastığımızda karşımıza get alt komutunun alabileceği değerler çıkacaktır, bu değerler set için de aynen kullanılabilmekte.

Aşağıdaki tablodan zfs dizin yapısı özelliklerini inceleyebilirsiniz, zfs dizin yapısı üzerinde hangi özelliklere sahibiz, hangilerini değiştirebiliriz hepsini görebiliyoruz.

Bu link üzerinden, zfs özelliklerinin tam listesi ve açıklamalarına erişebilirsiniz.


PROPERTYEDITINHERITVALUES
availableNONO
clonesNONO[,...]
compressratioNONO<1.00x or higher if compressed>
createtxgNONO
creationNONO
defer_destroyNONOyes | no
encryptionrootNONO
filesystem_countNONO
guidNONO
keystatusNONOnone | unavailable | available
logicalreferencedNONO
logicalusedNONO
mountedNONOyes | no
objsetidNONO
originNONO
receive_resume_tokenNONO
redact_snapsNONO[,...]
refcompressratioNONO<1.00x or higher if compressed>
referencedNONO
snapshot_countNONO
typeNONOfilesystem | volume | snapshot | bookmark
usedNONO
usedbychildrenNONO
usedbydatasetNONO
usedbyrefreservationNONO
usedbysnapshotsNONO
userrefsNONO
writtenNONO
aclinheritYESYESdiscard | noallow | restricted | passthrough | passthrough-x
aclmodeYESYESdiscard | groupmask | passthrough | restricted
acltypeYESYESoff | nfsv4 | posix
atimeYESYESon | off
canmountYESNOon | off | noauto
casesensitivityNOYESsensitive | insensitive | mixed
checksumYESYESon | off | fletcher2 | fletcher4 | sha256 | sha512 | skein | edonr
compressionYESYESon | off | lzjb | gzip | gzip-[1-9] | zle | lz4 | zstd | zstd-[1-19] | zstd-fast-[1-10,20,30,40,50,60,70,80,90,100,500,1000]
contextYESNO
copiesYESYES1 | 2 | 3
dedupYESYESon | off | verify | sha256[,verify] | sha512[,verify] | skein[,verify] | edonr,verify
defcontextYESNO
devicesYESYESon | off
dnodesizeYESYESlegacy | auto | 1k | 2k | 4k | 8k | 16k
encryptionNOYESon | off | aes-128-ccm | aes-192-ccm | aes-256-ccm | aes-128-gcm | aes-192-gcm | aes-256-gcm
execYESYESon | off
filesystem_limitYESNO | none
fscontextYESNO
keyformatNONOnone | raw | hex | passphrase
keylocationYESNOprompt | file:///absolute/file/path | https://address | http://address
logbiasYESYESlatency | throughput
mlslabelYESYES
mountpointYESYES | legacy | none
nbmandYESYESon | off
normalizationNOYESnone | formC | formD | formKC | formKD
overlayYESYESon | off
pbkdf2itersNONO
primarycacheYESYESall | none | metadata
quotaYESNO | none
readonlyYESYESon | off
recordsizeYESYES512 to 1M, power of 2
redundant_metadataYESYESall | most
refquotaYESNO | none
refreservationYESNO | none
relatimeYESYESon | off
reservationYESNO | none
rootcontextYESNO
secondarycacheYESYESall | none | metadata
setuidYESYESon | off
sharenfsYESYESon | off | NFS share options
sharesmbYESYESon | off | SMB share options
snapdevYESYEShidden | visible
snapdirYESYEShidden | visible
snapshot_limitYESNO | none
special_small_blocksYESYESzero or 512 to 1M, power of 2
syncYESYESstandard | always | disabled
utf8onlyNOYESon | off
versionYESNO1 | 2 | 3 | 4 | 5 | current
volblocksizeNOYES512 to 128k, power of 2
volmodeYESYESdefault | full | geom | dev | none
volsizeYESNO
vscanYESYESon | off
xattrYESYESon | off | dir | sa
zonedYESYESon | off
userused@...NONO
groupused@...NONO
projectused@...NONO
userobjused@...NONO
groupobjused@...NONO
projectobjused@...NONO
userquota@...YESNO | none
groupquota@...YESNO | none
projectquota@...YESNO | none
userobjquota@...YESNO | none
groupobjquota@...YESNO | none
projectobjquota@...YESNO | none
written@NONO
written#NONO

zpool get

Aşağıdaki tablodan zpool pool özelliklerini inceleyebilirsiniz.

Bu link üzerinden, zpool özelliklerinin tam listesi ve açıklamalarına erişebilirsiniz.


PROPERTYEDITVALUES
allocatedNO
capacityNO
checkpointNO
dedupratioNO<1.00x or higher if deduped>
expandsizeNO
fragmentationNO
freeNO
freeingNO
guidNO
healthNO
leakedNO
load_guidNO
sizeNO
altrootYES
ashiftYES
autoexpandYESon | off
autoreplaceYESon | off
autotrimYESon | off
bootfsYES
cachefileYES | none
commentYES
delegationYESon | off
failmodeYESwait | continue | panic
listsnapshotsYESon | off
multihostYESon | off
readonlyYESon | off
versionYES
feature@...YESdisabled | enabled | active

zvol kısmında bu başlığa atıfta bulunmuştum,

Hadi, ihtiyacımız olan özellikleri kontrol edelim, görelim, değiştirelim.

creation

zfs get creation <poolname/filesystemName/…>

mountpoint

zfs get -r mountpoint <poolname/filesystemName/...>

zfs get -r mountpoint kingston128/ysn.app
NAME                         PROPERTY    VALUE                         SOURCE
kingston128/ysn.app          mountpoint  /kingston128/ysn.app          local
kingston128/ysn.app/deneme1  mountpoint  /kingston128/ysn.app/deneme1  local

zfs list -r kingston128/ysn.app
NAME                          USED  AVAIL     REFER  MOUNTPOINT
kingston128/ysn.app            48K   111G       24K  /mnt/ysn.app
kingston128/ysn.app/deneme1    24K   111G       24K  /mnt/ysn.app/deneme1
canmount
guid
Çoklu özellik gösterimi.

Buraya kadar zfs get ve set ile temelde zfs dizin yapısı yapısı üzerinde ne gibi özelliklerin ayarlanabileceğini gördük.

Şimdi pool üzerinde zpool get ve set işlemlerinden örnekler yapalım.

zpool get autoexpand, autotrim, capacity, failmode, guid, checkpoint, health, multihost, fragmentation kingston128
readonly pool

6. zfs dizin yapısı kullanıcı/grup yetkilendirmelerini açma ve kapama (allow, unallow)

zfs allow <filesystem>

Komutu ile bir zfs dizin yapısı üzerinde kullanıcıya verilmiş hak varsa listelenecektir, allow komutu Linux sistemler üzerinde yalnızca root yetki alanıyla sınırlı olduğundan mount, unmount, mountpoint, canmount, rename, ve share alt komutlarını desteklenmemektedir, delege edilemez.

Örneğin casesensivity özelliğinin yetkilerini kullanıcıya verelim.

İlk olarak kingston128 pool mount yerini yasin kullanıcısının ev dizini yapıp sahipliğini yasin kullanıcısına aktarıyorum.

zfs unmount kingston128
zfs set mountpoint=/home/yasin/kingston128 kingston128
zfs mount kingston128
chown -R yasin:yasin /home/yasin/kingston128/

casesensivity özelliğini yasin kullanıcısına delege edelim ve büyük-küçük harf duyarsız (insensitive) bir zfs dizin yapısı oluşturalım.

Eğer zfs dizin yapısı bir kullanıcıya aktarılacaksa sahipliği chown ile kendisine verilmeli.

zfs allow -g yasin casesensitivity kingston128/ysn.app

zfs allow kingston128/ysn.app
---- Permissions on kingston128/ysn.app ------------------------------
Local+Descendent permissions:
	group yasin casesensitivity
    
zfs create -o casesensitivity=insensitive kingston128/case-test

chown -R yasin:yasin /home/yasin/kingston128/

case-test dizininde ve yasin dizininde a ve A isimli iki adet dosya oluşturmayı deneyelim.

Sonuç ekran görüntüsündeki gibi, peki yasin kullanıcısı ile casesensitivity özelliğini değiştirmeyi deneyelim.

casesensitivity özelliği readonly, yani değiştirilemez, zfs dizin yapısı oluşturulurken atanması gereken özelliklerden, sonradan değiştirilemiyor. “Yukarıdaki tabloda EDIT sütunu No yazanlar readonly property ve değiştirilemez sınıfta.”

yasin@zfs-mirror:~/kingston128$ touch readonly-test/a
touch: cannot touch 'readonly-test/a': Read-only file system

yasin@zfs-mirror:~/kingston128$ /sbin/zfs set readonly=off kingston128/readonly-test
cannot mount 'kingston128/readonly-test': Insufficient privileges
property may be set but unable to remount filesystem

#------------------
# root olarak unmount & mount işlemi
zfs unmount kingston128/readonly-test
zfs mount kingston128/readonly-test
chown -R yasin:yasin /home/yasin/kingston128/
#------------------

yasin@zfs-mirror:~/kingston128$ touch readonly-test/a

yasin@zfs-mirror:~/kingston128$ ls -l readonly-test/
total 1
-rw-r--r-- 1 yasin yasin 0 Mar 30 07:34 a

yasin@zfs-mirror:~/kingston128$ 

Belirli yetkileri kullanıcılara verebiliyoruz ama tespit ettiğim kadarıyla yetkiler büyük oranda mount ve unmount işlemi ile göbekten bağlı olduğundan kullanıcı bir özelliği değiştirse dahi etkinleştirmesi için sistem yöneticisi arkadaşı rahatsız etmek durumunda 🙂

zfs unallow <filesystem>

Yukarıdaki komut ise bir zfs dizin yapısı üzerinde kullanıcıya delege edilmemiş yetkileri listeler.

Bir zfs dizin yapısı altında kullanıcıya verilmiş yetkilerin tümünü devre dışı bırakalım.

zfs unallow -g yasin -r kingston128

zfs allow kingston128
---- Permissions on kingston128 --------------------------------------
Local+Descendent permissions:
	user yasin readonly
    
zfs unallow -u yasin -r kingston128

Yetkiyi -g ile gruba verdiysek temizlerken tekrar -g belirtmemiz gerekiyor, -u ile kullanıcıya verdiysek -u kullanarak kullanıcıyı belirtmemiz gerekiyor…


7. zfs dizin yapısı ve pool mount ve unmount işlemleri

zfs ve zpool create kısmında “mountpoint” ile ilgili bir konuya işaret etmiştim, mount-unmount kısmında işleneceğini söylemiştim. get-set başlığında nasıl yapıldığını öğrendik, burada uygulayalım.

zfs set mountpoint=/absolute/path/of/filesystem <poolname/filesystemName/...>

mkdir /mnt/ysn.app

zfs set mountpoint=/mnt/ysn.app kingston128/ysn.app

zfs get -r mountpoint kingston128/ysn.app
NAME                         PROPERTY    VALUE                         SOURCE
kingston128/ysn.app          mountpoint  /kingston128/ysn.app          local
kingston128/ysn.app/deneme1  mountpoint  /kingston128/ysn.app/deneme1  local

zfs list -r kingston128/ysn.app
NAME                          USED  AVAIL     REFER  MOUNTPOINT
kingston128/ysn.app            48K   111G       24K  /mnt/ysn.app
kingston128/ysn.app/deneme1    24K   111G       24K  /mnt/ysn.app/deneme1

zfs unmount kingston128

8. zfs dizin yapısı ve pool isim değiştirme (rename)

ZFS dizin yapısı ve Pool ismini değiştirmek için rename alt komutu.

zfs rename ile kingston128 pool içerisindeki readonly-test zfs dizin yapısı readonly olarak yeniden adlandıralım.

zfs rename kingston128/readonly-test kingston128/readonly

zpool ile kingston128 pool ismimizi kingston olarak yeniden adlandıralım. Bir pool oluşturuldukan sonra yeniden import ederken zpool import <oldname> <newname> şeklinde import edip, mountpoint değiştirilmesi yeterli. doğrudan rename alt komutu yok.

zpool export kingston128 
zpool import kingston128 kingston
zfs set mountpoint=/home/yasin/kingston kingston
zpool export kingston
zpool import kingston

9. zfs dizin yapısı bazlı kota yönetimi (quota)

Tek komutla bir zfs dizin yapısı için kota belirlenebilmekte.

zfs set quota=1G newpool/quota

zfs create newpool/quota

zfs list newpool/quota
NAME            USED  AVAIL     REFER  MOUNTPOINT
newpool/quota    24K  2.57G       24K  /newpool/quota

zfs set quota=1G newpool/quota

zfs list newpool/quota
NAME            USED  AVAIL     REFER  MOUNTPOINT
newpool/quota    24K  1024M       24K  /newpool/quota

dd if=/dev/urandom of=/newpool/quota/img bs=1M count=1024 status=progress
1070596096 bytes (1.1 GB, 1021 MiB) copied, 23 s, 46.4 MB/s
dd: error writing '/newpool/quota/img': Disk quota exceeded
1024+0 records in
1023+0 records out
1073086464 bytes (1.1 GB, 1023 MiB) copied, 23.3475 s, 46.0 MB/s

dd if=/dev/urandom of=/newpool/quota/img1 bs=1M count=1 status=progress
dd: failed to open '/newpool/quota/img1': Disk quota exceeded

Eğer bir sistem kullanıcısı için bir zfs dizin yapısı üzerinde kota uygulayacaksak;

zfs set userquota@yasin=10G rpool/home/yasin

Sistem kullanıcısı için zfs dizin yapısı üzerinde tanımlı kotayı görüntüleyeceksek;

zfs userspace rpool/home/yasin

zfs set userquota@yasin=10G rpool/home/yasin

zfs userspace rpool/home/yasin
TYPE        NAME    USED  QUOTA  OBJUSED  OBJQUOTA
POSIX User  root    512B   none        1      none
POSIX User  yasin  51.6M    10G    1.87K      none

10. Dosya sistemi veri sıkıştırma (compression-[gzip[1-9],-lz4-…]-)

lz4 sıkıştırma algoritması varsayılan olarak gelmekte, sıkıştırma oranı yükseldikçe performans kaybedeceğimizi, sıkıştırma hızı yüksek algoritmalarda da disk alanı kaybedeceğimizi unutmayalım.

gzip-[1,6,9] | lz4 | lzjb | zle algoritmaları arasında kıyaslama yaptım.

OpenZFS üzerinde desteklenen tüm sıkıştırma algoritmaları:
gzip
| gzip-N | lz4 | lzjb | zle | zstd | zstd-N | zstd-fast | zstd-fast-N

zfs set compression=gzip-[1-9] rpool/home/yasin/compression-test/gzip...
zfs create rpool/home/yasin/compression-test/gzip-1

zfs create rpool/home/yasin/compression-test/gzip-6\ std

zfs create rpool/home/yasin/compression-test/gzip-9

zfs create rpool/home/yasin/compression-test/lz4

zfs create rpool/home/yasin/compression-test/lzjb

zfs create rpool/home/yasin/compression-test/zle
zfs set compression=gzip-1 rpool/home/yasin/compression-test/gzip-1

zfs set compression=gzip rpool/home/yasin/compression-test/gzip-6\ std

zfs set compression=gzip-9 rpool/home/yasin/compression-test/gzip-9

zfs set compression=lzjb rpool/home/yasin/compression-test/lzjb

zfs set compression=zle rpool/home/yasin/compression-test/zle

du -s /home/yasin/compression-test/gzip-1/
23117	/home/yasin/compression-test/gzip-1/

du -s /home/yasin/compression-test/gzip-6\ std/
22885	/home/yasin/compression-test/gzip-6 std/

du -s /home/yasin/compression-test/gzip-9
22881	/home/yasin/compression-test/gzip-9

du -s /home/yasin/compression-test/lz4/
23481	/home/yasin/compression-test/lz4/

du -s /home/yasin/compression-test/lzjb/
24465	/home/yasin/compression-test/lzjb/

du -s /home/yasin/compression-test/zle/
25769	/home/yasin/compression-test/zle/

ext4 altında 25839K tutan veri, gzip-9 ile 22881K alan kaplamakta.

compressratio

zfs dizin yapısında sıkıştırma oranı bilgisine ulaşabileceğimiz özellik.


11. zfs dizin yapısı çoklu kopya tespiti ve engellenmesi (dedup)

Deduplication (Tekilleştirme / Çoklamayı engelleme) kısaltması dedup zfs dizin yapısı üzerinde aynı dosyanın çoklu kopyalarının oluşup boş yere depolama alanını işgal etmesinin önüne geçen bir özellik.

zfs ile yeni bir zfs dizin yapısı oluşturup dedup özelliğini aktif edip aynı dosyanın kopyalarını oluşturarak testimizi yapalım.

zfs create rpool/home/yasin/dedup

chown -R yasin:yasin /home/yasin/

zfs set dedup=on rpool/home/yasin/dedup

veya istersek zfs dizin yapısını oluşturma aşamasında özelliği aktifleştirelim, aklıma gelmişken gzip-1 sıkıştırmayı da etkinleştirerek bu işi yapayım. Alıştırma olsun.

zfs create \
-o dedup=on \
-o compression=gzip-1 \
rpool/home/yasin/dedup

chown -R yasin:yasin /home/yasin/

zfs get dedup,compression rpool/home/yasin/dedup
NAME                    PROPERTY     VALUE           SOURCE
rpool/home/yasin/dedup  dedup        on              local
rpool/home/yasin/dedup  compression  gzip-1          local

dedup özelliğini zfs dizin yapısı için açıyor olsakta pool genelinden takip edilen bir özelliktir, aşağıda işaretli alanda DEDUP başlığı (zpool get dedupratio) bize pool içerisinde çoklu dosyaların oranını verecektir.
1.00x herhangi bir duplication yok. üst değerler ise pool içerisindeki dosya sistemlerinde oluşan duplicated oranıdır.

İşleme başlamadan önce dedup zfs dizin yapısını barındıran rpool özellikleri ve kapasite bilgileri aşağıdaki gibi.

Test için dedup zfs dizin yapısında 10 adet klasör oluşturacağım ve içerisine urandom tarafından üretilmiş 100M boyutundaki dosyayı her bir klasöre kopyalayacağım. 100M ismindeki dosyanın 10 adet kopyasını dedup özelliği aktif olan dizin içerisine! çoklamış olacağız.

cd /home/yasin
dd if=/dev/urandom of=100M bs=1M count=100

for i in $(seq 1 10); do mkdir dedup/$i; cp 100M dedup/$i; done

Şimdi rpool bilgilerine ve toplam kapasite bilgilerine bir daha bakalım.

İlk oluşturulan dosya diskte yer kaplıyor hali hazırda diyerekten ZFS dosya sistemi dedup özelliği açık olan dosya sistemlerinde aynı dosyayı kullanıyor 🙂 normalde 1000MB ilave olarak alan kıllanması gerekiyordu, bu dosyalar için dedup zfs dizin yapısında 1000M rezerve ediliyor ancak toplam kapasiteye herhangi bir etkisi bulunmamakta…


12. zfs dizin yapısı ve pool anlık görüntü alma ve geri yükleme (snapshot, rollback | checkpoint)

Ve geldik en sevdiğim dosya sistemi özelliğine snapshot. Bu özellik sayesinde dosya sistemimizi aynı bir versiyon kontrol sistemi gibi yönetebilmekteyiz. Yazının başında kısaca versiyon kontrol sistemine değinmemdeki asıl amaç tam olarak burasıydı.

snapshot bir zfs dizin yapısının o anki konumuna ait bir geri dönüş noktası oluşturur. Birden fazla oluşturulabilir.

rollback bir zfs dizin yapısı için alınan snapshot üzerinden o anki durumuna geri dönülmesini sağlar.

zfs destroy poolname/filesystemName/subFilesystem@snapshotID komutuyla snapshot silinir.

checkpoint Bir pool için geri dönüş noktası oluşturur. Yalnızca 1 adet oluşturulabilir.

zpool import <poolname> --rewind-to-checkpoint Bu komut ile seçilen pool checkpoint noktasından geri yükler.

Sırasıyla uygulamalarımızı yapalım.

Bir uygulamada tüm yolu kat edelim. Senaryom şu şekilde, yukarıda dedup anlatırken oluşturduğum zfs dizin yapısı içerisinde 10 adet dizin ve her birinde 100M boyutunda imaj dosyam var, compression isimli zfs dizin yapısında da Blog için hazırladığım veya hazırlayacağım yazıların geçmişte yaptığım ve not aldığım uygulamaları, dökümanları mevcut.

  1. zfs dizin yapılarının snapshot alımı.
  2. dizin içeriklerini yer değiştirmek.
  3. dosyaların birkaçını silmekç
  4. zfs dizin yapısının snapshot noktasına geri döndürmek.

İlk olarak zfs dizin yapılarımın snapshot işlemi.

zfs snapshot rpool/home/yasin/dedup@ilk
zfs snapshot rpool/home/yasin/compression-test@ilk

snapshot alırken zfs snapshot poolName/zfs/dizin/yapısı@snapshotName

komutu ile işlemi gerçekleştiriyoruz. Belirtilen zfs dizin yapısı altındaki her bir dizin için recursive olarak bu işlemi yapmak istersek zfs snapshot -r argümanı ile komut vererek bunu yapabiliriz.

Burada değinmek istediğim bir nokta var, dedup dizini zfs create komutu ile oluşturduğumuz bir zfs dizin yapısı, compression-test dizini de aynı şekilde ancak dedup dizini içerisindeki diğer dizin ve dosyaları elle oluşturduk, diğer taraftan compression-test dizini altındaki dizinleri de zfs create komutu ile zfs dizin yapısı olarak oluşturduk.

ZFS dizin yapısı olarak oluşturulan bir dizin yalnızca kendi altında elle oluşturulan dizin ve dosyaların, verilerin bağlam noktasıdır, bu dizin altında oluşturduğumuz zfs dizin yapısı da aynı şekilde kendi bağlam noktasının altında oluşturulan dizin ve dosyalardan sorumludur. Bu şu demek oluyor;

Bir zfs dizin yapısına ait snapshot alırsak yalnızca bu dizine ait elle oluşturulmuş dizin ve dosyaları için geri dönüş noktası oluşturmuş oluruz!

compression-test örneğimizin altında farklı sıkıştırma algoritmalarına sahip şekilde oluşturduğumuz zfs dizin yapıları, compression-test zfs dizin yapısına ait bağlam noktası tarafından izlenmez, alt kademe zfs dizin yapıları olan gzip-1, gzip-6 std, gzip-9 … zfs dizin yapıları için ayrıca snapshot alınması gerekmektedir.

Yukarıdaki ekran görüntüsündeki gibi -r argümanı ile recursive şekilde alt kademede bulunan zfs dizin yapıları için de snapshot alındı. Artık gönül rahatlığı ile dosyalarımızı silip yerlerini değiştirebiliriz, ne de olsa geri dönüş noktamız var.

Sıradaki adım zfs dizin yapısı içerisindeki birkaç verinin yerini değiştirmek ve yeni snapshot alımı.

# root kullanıcısı ile
cd /home/yasin/dedup
mv 1 2 3 4 5 ../compression-test/
mv ../compression-test/gzip-1/* .
rm -rf 9/ 10/ ../compression-test/gzip-9/ ../compression-test/lzjb/
	rm: cannot remove '../compression-test/gzip-9/': Device or resource busy
	rm: cannot remove '../compression-test/lzjb/': Device or resource busy
rm -f ../compression-test/compression-arguments

Yukarıdaki örneklemede dikkatimizi hemen çekmiştir, root olmamıza rağmen zfs dizin sistemini silemedik 🙂 sebebi her bir zfs dizin yapısı sistemde bir mount değerine sahiptir ve dosya kullanımda olduğu sürece mount sonlandırılamaz dolaylı olarak silemezsiniz. zfs destroy ile bu işlemi yapmak zorundasınız.

dedup dizinimizi snapshot noktasına geri döndürelim.

zfs rollback rpool/home/yasin/dedup@ilk

compression-test dizinimizi snapshot noktasına geri döndürelim.

zfs rollback rpool/home/yasin/compression-test@recursive

compression-test zfs dizin yapımızın ilk hali yukarıdaki gibi, gzip-1 dizininin içeriği boş durumda yani compression-test geri yüklendi ancak alt dizin yüklenemedi, şimdi tüm alt dizinler ile birlikte sırasıyla geri yükleyelim.

zfs rollback rpool/home/yasin/compression-test/gzip-1@recursive 
zfs rollback rpool/home/yasin/compression-test/gzip-6\ std@recursive 
zfs rollback rpool/home/yasin/compression-test/gzip-9@recursive 
zfs rollback rpool/home/yasin/compression-test/lz4@recursive 
zfs rollback rpool/home/yasin/compression-test/lzjb@recursive 
zfs rollback rpool/home/yasin/compression-test/zle@recursive

Bir zfs dizin yapısı üzerinde birden çok snapshot alınabilir demiştik, bu snapshotlar üzerinde rollback veya destroy işlemi uygulayacaksak sıralamayı takip etmek durumundayız, 3 adet snapshot varsa doğrudan ilk aldığımıza rollback yapamayız demek oluyor. Bu gibi durumlarda clone ile geriye dönmek istediğimiz noktanın klonunu çıkartıp orada işlem yapmamız gerekir.

İlave bilgi olarak zfs set snapshot_limit=7 rpool/home/yasin/dedup gibi bir komut ile bir zfs dizin yapısına ait alınabilecek snapshot sayısını sınırlayabiliriz.

ZFS snapshot ve rollback buraya kadar. Bir sonraki örneğimiz pool için oluşturduğumuz checkpoint.

pool için geri dönüş noktası oluşturmayı 12. başlığın ilk satırlarında nasıl geri dönülebileceği ile birlikte belirttik.

Öncelikle oluşturduğumuz newpool isimli pool için uygulayalım, ardından rpool için nasıl uygulanacak bakacağız. Bildiğiniz gibi rpool bizim kök dosya sistemimiz bu yüzden hadi export edelim diyerek export edemeyiz 🙂 export edemezsek import edemeyiz, import edemezsek rewind yapamayız vesselam…

# pool için checkpoint var mı?
zpool get checkpoint newpool 
NAME     PROPERTY    VALUE    SOURCE
newpool  checkpoint  -        -
# pool için checkpoint oluşturalım
zpool checkpoint newpool 
# pool için checkpoint var mı?
zpool get checkpoint newpool 
NAME     PROPERTY    VALUE    SOURCE
newpool  checkpoint  99K      -
# pool export edelim
zpool export newpool 
# pool checkpoint noktasına geri dönelim...
zpool import newpool --rewind-to-checkpoint
# pool için checkpoint var mı? -- pool eski halinde...
zpool get checkpoint newpool 
NAME     PROPERTY    VALUE    SOURCE
newpool  checkpoint  -        -

Şimdi aynısını rpool için yapalım.

Kök dosya sistemimiz zfs dizin yapısına sahip olduğundan ve burası üzerinde işlem yapmamız gerektiğinden mount işleminden önce bu işlemi yapmak zorundayız, sistemi bilinçli olarak initramfs satırına düşüreceğiz

  • İlk olarak sistemi yeniden başlatıyoruz, grub boot ekranı karşımıza çıkıyor ve e harfine basıyoruz,
  • linux ile başlayan satırın sonuna break=mount ekleyip, F10 veya Ctrl + X ile sistem açılışını yapalım.
  • initramfs satırına düştükten sonra;
    • modprobe zfs [Enter]
    • zpool import rpool --rewind-to-checkpoint [Enter]
    • Ctrl + D olmadı tekrardan Ctrl + D

Bir pool üzerinde rewind yapılarak checkpoint noktasına geri dönüldüğünde;

  • Dönüş yapılan checkpoint noktası da siliniyor, yeniden oluşturmayı unutmayın…
  • zfs dizin yapısı felan dinlemiyor, ne var ne yok o noktaya geri dönüş yapıyorsunuz…

Dikkat ! Eğer bir pool üzerinde bir checkpoint tanımlandıysa zpool alt komutlarından remove, attach, detach, split, and reguid kullanım dışı kalıyor.


13. zfs dizin yapısı klonlama işlemi (clone)

Buraya kadar zfs dizin yapısı oluşturma, yoketme, snapshot alma, rollback işlemi gibi işlemleri gördük. clone işlemi ise en basit mantıkla geçmişte alınan bir snapshot noktasında ihtiyacımız olan bir veri varsa ve o snapshot sonrasında da snapshot alındıysa o anki dizin yapısını yeni bir dal olarak kullanma işlemidir.

Basit bir örnek ile klonlama işlemi yapalım.

cd /home/yasin/dedup/

zfs snapshot rpool/home/yasin/dedup@1
rm -rf 1 2 3

zfs snapshot rpool/home/yasin/dedup@2
rm -rf 4 5 6

zfs snapshot rpool/home/yasin/dedup@3
rm -rf 7 8 9

Her bir snapshot işleminden sonra zfs dizin yapısından dosya sildik, buradan 1. snapshot noktasına rollback deneyelim, 1 numaralı dizine ihtiyaç duyduğumuzu farzedelim.

Özetle o noktaya dönebilmek için sonrakileri silmek zorundasın diyor… Böyle bir durumda tam geriye gidip sonrasında yaptığımız herşeyi tekrar yapmamızın önüne geçmemizi sağlayan yapı clone. dedup@1 noktasından yeni bir dal oluşturalım, clone çıkartalım.

Buradaki örnekte clone geçmişte ihtiyaç duyulan bir klasöre erişmek için kullanıldı, dedup-clone1 dizini içerisinden 1/ ismindeki dizini güncel dedup zfs dizin yapısına kopyalarsak örnek senaryomuzu tamamlamış oluruz. Bu durumda clone dizin yapısına ihtiyacımız kalmadığından klonu kaldırabiliriz.

Bu işlemden önce ufak bir not. Klonlanan zfs dizin yapısı şu anki haliyle klonlandığı zfs dizin yapısına göbekten bağlı durumda, eğer dedup ismindeki zfs dizin yapısını silmek istersek bize hayır silemezsin önce klonu sil diye kızacaktır…

zfs destroy rpool/home/yasin/dedup-clone1


14. Klonlanmış zfs dizin yapısı görüntüsünü zfs dizin yapısı olarak sisteme dahil etmek (promote)

Yeni senaryo, bir projeye başlayacağız diyelim ve harika bir dosyalama sistematiğimiz var, ama gel gelelim bu dosyalama yapısını kopyalamadık ve doğrudan üzerine yığmaya başladık… ZFS dizin yapımız var ve snapshot noktalarımız var. Hadi dizinlerimizi yeni bir zfs dizin yapısına klonlayalım ve alt maddeye geçelim.

Yukarıdaki ekran görüntüsünde aşırı hızlı şekilde ilerlemiş bir proje görüyorsunuz 🙂 şaka bir yana örneği gerçekçi olsun diye geçmişte uğraştığım bir şeyleri ilave ederek yapmak istedim.

@initial olarak işaretlediğim snapshot sadece dizin yapısını barındırıyor, içerisinde veri yok. Bu noktadan yeni bir dal oluşturalım yani clone yapalım.

Şu anki haliyle project2 yalnızca project1@initial snapshot noktasının görüntüsü, her koşulda project1 isimli zfs dizin yapısına bağımlı. Bu noktada project2 klonunu bağımsız hale getirmek istediğimizde promote alt komutunu kullanıyoruz.

Bu kadar, project2 artık bağımsız bir zfs dizin yapısına sahip, kendisine ait snapshotları olabilir 🙂

Yukarıda görüleceği üzere clone ile bir snapshot üzerinden ayırdığımız ve promote ile zfs dizin yapısı haline getirdiğimiz dizin ayrıldığı snapshot noktasını kendi üzerine taşır.

zfs clone rpool/home/yasin/Projects/project1@initial rpool/home/yasin/Projects/project2

zfs list -r -t snapshot rpool/home/yasin/Projects

zfs get origin rpool/home/yasin/Projects/project2

zfs promote rpool/home/yasin/Projects/project2

zfs get origin rpool/home/yasin/Projects/project2

15. Yazarken kopyalama (copy on write)

Bu kısmı açıklamaya uğraşmaktan haya ederim, teknik derinliğim şimdilik yetersiz.


16. Sürekli veri bütünlüğü kontrolü ve veri bozulmalarına karşı otomatik onarım (scrubbing)

ZFS dosya sisteminin işleyişi gereği dosya sisteminde dosya bütünlüğü başlı başına bir iş ve fragmentation olarak tanımlanan bu kavram tüm dosya sistemlerinde erişim hızlarının düşmesi, dosyalarda bozulma ve veri kaybı meydana gelmesi kavramları ile birlikte anılıyor.

ZFS bu olaya dosyalar her okunduğunda parçalanmış verileri birleştir diyerek kalıcı bir çözüm getirmiş, scrub komutu ile seçili pool üzerinde elle de tetiklenebilmekte.

zpool get dedupratio,health,fragmentation rpool 
NAME   PROPERTY       VALUE     SOURCE
rpool  dedupratio     10.00x    -
rpool  health         ONLINE    -
rpool  fragmentation  1%        -

17. Mirror yapıdaki disklerde ayna kopyalama (resilver)

RAID1 ve RAID10 topolojide çalışan sistemlerde ayna kopya mekanizması mevcuttur, ZFS ile raid işlemlerinden ilk yazımda bahsetmiştim ve orada bu konuya değinmiştik. Burada 2 şekilde uygulama yapacağım.

  • Birincisi offline olan ayna konumdaki bir diskin tekrar online yapılıp kaydetmediği veriyi eşitlemesi üzerine.
  • İkincisi arızalı disk değişimi senaryosu üzerine.

Deneme için kurduğum sistemde 4 adet disk ile RAID-10 (mirror) kullanmıştım. Disklerden birisini offline konuma alıp tekrar online komuta aldığımda ne oluyor bakalım.

Sistem mirror yapıda olduğu için şu anda sistemi bu haliyle kullanmaya da devam edebilirim, rpool verdiği uyarılara gelecek olursak.

  • status: DEGRADED bir veya daha fazla aygıt devre dışı bırakıldı, olağan şekilde çalışabilmek için yeterli kopya mevcut durumda.
  • action: zpool online ile aktifleştir veya muadili diski yerleştirip zpool replace diyerek o aygıtı pool içerisine ekle.

Bu uygulamada resilver işlemine değinmek için online konuma alacağız.

İkinci uygulamamızı yapmak için yeni bir sanal disk oluşturup biçimlendirelim, ardından VM üzerinden sanal diski söküp yerine yeni diskimizi yerleştirelim.

Boot sektörü içeren 1. diski söktüm. Şu anda hem bpool hem de rpool DEGRADED durumda,

Aynı kapasitedeki yeni bir diski sisteme ekleyip partition yapımı oluşturdum, hali hazırda /boot/efi partition içeren diski sistemden sildiğim için şu anda boot oluşturma adımlarını tekrardan yapmam gerekecek, o kısmı hazırladığım installer script otomatik yapıyordu burada elle uygulayacağım.

lsblk /dev/sda
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   20G  0 disk 
├─sda2   8:2    0  512M  0 part 
├─sda3   8:3    0    1G  0 part 
└─sda4   8:4    0 18.5G  0 part 

blkid -s PARTUUID -o value /dev/sda2
4e7933fa-c45f-4053-9829-f453a4cbba8a

blkid -s PARTUUID -o value /dev/sda3
4b5947b3-6a86-4da8-acc8-352f4defa345

blkid -s PARTUUID -o value /dev/sda4
cebf8f7f-3a01-4d35-a404-aa1cde31231a
dd if=/dev/disk/by-partuuid/8b2ad6f4-63e0-441e-9b35-3ccc8da91563 \
> of=/dev/disk/by-partuuid/4e7933fa-c45f-4053-9829-f453a4cbba8a status=progress
516051456 bytes (516 MB, 492 MiB) copied, 10 s, 51.6 MB/s
1048576+0 records in
1048576+0 records out
536870912 bytes (537 MB, 512 MiB) copied, 10.6724 s, 50.3 MB/s

mkdosfs -F 32 -s 1 -n EFI /dev/disk/by-partuuid/4e7933fa-c45f-4053-9829-f453a4cbba8a
mkfs.fat 4.2 (2021-01-31)

efibootmgr -c -g -d /dev/disk/by-partuuid/4e7933fa-c45f-4053-9829-f453a4cbba8a -p 2 -L "debian" -l '\EFI\debian\grubx64.efi'
BootCurrent: 0009
Timeout: 3 seconds
BootOrder: 0002,0001,0009,0000,0003
Boot0000* UiApp
Boot0001* UEFI QEMU QEMU HARDDISK 
Boot0003* EFI Internal Shell
Boot0009* zfs-mirror
Boot0002* debian

Yeni diskimiz artık sistemde resilver yapılmış ve çalışır durumda.

Eski diskimi yerine taktım ve replace işlemini yaptıktan sonra resilver otomatik olarak gerçekleşti.


18. Kriptolama (encryption)

Eğlenceli bir konuya daha geldik, encryption. Burada kalkıp tüm mekanizmayı araştırıp sunmayacağım, hali hazırda installer.sh scriptim unencrypted yapıda kurulum yaptırıyor ama bu kriptolama kullanamayacağımız manasına gelmiyor. Hadi kriptolu zfs dizin yapısı oluşturalım, kullanacağımız komutlar ve özellikler aşağıdaki gibi.

encryption	on | off | aes-128-ccm | aes-192-ccm | aes-256-ccm | aes-128-gcm | aes-192-gcm | aes-256-gcm

keyformat	raw | hex | passphrase

keylocation	prompt | file:///absolute/file/path | https://address | http://address

pbkdf2iters=iterations

Burada geçen pbkdf2iters özelliğinin ne olduğunu ufak bir araştırma ile buldum, rfc2898 içerisinde tanımlandığı şekliyle açılımı password-based key derivation function yaptığı iş ise “Parola tabanlı bir anahtar türetme işlevinde, temel anahtar bir paroladır ve diğer parametreler bir salt (hash) değeri ve bir yineleme (iteration) sayısıdır.” şeklinde çevrilebilir. Genel açıklamasına buradan bakabilirsiniz. pbkdf2iters varsayılan 350000 tur, minimum 100000 tur hashlenmiş şekilde parola tutulur. Özetle parolamızın hash değeri 350000 defa hashlendiğinde ortaya çıkan değer olduğundan bruteforce ile kırılması zorlaştırılmış olur.

Ara örnek:

Örneğin parolamız 12345678 olsun, hash algoritmamız sha256 olsun, parolamızı 1 defa hashlediğimizde :

ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f

değerini elde ederiz, 100000 defa hashlediğimizde ise :

<?php

$hash = hash('sha256', 12345678);

for($i=1;$i<100000;$i++) {
    $hash = hash('sha256', $hash);
}

echo $hash;
0375cc80279f9ddfe3bade3f6c1f1cf5425f229be03d11f4a1c970c8f5c27a6d

değerini elde ederiz. Benzer şekilde dosya sistemimizde pbkdf döngü sayısını bilmeyen birisi, bruteforce yöntemiyle parola kırmak için epey bir zahmete girmek zorunda, parola 12345678 olmasına rağmen!

pbkdf2iters özelliğinin kullanabilmesi için zfs dizin sisteminde encryption aktif ve keyformat=passphrase olmalıdır. zfs change-key alt komutu ile değiştirilebilir.

zfs create \
-o encryption=aes-256-gcm \
-o keyformat=passphrase \
-o keylocation=prompt \
-o pbkdf2iters=19840101 \
	rpool/home/yasin/encrypted
Enter passphrase:
Re-enter passphrase:

chown -R yasin:yasin /home/yasin/

zfs get encryption,keystatus,keyformat,keylocation rpool/home/yasin/encrypted
NAME                        PROPERTY     VALUE        SOURCE
rpool/home/yasin/encrypted  encryption   aes-256-gcm  -
rpool/home/yasin/encrypted  keystatus    available    -
rpool/home/yasin/encrypted  keyformat    passphrase   -
rpool/home/yasin/encrypted  keylocation  prompt       local

encryption, keyformat, keylocation temelde kriptolu zfs dizin yapısı oluşturmak için yeterli. Buradan zfs özellikleri listesinde özelliklerin alabileceği parametrelere bir göz atabiliriz.

Şu anda /home/yasin/encrypted zfs dizin yapımız kriptolu bir dizin, oluştururken parolamızı girdiğimiz için şu anda içerisinde dosya oluşturma silme gibi işlemler yapabiliyoruz.

zfs komutunun kriptolama ile ilgili alt komutları aşağıdaki gibi.

zfs load-key [-nr] [-L keylocation] -a|filesystem

zfs unload-key [-r] -a|filesystem

zfs change-key [-l] [-o keylocation=value] [-o keyformat=value] [-o pbkdf2iters=value] filesystem

zfs change-key -i [-l] filesystem

load-key, unload-key, change-key

  • Erişimimiz olan encrypted zfs dizinimizi unmount edelim ve mount edelim
    • zfs unmount rpool/home/yasin/encrypted
    • zfs mount rpool/home/yasin/encrypted

Sorunsuz şekilde sistemden ayırıp tekrar bağlayabildik.

  • zfs unload-key ile kriptolu zfs dizin yapımızın key bilgisini ayıralım.
    • zfs unmount rpool/home/yasin/encrypted
      zfs unload-key rpool/home/yasin/encrypted

Bu işlemi yapmadan önce unmount ile sistemden ayırmak zorundayız. Şu aşamada sistemde encrypted dizini için bir anahtar bulunmamakta, mount etmeye çalışalım ve ne uyarı alacağımıza bakalım.

  • zfs load-key ile kriptolu zfs dizin yapımızın key bilgisini sisteme ekleyip birde bu şekilde mount deneyelim.
    • zfs load-key rpool/home/yasin/encrypted
      zfs mount rpool/home/yasin/encrypted

Çok secret dosyalarımıza artık erişebiliyoruz,

Sistem açılışında parola isteyip sistemin açılışını durdurmaması için yapabileceklerimiz:

  • zfs set canmount=noauto rpool/home/yasin/encrypted

komutu ile zfs dizinimizin automount özelliğini devre dışı bırakabiliriz, böylece sistem açıldıktan sonra dilediğimiz zaman load-key, mount işlemimizi yapıp erişim sağlayabiliriz.

  • zfs set keylocation=... özelliğimiz prompt olduğundan bize parolayı girmemiz için ekran çıkartıyordu, keylocation özelliği file:// | https:// | http:// gibi wrapper yapısını da destekliyor, /root dizini altına kullanıcının parolasını cleartext dosya olarak oluşturdum ve keylocation=file:/// ile dosya yolunu gösterdim, sonuç aşağıdaki gibi, artık auto mount yaptırabiliriz.
echo 12345678 > yasinPassword

zfs set keylocation=file:///root/yasinPassword rpool/home/yasin/encrypted

zfs get keylocation rpool/home/yasin/encrypted
NAME                        PROPERTY     VALUE                       SOURCE
rpool/home/yasin/encrypted  keylocation  file:///root/yasinPassword  local

zfs unmount rpool/home/yasin/encrypted
zfs unload-key rpool/home/yasin/encrypted
zfs load-key rpool/home/yasin/encrypted
zfs mount rpool/home/yasin/encrypted

Parolamızı değiştirelim mi? zfs change-key Bu işlemi yapabilmemiz için key sisteme yüklü durumda olmalı (load-key), aksi taktirde yeni parola verme işlemi gerçekleşmeyecektir, parolamızın pbkdf2iter değerini de değiştirelim.

echo 87654321 > /root/yasinPassword

zfs change-key \
-o keyformat=passphrase \
-o keylocation=file:///root/yasinPassword \
-o pbkdf2iters=198411 \
	rpool/home/yasin/encrypted

zfs unmount rpool/home/yasin/encrypted
zfs unload-key rpool/home/yasin/encrypted
zfs load-key rpool/home/yasin/encrypted
zfs mount rpool/home/yasin/encrypted

Yeni parolamızın çalıştığını doğruladıktan sonra farklı formatları deneyelim. Parolayı cleartext oluşturmuştuk ancak keyformat bize raw | hex | passphrase şeklinde 3 seçenek sunuyor, raw keyformat kullanalım, parolayı değiştirmek için change-key alt komutumuz ile işlem yapacağız.

  • İlk olarak parola olarak kullanacağımız raw değeri oluşturalım, dökümanda 32 byte random olması gerektiği yazıyor buna göre dd ve /dev/urandom iş görecektir. Ardından zfs change-key ile parolamızı ve diğer özelliklerimizi değiştirelim. pbkdf2iters yalnızca passphrase ile çalışıyordu bu sebepten artık kendisine ihtiyacımız yok.
dd if=/dev/urandom bs=32 count=1 of=/root/yasinPasswordRaw
1+0 records in
1+0 records out
32 bytes copied, 0.000169307 s, 189 kB/s

zfs change-key \
-o keyformat=raw \
-o keylocation=file:///root/yasinPasswordRaw \
	rpool/home/yasin/encrypted

zfs unmount rpool/home/yasin/encrypted
zfs unload-key rpool/home/yasin/encrypted
zfs load-key rpool/home/yasin/encrypted
zfs mount rpool/home/yasin/encrypted

zfs set canmount=on rpool/home/yasin/encrypted

Son olarak parolamızı dosyadan çektiğimiz için artık huzurlu bir şekilde auto mount aktifleştirbiliriz. Parolamızı içeren dosyamızı bir flashdisk içerisinde saklayıp o flashdisk ile de kriptolu zfs dizin yapımıza erişebiliriz.

Son olarak BT sorumlusu arkadaşın sürekli parola değiştirme işlemini yüklenmesini istemiyorsak ve kullanıcımıza güveniyorsak kendisine gerekli yetkileri verip kendi parolasını değiştirmesine de izin verebiliriz. Burada özet geçmiştim ancak encryption kapsamlı bir konu olduğundan bu kısma bırakmak gerekti. load-key, unload-key yetkileri de eklenebilir ancak mount-unmount işlemleri root ile yapıldığından kullanıcımız yalnızca parola değiştirmekle yetinmek zorunda, eğer sudo yetkileri yoksa

# root olarak
zfs allow -u yasin \
change-key,keyformat,keylocation,pbkdf2iters \
rpool/home/yasin/encrypted

19. Uzak sunucu gönderme ve alma (send, receive)

Aslında send ve receive komutları yerel zfs dizin yapıları arasında da kullanılabilmekte ancak burada uzak sunucuya gönderme alma üzerine örnekleme yapacağım, hali hazırda veri kaybetmemek için backup sistemimiz olmalı ve backup denilince uzak sistemler akla gelir değil mi?

Uzak sunuculara Linux sistemler üzerinden bağlantı kurabilmemizin en güzel ve kolay yollarından bir tanesi ssh, ssh kullanarak bir sisteme parola kullanmadan giriş yapabilmemiz, komut çalıştırabilmemiz için ise ssh key çifti imdadımıza yetişiyor. Hadi ilk olarak iki makine arasında parolasız şekilde ssh bağlantısı oluşturacak şekilde key pair oluşturalım.

# parolasız ssh rsa key çifti
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

# ssh copy id
ssh-copy-id -i /root/.ssh/id_rsa root@192.168.122.21
...
Number of key(s) added: 1
...

echo -e "192.168.122.21\tzfs-backup" >> /etc/hosts

# Test edelim
ssh -i .ssh/id_rsa root@zfs-backup 'ls'
after-reboot.sh
eth0
installer.sh

### başarılı. Şimdi backup sisteminden buraya bakalım.
# zfs-backup root terminal
ssh-copy-id -i /root/.ssh/id_rsa root@zfs-mirror
...
Number of key(s) added: 1
...

ssh -i .ssh/id_rsa root@zfs-mirror 'ls'
after-reboot.sh
dead.letter
yasinPassword
yasinPasswordRaw

Şu anda zfs-mirror <-> zfs-backup sistemleri arasında send / receive işlemlerini ssh ile parolasız şekilde yapabiliriz.

zfs-backup sistemi üzerinde zfs create rpool/backup komutu ile backup isminde bir zfs dizin sistemi oluşturdum ve zfs-mirror sisteminde yedeklemek istediğim zfs dizin yapılarını buraya göndereceğim.

zfs send rpool/home/yasin/compression-test@recursive | \
  ssh zfs-backup zfs receive -d rpool/backup

Yukarıdaki komut ile zfs send kullanarak rpool/home/yasin/compression-test@recursive snapshot noktamızı bir stream haline getirdik, uzak sunucumuzda ise ssh kullanarak zfs receive komutu ile bu stream üzerinden okuyarak belirttiğimiz zfs dizin yapısı altına yedeğimizi aldık. Yedeği alırken eğer dosya sistemi özelliklerini belirtmezsek backup sisteminin varsayılanlarına göre hareket edecektir, bu kısma dikkat etmek gerek.

Burada send / receive alt komutlarının alabileceği argümanlar detaylı şekilde açıklanmış durumda, gerisini size bırakıyorum 🙂 Bu yazı bildiğiniz zfs kitapçığı halini aldı o yüzden detayına girmeden anlattım. Ancak linkini verdiğim sayfada --raw argümanı şahsen işime yarayan bir argüman.


20. zfs dizin yapısı paylaşımı (share)

sharenfs ve sharesmb olmak üzere iki çeşit paylaşım yapabiliyoruz, detayına girmek gerekirse sistemimizdeki dilediğimiz bir zfs dizin yapısını ağ üzerinde nfs veya samba paylaşım olarak açabiliyoruz. Bu şekilde Windows veya Linux sistemler ile ağ üzerinden bu dizinlere kolaylıkla erişim sağlanılabiliyor.

[NFS Server !] Bu işlem zfs sistemimizde gerçekleşiyor.

zfs dizin yapısı özelliklerinden sharenfs özelliği kullanımı örneğimiz:

apt install nfs-kernel-server
showmount -e
systemctl enable nfs-kernel-server
systemctl start nfs-kernel-server
systemctl status nfs-kernel-server

zfs create -o sharenfs="rw=@192.168.122.0/24" rpool/home/yasin/nfsShare
chown -R yasin:yasin /home/yasin/
zfs share rpool/home/yasin/nfsShare
exportfs -a

[NFS Client !] Bu işlem nfs client yüklü herhangi bir makinede gerçekleşiyor.

Linux

sudo apt install nfs-common
mkdir /mnt/nfsShare

sudo mount -t nfs 192.168.122.232:/home/yasin/nfsShare /mnt/nfs/

touch /mnt/nfs/test1

ls -alh /mnt/nfs/
toplam 8,0K
drwxr-xr-x 3 yasin yasin    5 Nis  4 06:44 .
drwxr-xr-x 3 root  root  4,0K Nis  4 06:04 ..
-rw-r--r-- 1 yasin yasin    0 Nis  4 06:38 deneme
drwxr-xr-x 2 yasin yasin    2 Nis  4 06:37 test
-rw-r--r-- 1 yasin yasin    0 Nis  4 06:44 test1

Windows

[SAMBA Server!] ZFS sistemimizde:

apt install samba samba-common smbclient cifs-utils
modprobe cifs
systemctl enable smbd
systemctl start smbd
systemctl status smbd

smbpasswd -a yasin
New SMB password:
Retype new SMB password:
Added user yasin.

smbpasswd -e yasin
Enabled user yasin.

zfs create -o casesensitivity=mixed -o sharesmb=on rpool/home/yasin/smbShare
chown -R yasin:yasin /home/yasin/
zfs get sharesmb rpool/home/yasin/smbShare
zfs share rpool/home/yasin/smbShare

systemctl restart smbd

İşlem bu kadar 🙂 Aşağıda Windows sistem üzerinden erişimi görebiliyorsunuz. Parola sorulduğunda yukarıda oluşturduğunuz samba kullanıcısı ve parolasını girmeniz yeterli.

NFS ile SAMBA arasında tercihim NFS


Kapanış olarak;

Yazımızın başlangıcında … üzerinde çalıştığımız veriler ne kadar kıymetli ? sorusunu sorduk, şahsi cevabımı vermiştim, “Kaybetmek istemeyeceğimiz kadar.” Hazırlamış olduğum bu 3 yazıda, kıymetli verilerimizi kaybetmeden depolayabileceğimiz, yedekleyebileceğimiz, hata yapsak bile geri dönüşü büyük oranda mümkün olan bir dosya sistemi teknolojisinden, ZFS teknolojisinden, özelliklerinden ve Debian GNU / Linux üzerine kurulumundan, kullanımından öğrenebildiğim kadarıyla bahsettim.

ZFS üzerine yazıları hazırlarken faydalandığım kaynaklara gelince;

OpenZFS web sitesi, man komutları, Oracle web sitesi ile birlikte, aramalarım sırasında yanılmıyorsam reddit üzerinde karşılaştığım ve tanıtımı yaklaşık olarak “Yazılar eski olmasına rağmen büyük oranda güncelliğini koruduğundan ZFS üzerine incelenmesi gereken bir web sitesi …” şeklinde olan, Aaron Toponce tarafından hazırlanmış Zpool ve Zfs Yönetimi üzerine de yazarın kişisel notlarını, araştırmalarını içeren bir blog. Sitenin tanıtımına aynen katılıyorum, hakkını vermiş.

Eğer fırsat bulacak olursam ZFS dosya sisteminin, teknik altyapısı, spare, draid, log, zil, cache aygıtları ile hata tespit & giderme yöntemleri üzerine 4. bir yazı hazırlamayı düşünüyorum, kendim öğrendikten sonra tabii ki, şu aşamada ZFS sistemlerin sadece acemisi durumundayım, bir hata ile karşılaşacak olursam veya arızalanmış bir sistem önüme bırakılıp çözüm geliştirmem beklenirse, ciddi oranda efor sarf etmem gerekecektir.

Önce bloğumu biraz daha şenlendireyim, nasipse ona da elbet sıra gelir.

Allah’a emanet olun.

Yorumlar kapatıldı.