Uncategorized

FUSE ile Basit Bir Sanal Dosya Sistemi Geliştirme

Linux işletim sisteminde, diske fiziksel olarak veri kaydetmeden yalnızca yazılım tabanlı dosya sistemleri oluşturabilirsiniz. Bu tür sistemler çoğunlukla test süreçlerinde, laboratuvar ortamlarında veya belirli uygulama gereksinimleri için tercih edilir. Bunun en kolay yolu FUSE aracını kullanmaktır.

FUSE Nedir?

FUSE, çekirdeğe müdahale etmeye gerek kalmadan kullanıcı düzeyinde dosya sistemleri geliştirmenizi sağlar. Bu yapı, yeni bir çekirdek modülü oluşturmadan kendi dosya sisteminizi yazabilmenize imkân verir. FUSE aracılığıyla bulut tabanlı dizinler oluşturabilir, veritabanı ya da API çıktısını dosya gibi gösterebilir, bellekte çalışan geçici alanlar tanımlayabilirsiniz.

Sahte Dosya Sistemi Nedir?

Sahte dosya sistemi, diskte fiziksel olarak bulunmayan ama sistem tarafından dosya sistemi gibi kullanılan yapılardır. Bu tür ortamlarda görünen dosya ve klasörler gerçekte yalnızca yazılımın oluşturduğu geçici öğelerdir.
/proc ve /sys dizinleri, çekirdeğin iç verilerini dosya biçiminde gösteren bu yapıların tipik örnekleridir. tmpfs belleği kullanarak geçici bir alan oluşturur, sshfs ise uzak bir sunucuyu yerel dizin olarak gösterir.
Bellek kullanımı konusunda daha fazlasını öğrenmek için Swap Oluşturma ve Etkinleştirme Komutları yazımıza göz atabilirsiniz.

FUSE Kurulumu

Kullandığımız sistem Debian ya da Ubuntu tabanlıysa, başlamadan önce paket depolarını güncellemek ve zorunlu bağımlılıkları sisteme eklemek önemlidir.

sudo apt update
sudo apt install build-essential libfuse3-dev pkg-config

Eğer Python ile FUSE tabanlı bir proje geliştirmeyi düşünüyorsak, fusepy paketini de yükleyelim.

pip3 install fusepy

Kurulum işlemleri tamamlandıktan sonra FUSE’un sisteme düzgün şekilde yüklendiğini doğrulayalım.

lsmod | grep fuse

Bu komutun çıktısında fuse satırını görüyorsak, kurulumun başarıyla tamamlandığını anlayabiliriz.

Linux Sahte Dosya Oluşturma

Şimdi basit bir örnek oluşturalım. Bu örnekte /hello adında sanal bir dosya yaratacağız.

#define FUSE_USE_VERSION 35
#include <fuse3/fuse.h>
#include <string.h>
#include <errno.h>

static const char *path_hello = "/hello";
static const char *content = "Merhaba FUSE\n";

static int getattr_cb(const char *path, struct stat *st) {
    memset(st, 0, sizeof(struct stat));
    if (strcmp(path, "/") == 0) {
        st->st_mode = S_IFDIR | 0755;
        st->st_nlink = 2;
        return 0;
    }
    if (strcmp(path, path_hello) == 0) {
        st->st_mode = S_IFREG | 0444;
        st->st_size = strlen(content);
        return 0;
    }
    return -ENOENT;
}

static int readdir_cb(const char *path, void *buf, fuse_fill_dir_t filler,
                      off_t off, struct fuse_file_info *fi) {
    if (strcmp(path, "/") != 0) return -ENOENT;
    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    filler(buf, "hello", NULL, 0);
    return 0;
}

static int open_cb(const char *path, struct fuse_file_info *fi) {
    return strcmp(path, path_hello) ? -ENOENT : 0;
}

static int read_cb(const char *path, char *buf, size_t size, off_t off,
                   struct fuse_file_info *fi) {
    if (strcmp(path, path_hello)) return -ENOENT;
    size_t len = strlen(content);
    if (off >= len) return 0;
    if (off + size > len) size = len - off;
    memcpy(buf, content + off, size);
    return size;
}

static struct fuse_operations ops = {
    .getattr = getattr_cb,
    .readdir = readdir_cb,
    .open = open_cb,
    .read = read_cb,
};

int main(int argc, char *argv[]) {
    return fuse_main(argc, argv, &ops, NULL);
}

Kod dosyasını hello_fuse.c olarak kaydedelim ve ardından derleme işlemini gerçekleştirelim.

gcc hello_fuse.c -o hello_fuse `pkg-config fuse3 --cflags --libs`

Mount işlemi için bir dizin oluşturalım ve sanal dosya sistemimizi oraya bağlayalım.

mkdir /tmp/mount
./hello_fuse /tmp/mount

Sanal dosya sistemimiz aktif hale geldi. Şimdi oluşturduğumuz sanal dosyayı okuyarak sonucu görelim:

cat /tmp/mount/hello

İşimiz bittikten sonra sanal dosya sistemini güvenli şekilde ayırmak için şu komutu çalıştıralım:

fusermount3 -u /tmp/mount

Eğer dosya sistemi testleri sırasında hata veya bozukluk tespit edersen, fsck Komutu Nedir ve Linux’ta Disk Hataları Nasıl Onarılır? rehberindeki adımlar, sanal veya fiziksel disklerde güvenli şekilde onarım yapmana yardımcı olur.

Python ile Sanal Dosya Sistemi

Aynı işlemi bu kez Python kullanarak da gerçekleştirebiliriz. fusepy kütüphanesi sayesinde, birkaç satır kodla kendi sanal dosya sistemimizi oluşturalım.

from fuse import FUSE, Operations
import stat, time

class Hello(Operations):
    def getattr(self, path, fh=None):
        if path == '/':
            return dict(st_mode=(stat.S_IFDIR | 0o755), st_nlink=2)
        if path == '/hello':
            return dict(st_mode=(stat.S_IFREG | 0o444), st_size=15)
        raise FileNotFoundError

    def readdir(self, path, fh):
        return ['.', '..', 'hello']

    def read(self, path, size, offset, fh):
        return b"Merhaba FUSE\n"[offset:offset+size]

FUSE(Hello(), '/tmp/hello_py', foreground=True)

Bu örnekte /tmp/hello_py adında bir sanal dosya sistemi oluşturuyoruz. İçinde hello adlı bir dosya yer alacak ve dosya okunduğunda ekrana “Merhaba FUSE” metni yazdırılacak.

Kodu çalıştıralım.

python3 hello.py

Ardından oluşturulan dosyayı test edelim.

cat /tmp/hello_py/hello

Son olarak, işlemi tamamladıktan sonra dosya sistemini kapatabilmek için Ctrl + C tuşlarına basalım.

Sık Sorulan Sorular

FUSE tam olarak nasıl çalışır?

FUSE, çekirdek modülünün dosya sistemi çağrılarını kullanıcı alanındaki bir programa yönlendirmesiyle çalışır. Yani dosya işlemleri doğrudan kernel tarafından değil, kullanıcı alanındaki bir uygulama tarafından yönetilir.

FUSE ile oluşturulan dosya sistemleri neden kernel seviyesinde değildir?

FUSE’un amacı, geliştiricilerin güvenli bir ortamda dosya sistemi prototipleri yazmasını sağlamaktır. Kullanıcı alanında çalıştığı için çekirdek çökmesine yol açmadan hatalar yakalanabilir.

FUSE’un performansı hangi durumlarda sınırlı olur?

Her dosya işlemi kullanıcı alanı ile çekirdek arasında ek bir geçiş gerektirdiğinden, FUSE tabanlı sistemler yüksek I/O yoğunluklu senaryolarda yavaşlayabilir.

FUSE kullanımı için özel izin gerekir mi?

Eğer sistem yöneticisi kullanıcıya /etc/fuse.conf üzerinden erişim izni verdiyse, root yetkisi gerekmeden FUSE dosya sistemleri oluşturulabilir. Aksi durumda “permission denied” hatası alınabilir.

FUSE dosya sisteminde hata ayıklama (debug) nasıl yapılır?

FUSE uygulamaları çalıştırılırken -d veya --debug parametresi eklenerek hata çıktıları ayrıntılı şekilde görülebilir.

./hello_fuse -d /tmp/mount

Bu sayede dosya işlemleri, erişim talepleri ve hata mesajları gerçek zamanlı olarak takip edilebilir.

FUSE dosya sistemi nasıl kapatılır veya kaldırılır?

Bağlı bir FUSE dosya sistemini devre dışı bırakmak için şu komutu çalıştıralım

fusermount3 -u /tmp/mount

Bu işlem, sanal dosya sistemini güvenli şekilde ayırır ve bellekteki kaynakları serbest bırakır.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir