losetup ile Döngü Aygıtları Oluşturma: Dosyadan Sanal Disk Bağlama ve Yönetme
Disk doldu, yedek sisteme gerek var, ama elimde ekstra donanım yok. İşte böyle bir günde losetup ile tanıştım. O günden bu yana loop device’lar benim için vazgeçilmez bir araç haline geldi. Sanal diskler oluşturmak, şifreli container’lar yönetmek, dosya sistemi testleri yapmak… Bunların hepsini fiziksel bir disk dokunmadan yapabiliyorsunuz. Gelin bu işin derinliklerine inelim.
Loop Device Nedir, Neden Önemlidir?
Linux çekirdeği, normal bir dosyayı sanki bir blok aygıtıymış gibi kullanmanıza izin verir. Bu mekanizmanın adı loop device‘tır. /dev/loop0, /dev/loop1 gibi aygıt dosyaları aracılığıyla çalışır. Pratik olarak ne anlama geliyor? Bir .img dosyasını alıp üzerine ext4 formatlar, mount edersiniz ve sistem için bu tıpkı fiziksel bir disk gibi görünür.
Bu mekanizmanın gerçek hayattaki kullanım alanları:
- ISO ve disk imajlarını bağlamak: CD/DVD imajlarını donanım gerektirmeden mount etmek
- Şifreli dosya sistemleri: LUKS ile şifreli container oluşturmak
- Test ortamları: Yeni bir dosya sistemi denemek için fiziksel disk riske atmamak
- Gömülü sistem geliştirme: Raspberry Pi veya benzeri cihazlar için disk imajı hazırlamak
- Docker ve container altyapısı: Bazı storage driver’lar arka planda loop device kullanır
Temel Sözdizimi ve Parametreler
losetup komutunun temel kullanımı oldukça basittir:
losetup [seçenekler] [loop_aygıtı] [dosya]
Sık kullandığım parametreler:
- -a: Tüm aktif loop device’ları listeler
- -f: Kullanılabilir ilk boş loop device’ı bulur
- -d: Belirtilen loop device’ı ayırır (detach)
- -D: Tüm loop device’ları temizler
- -l: Loop device bilgilerini listeler (JSON çıktı için
--jsonile birleştirilir) - -o: Offset belirtir, imaj içinde belirli bir pozisyondan başlamak için
- –sizelimit: Kullanılacak maksimum boyutu sınırlar
- -P: Partition table’ı otomatik olarak parse eder
- -r: Read-only modda bağlar
- –show: Bağlanan loop device adını ekrana basar
İlk Adım: Boş Bir Disk İmajı Oluşturmak
Önce çalışacağımız ham dosyayı oluşturmamız gerekiyor. Bunun için iki farklı yöntem var ve ikisinin de farklı kullanım senaryoları mevcut.
Yöntem 1: dd ile sıfırlarla dolu imaj
# 1GB boyutunda sıfırlarla dolu bir imaj oluştur
dd if=/dev/zero of=/tmp/virtual_disk.img bs=1M count=1024
# Daha hızlı alternatif: /dev/urandom yerine /dev/zero kullanmak çok daha hızlıdır
# Eğer güvenlik gereksiniminiz yoksa /dev/zero yeterli
Yöntem 2: fallocate ile sparse (seyrek) dosya
# 2GB boyutunda sparse dosya oluştur - anlık olarak yer kaplamaz
fallocate -l 2G /tmp/sparse_disk.img
# Dosyanın gerçek disk kullanımını kontrol et
du -sh /tmp/sparse_disk.img
ls -lh /tmp/sparse_disk.img
fallocate ile oluşturulan sparse dosya, içeriğe göre büyür. Disk alanınız kısıtlıysa test ortamları için ideal seçenektir. Ancak production’da buna dikkat edin, aniden disk dolabilir.
Loop Device’a Bağlama
Dosyamızı oluşturduktan sonra loop device’a bağlayabiliriz:
# Boş ilk loop device'ı bul ve bağla, bağlanan aygıtı göster
losetup -f --show /tmp/virtual_disk.img
# Çıktı genellikle şöyle görünür:
# /dev/loop0
# Manuel olarak belirli bir loop device'a bağla
losetup /dev/loop1 /tmp/virtual_disk.img
# Aktif loop device'ları listele
losetup -a
# Çıktı:
# /dev/loop0: [2049]:1234567 (/tmp/virtual_disk.img)
Bağlama işlemi başarılıysa artık /dev/loop0 adresini normal bir blok aygıt gibi kullanabilirsiniz. Üzerine dosya sistemi oluşturabilir, fdisk ile partition oluşturabilir, hatta şifreli volume açabilirsiniz.
Dosya Sistemi Oluşturma ve Mount Etme
Şimdi bu sanal diske gerçekten kullanışlı bir şey yapalım:
# Loop device üzerine ext4 dosya sistemi oluştur
mkfs.ext4 /dev/loop0
# Mount noktası oluştur
mkdir -p /mnt/virtual_disk
# Mount et
mount /dev/loop0 /mnt/virtual_disk
# Kontrol et
df -h /mnt/virtual_disk
# Çıktı:
# Filesystem Size Used Avail Use% Mounted on
# /dev/loop0 976M 24K 909M 1% /mnt/virtual_disk
# Artık normal bir disk gibi kullanabilirsiniz
touch /mnt/virtual_disk/test_file.txt
cp /etc/hosts /mnt/virtual_disk/
ls -la /mnt/virtual_disk/
Bu aşamadan sonra /mnt/virtual_disk dizinine yazdığınız her şey aslında /tmp/virtual_disk.img dosyasına gidiyor. Sihir gibi ama tamamen çekirdek seviyesinde bir mekanizma.
Gerçek Dünya Senaryosu 1: Partition’lı Disk İmajı
Gömülü sistem geliştirme yapıyorsanız veya Raspberry Pi için imaj hazırlıyorsanız, partition’lı disk imajlarıyla çalışmanız gerekecek. İşte burada -P parametresi devreye giriyor:
# 4GB'lık bir imaj oluştur
fallocate -l 4G /tmp/rpi_disk.img
# Partition tablosu oluştur
fdisk /tmp/rpi_disk.img << 'EOF'
o
n
p
1
+256M
t
c
n
p
2
w
EOF
# Loop device'a bağla ve partition'ları otomatik algıla
losetup -f -P --show /tmp/rpi_disk.img
# Çıktı: /dev/loop2
# Partition'ları kontrol et - otomatik olarak oluşturuldu
ls /dev/loop2*
# /dev/loop2 /dev/loop2p1 /dev/loop2p2
# Boot partition'ı FAT32 formatla
mkfs.vfat /dev/loop2p1
# Root partition'ı ext4 formatla
mkfs.ext4 /dev/loop2p2
# Mount et
mkdir -p /mnt/rpi_boot /mnt/rpi_root
mount /dev/loop2p1 /mnt/rpi_boot
mount /dev/loop2p2 /mnt/rpi_root
Bu yöntemle partition tablonuzla birlikte tam bir disk imajı hazırlayabilirsiniz. Sonrasında dd ile gerçek bir SD karta yazmanız yeterli.
Gerçek Dünya Senaryosu 2: Şifreli Container Oluşturma
Hassas verileri bir dosya içinde şifreli tutmak istiyorsanız loop device ile LUKS kombinasyonu mükemmel çalışır:
# 500MB şifreli container oluştur
dd if=/dev/urandom of=/secure/encrypted_vault.img bs=1M count=500
# Loop device'a bağla
losetup -f --show /secure/encrypted_vault.img
# Diyelim ki /dev/loop3 döndü
# LUKS ile şifrele
cryptsetup luksFormat /dev/loop3
# Şifreli volume'u aç
cryptsetup open /dev/loop3 secure_vault
# Üzerine dosya sistemi oluştur
mkfs.ext4 /dev/mapper/secure_vault
# Mount et
mkdir -p /mnt/vault
mount /dev/mapper/secure_vault /mnt/vault
# Kullanımı tamamlandığında temizle
umount /mnt/vault
cryptsetup close secure_vault
losetup -d /dev/loop3
Bu yöntem, özellikle müşteri verilerini local’de tutmak zorunda olduğunuzda veya taşınabilir medyada hassas bilgi sakladığınızda işe yarıyor. Dosyaya baktığınızda sadece rastgele baytlar görürsünüz.
Offset Kullanımı: İmaj İçinden Belirli Bir Bölüm
Bazen bir disk imajının tamamını değil, içindeki belirli bir partition’ı mount etmek isteyebilirsiniz. Bunun için offset hesaplamak gerekir:
# Disk imajının partition bilgilerini görüntüle
fdisk -l /tmp/rpi_disk.img
# Örnek çıktı:
# Device Boot Start End Sectors Size Id Type
# /tmp/rpi_disk.img1 2048 526335 524288 256M c W95 FAT32 (LBA)
# /tmp/rpi_disk.img2 526336 8388607 7862272 3.7G 83 Linux
# Start sektörü 512 ile çarp (sektör boyutu)
# İkinci partition için: 526336 * 512 = 269484032
# Offset ile direkt ikinci partition'ı bağla
losetup -f --show -o 269484032 /tmp/rpi_disk.img
# Bu işlem sadece ikinci partition'ı bağlar
# Alternatif olarak --sizelimit ile boyutu da kısıtlayabilirsiniz
losetup -f --show
-o 269484032
--sizelimit $((7862272 * 512))
/tmp/rpi_disk.img
Bu yöntemi özellikle backup imajlarından tek bir partition’ı kurtarırken kullanıyorum. Tüm imajı mount etmek yerine sadece ihtiyacınız olan bölümü açmak çok daha temiz.
Detach İşlemi ve Temizlik
Loop device’ları kullandıktan sonra düzgünce kapatmak önemli. Yarım kalan bağlantılar /dev/loop havuzunu tüketebilir:
# Önce unmount et
umount /mnt/virtual_disk
# Belirli bir loop device'ı ayır
losetup -d /dev/loop0
# Tüm loop device'ları temizle (dikkatli kullanın!)
losetup -D
# Aktif loop device kalmadığını doğrula
losetup -a
# Boş çıktı beklenir
# Eğer loop device meşgul görünüyorsa hangi process kullandığını bul
lsof /dev/loop0
fuser -m /dev/loop0
losetup -D komutunu production sistemlerde çok dikkatli kullanın. Eğer sistemde başka servisler loop device kullanıyorsa (Docker, snap paketler gibi) onları da etkileyebilirsiniz.
Loop Device Sayısını Artırma
Varsayılan olarak çoğu sistemde 8 loop device bulunur. Snap paketleri yoğun kullanan sistemlerde veya çok sayıda sanal disk bağladığınızda bu limite ulaşabilirsiniz:
# Mevcut loop device sayısını kontrol et
ls /dev/loop* | wc -l
# Modül parametresi ile sayıyı artır
modprobe loop max_loop=64
# Kalıcı hale getirmek için
echo "options loop max_loop=64" > /etc/modprobe.d/loop.conf
# Alternatif olarak kernel parametresi olarak da eklenebilir
# /etc/default/grub içine GRUB_CMDLINE_LINUX'a ekle:
# loop.max_loop=64
# Yeni loop device'ları anında oluşturmak için
mknod /dev/loop8 b 7 8
chmod 0660 /dev/loop8
Snap paketi kullanan Ubuntu sistemlerinde her snap paketi bir loop device tüketir. 20-30 snap paketi olan bir sistem 50-60 loop device kullanıyor olabilir. Bu durumu görmezden gelmek ciddi sorunlara yol açar.
Sistem Başlangıcında Otomatik Bağlama
Eğer sanal diskinizin her boot’ta otomatik mount edilmesini istiyorsanız /etc/fstab yeterli olmayabilir. Önce loop device’ın hazır olması gerekir:
# /etc/rc.local veya systemd service ile loop device hazırla
# systemd service dosyası oluştur
cat > /etc/systemd/system/virtual-disk.service << 'EOF'
[Unit]
Description=Virtual Disk Mount
After=local-fs.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/losetup -f --show /data/virtual_disk.img
ExecStartPost=/bin/mount /dev/loop0 /mnt/virtual_disk
ExecStop=/bin/umount /mnt/virtual_disk
ExecStop=/sbin/losetup -d /dev/loop0
[Install]
WantedBy=multi-user.target
EOF
systemctl enable virtual-disk.service
systemctl start virtual-disk.service
Ancak daha temiz bir yöntem /etc/fstab içinde loop parametresini doğrudan kullanmaktır:
# /etc/fstab'a ekle
echo "/data/virtual_disk.img /mnt/virtual_disk ext4 loop,defaults 0 0" >> /etc/fstab
# Test et
mount -a
df -h /mnt/virtual_disk
Sorun Giderme
Pratikte karşılaştığım yaygın sorunlar ve çözümleri:
“No free loop devices” hatası:
# Kullanılan ve boşta olan loop device'ları gör
losetup -l
# Yeni bir tane oluştur
mknod /dev/loop10 b 7 10
# Veya modülü yeniden yükle
modprobe -r loop && modprobe loop max_loop=32
“Device is busy” hatası ile losetup -d başarısız olursa:
# Hangi process bu aygıtı tutuyor?
fuser -vm /dev/loop0
# Zorla umount (son çare)
umount -l /mnt/virtual_disk
losetup -d /dev/loop0
İmaj boyutunu sonradan büyütmek:
# Önce unmount ve detach
umount /mnt/virtual_disk
losetup -d /dev/loop0
# Dosyayı genişlet (1GB ekle)
fallocate -l $(($(stat -c %s /tmp/virtual_disk.img) + 1073741824)) /tmp/virtual_disk.img
# Yeniden bağla
losetup -f --show /tmp/virtual_disk.img
# /dev/loop0
# Dosya sistemini genişlet
e2fsck -f /dev/loop0
resize2fs /dev/loop0
# Yeniden mount et
mount /dev/loop0 /mnt/virtual_disk
df -h /mnt/virtual_disk
Performans İpuçları
Loop device’lar doğrudan disk erişimine göre biraz daha yavaştır çünkü ek bir soyutlama katmanı var. Ancak şu ayarlarla performansı artırabilirsiniz:
- Direct I/O kullanmak:
losetup --direct-io=on /dev/loop0 /tmp/disk.imgkomutu ile ara bellek katmanını atlayabilirsiniz - Async seçeneği: Mount ederken
asyncseçeneği yazma performansını artırır ama güç kesintisinde veri kaybı riski doğurur - Sparse dosyaları production’da kullanmayın: Tahmin edilemeyen disk dolma senaryoları yaratır
- Büyük blok boyutu:
mkfs.ext4 -b 4096varsayılan değerdir, büyük dosyalar için daha büyük blok boyutu düşünülebilir
Sonuç
losetup görünürde basit bir araç, ama altında son derece güçlü bir mekanizma yatıyor. Fiziksel donanıma ihtiyaç duymadan disk imajları oluşturmak, test ortamları kurmak, şifreli container’lar yönetmek… Bunların hepsi çekirdek seviyesinde, kararlı ve güvenilir bir şekilde çalışıyor.
Özellikle şu senaryolarda losetup‘ı aklınızın bir köşesinde tutun: Yeni bir dosya sistemi türünü test edeceğinizde, gömülü sistem geliştirirken, hassas veriler için şifreli alan yaratırken, ya da mevcut bir disk imajının içini kurcalamanız gerektiğinde. Doğru araç, doğru anda kullanıldığında saatlerce sürebilecek bir işi dakikalara indirebilir.
Bir de şunu söyleyeyim: Loop device’larla ilgili öğrendiğim en değerli ders, her kullanımdan sonra temizliği ihmal etmemek. Sisteminizde onlarca yarım kalmış loop bağlantısı birikirsek, hem kaynak tüketirsiniz hem de hata ayıklamayı inanılmaz derecede zorlaştırmış olursunuz. losetup -a ile ara sıra kontrol etmek iyi bir alışkanlık.
