UBIFS Dosya Sistemi

UBIFS (Unsorted Block Image File System), JFFS2 gibi raw flash aygıtları üzerinde çalışan bir dosya sistemidir.

Nokia mühendisleri ve Szeged Üniversitesi'nin (Macaristan) katkılarıyla geliştirilmiştir.

Kernel 2.6.27 versiyonundan itibaren Linux kaynak kodu ile birlikte dağıtılmaya başlanmıştır.

JFFS2'den farklı olarak doğrudan MTD aygıtın üzerinde değil, Unsorted Block Images aygıtları üzerinde çalışır.

UBI ise MTD aygıtının üzerinde çalışmaktadır.

Tasarım Prensipleri

UBIFS'in tasarımındaki temel hedefler:

  • Artan flash kapasiteleriyle büyük dosya sistemleriyle performanslı çalışmak

  • Mount süresinin kısaltılması

  • Yazma hızının artırılması

  • Büyük dosyalara hızlı erişim

şeklinde özetlenebilir.

Kullanım

Oluşturulan bir UBI volume birimi, içerisinde dosya sistemi henüz olmasa dahi ubifs türünde mount edilebilir:

mount -t ubifs ubi0:test1 /mnt

Mount işleminde etiketler kullanılabildiği gibi, volume birim numaraları da kullanılabilir:

mount -t ubifs ubi0:1 /mnt

UBIFS İmajı Oluşturma

Mevcut bir dizinden UBIFS imajı oluşturmak için mtd-utils paketinden çıkan mkfs.ubifs uygulaması kullanılır.

mkfs.ubifs -m 512 -c 100 -e 128KiB -x lzo -r /work/dir /tmp/ubifs.img
  • -m parametresi minimum IO işlem büyüklüğünü gösterir

  • -c parametresi ile maksimum logical eraseblock adedi belirlenir.

  • -x parametresi ile sıkıştırma algoritması seçilir.

  • -r parametresi ile imajı oluşturulacak olan dizin belirtilir.

İmaj oluşturulması tamamlandıktan sonra ubiupdatevol uygulaması ile bu volume imajı, volume birimi üzerine yazılır:

ubiupdatevol /dev/ubi0_0 /tmp/ubifs.img

UBI İmajı Oluşturma

Mevcut bir UBI aygıtı (/dev/ubi0) bir veya birden fazla UBI volume biriminden oluşabilir.

Bu durumda bir UBI aygıtının imajı oluşturulacak olursa, ubiformat uygulaması ile başka bir UBI aygıtı üzerine yazıldığında, aynı volume birimleri de oluşturulmuş olacaktır.

ubiformat /dev/mtd0 -f /tmp/ubi.img

UBI imajı oluşturmak için mtd-utils paketinden çıkan ubinize uygulaması kullanılır.

Ubinize uygulamasını çalıştırmadan önce, INI formatında bir konfigürasyon dosyası oluşturulmalıdır.

Örnek kullanım:

ubinize -o /tmp/ubi.img -m 512 -p 128KiB ubinize.cfg

Konfigürasyon dosyası içeriği:

# ubinize.cfg
[rootfs_volume]
mode=ubi
image=rootfs.ubifs
vol_id=1
vol_type=static
vol_name=rootfs
vol_alignment=1

[data_volume]
mode=ubi
image=data.ubifs
vol_id=2
vol_type=dynamic
vol_name=data
vol_alignment=1
vol_flags=autoresize

Root Dosya Sistemi Olarak UBIFS

Root dosya sistemi olarak UBIFS kullanılmak istendiğinde, kernel açılış parametrelerine aşağıdaki değerler eklenmelidir:

  • ubi.mtd=0
  • root=ubi0:rootfs_label
  • rootfstype=ubifs

rootfs_label ilgili UBI aygıtı üzerindeki volume birim etiketini göstermektedir.

UBIFS - Write-Back Desteği

JFFS2 dosya sistemi write-through modunda çalışır ve değişiklikler senkron biçimde NAND flash'a yazılır.

UBIFS ise write-back desteği sayesinde, asenkron modda çalışmaktadır.

Her tür write sistem çağrısı ile yapılan yazma işlemleri, Linux'te öncelikle page cache'lere yazılır.

Page Cache, genel bir bellek yönetim mekanizmasıdır.

Bir dosyaya yazmaya çalıştığınızda veriler aslında bellekteki page cache'e yazılır ve ilgili page'ler dirty olarak işaretlenir. Bu aşamada sistem başarılı bir değer döndürür ama gerçekte veriler fiziksel olarak henüz yazılmış değildir. Asıl yazma işlemi, bazı parametrelere bağlı olarak daha sonra gerçekleşir.

Yazma Operasyonları ve Page Cache

Yazma işlemlerinde Page Cache kullanımından kaynaklanan bu durumla ilgili write sistem çağrısının açıklamalarında yer alan önemli notu tekrar vurgulamamız, uygulama geliştirme sürecinde tespiti zor hatalarla karşılaşmamamız için yerinde olacaktır:

$ man 2 write
...
NOTES

A successful return from write() does not make any guarantee that data
has been committed to disk.  In fact, on some buggy  implementations, 
it does not even guarantee that space has successfully been reserved 
for the data. The only way to be sure is to call fsync(2) after you 
are done writing all your data.

Linux write-back Konfigürasyonu

Linux sistemlerde /proc/sys/vm dizini altında write-back mekanizmasını ayarlayabileceğimiz dosyalar bulunur. Bu değerler UBIFS'e özgü olmayıp sistemdeki tüm dosya sistemlerini etkiler.

  • dirty_writeback_centisecs: write-back thread'inin hangi sıklıkta çalışıp dirty page cache'leri yazacağını belirtir. (Örnek: 500)

  • dirty_expire_centisecs: verinin maksimum ne kadar süre dirty olarak kalabileceğini gösterir, süre bitiminde periyodik çalışan write-back thread'i gerekli işlemleri yapacaktır. (Örnek: 3000)

  • dirty_background_ratio: Toplam bellek alanının maksimum ne kadarlık kısmının dirty page cache tutmak için kullanılacağını belirtir. Bu değer aşılırsa periyodik write-back thread'i ayarlanan oranı sağlayabilmek için gerekli işlemleri yapar. Soft-Limit olarak düşünülebilir. (Örnek: 40)

  • dirty_ratio: dirty page-cache oluşturabilecek süreçlerin, yazma işlemi öncesinde toplam bellek alanının ne kadarının bu amaçla kullanılabileceğini gösteren orandır. Yazma öncesinde yapılan kontrolde bu değere erişildiği tespit edilirse, öncelikle mevcut dirty page cache'ler commit edilir ve bu oran sağlanmaya çalışılır. Hard-Limit olarak düşünülebilir. (Örnek: 60)

UBIFS Write-Buffer

Genel Linux write-back mekanizmasına ek olarak, UBIFS'in kendine özgü write-buffer mekanizması da bulunmaktadır.

UBIFS write-buffer alanları, UBIFS kodu içerisinde, page cache ve flash alanı arasında durur. Dolayısıyla write-back mekanizması verileri flash'a değil, UBIFS write-buffer alanına yazar.

Write-buffer alanı page cache ile karşılaştırdığımızda çok küçüktür ve genellikle NAND page size değerine eşittir. (512 byte, 2Kb, 4Kb vb.)

NAND page size değeri, NAND aygıtı üzerinde yapılabilecek minimum okuma/yazma miktarını gösterir. Dolayısıyla dirty veriler dirty_expire_centisecs'lik süre sonrasında commit edilir ancak verinin son kısımları write-buffer yüzünden ekstra bir 3-5 saniyelik gecikmeye tabi tutulabilir.

write-back ve Senkronizasyon

Write-back ve write-buffer mekanizmaları karşısında verilerin commit edilme zamanını kontrol için aşağıdaki yöntemler kullanılabilir:

  • İlgili bölüm -o sync parametresi ile mount edilecek olursa tüm yazma işlemleri senkron olarak yapılır (JFFS2'deki gibi) ancak performans çok ciddi biçimde düşer.

  • fsync(int fd) çağrısı ile sadece belirli bir file descriptor'a ait verilerin commit edilmesi sağlanabilir.

  • fdatasync(int fd) çağrısı ile dosyanın meta-data bilgilerinin commit edilmemesi sağlanır, sadece dosya içeriği commit edilir.

  • open() çağrısında O_SYNC bayrağı kullanılması durumunda ilgili file descriptor için yapılan tüm write işlemleri senkron olarak gerçekleşir. (fsync ve fdatasync örneğinde pek çok write işleminin bir defada commit edilebileceğini unutmayın)

Ve Daha Çok Senkronizasyon Problemi...

Write-Back mekanizması ve asenkron çalışma yöntemiyle ilgili pek çok detay daha bulunmaktadır ve Kernel geliştiricileri ile uygulama geliştiriciler arasında bir çatışmaya yol açmaktadır. (Bkz: http://lwn.net/Articles/326471)

Konuyla ilgili uzun tartışmalar genelde Linux çekirdeğinin duruma göre bazı ince ayarlara otomatik karar vermesi ve yapması ile kullanıcı adına böyle bir karar vermeyip, zaten halihazırda kullanıcı seviyesinden sysctl mekanizmasıyla yapılabilmekte olan bu ince ayarların, kullanıcının sorumluluğuna bırakılması noktasında yaşanmaktadır.

Fikir vermesi açısından aşağıda konuyu özetleyen bir mail ve Torvalds'ın yorumu yer almaktadır. İlgili kişiler:

  • Andrew Morton: 1959 doğumlu ana Linux geliştiricilerinden, halihazırda Ext3 ve blok tabanlı aygıtlar için journaling desteğiyle ilgili kısımlardan sorumlu
  • Theodore Y. Ts'o: 1968 doğumlu ana Linux geliştiricilerinden, ext2 ve ext3 içerisinde çalışmış, halihazırda ext4 kodundan sorumlu
  • Linus Benedict Torvalds: 1969 doğumlu, fazla söze gerek yok, Linux'un yanı sıra Git versiyon kontrol sistemini de geliştiren kişi
From:     Linus Torvalds <torvalds-AT-linux-foundation.org>
To:       Andrew Morton <akpm-AT-linux-foundation.org>
Subject:  Re: Linux 2.6.29
Date:     Thu, 26 Mar 2009 20:38:43 -0700 (PDT)

On Thu, 26 Mar 2009, Andrew Morton wrote:
> 
> Why does everyone just sit around waiting for the kernel to put a new
> value into two magic numbers which userspace scripts could have set?
> 
> My /etc/rc.local has been tweaking dirty_ratio, dirty_background_ratio
> and swappiness for many years.  I guess I'm just incredibly advanced.

.. and as a result you're also testing something that nobody else is.

Look at the complaints from people about fsync behavior that Ted says he 
cannot see. Let me guess: it's because Ted probably has tweaked his 
environment, because he is advanced. As a result, other people see 
problems, he does not.

That's not "advanced". That's totally f*cking broken.

Having different distributions tweak all those tweakables is just even 
_more_ so. It's the anti-thesis of "advanced". It's just stupid.

We should aim to get it right. The "user space can tweak any numbers they 
want" is ALWAYS THE WRONG ANSWER. It's a cop-out, but more importantly, 
it's a cop-out that doesn't even work, and that just results in everybody 
having different setups. Then nobody is happy.

results matching ""

    No results matching ""