şükela:  tümü | bugün soru sor
  • linux'te bir programın, belli bir dosya veya dizin üzerinde bir dosya işlemi olduğu zaman sistem tarafından otomatik haberdar edilebilmesini sağlayan bir sistem. bir player'ın monitor ettiği bir dizin içine eklenen dosyaları otomatik olarak library'sine eklemesi veya bir çok program tarafından kullanılan config dosyaları update olduğu zaman programların bu değişiklikten kolayca haberdar edilmesi gibi konularda çok kullanışlıdır. kernel versiyon 2.6.13'den beri mevcuttur.
  • linux'te watch list olusturup event'leri izlemenizi saglayan notification api.

    mesela bir config dosyaniz ya da config dosyalarindan olusan bir directoryniz var diyelim. buna dair access, modify, delete, close, move, create islemlerinden haberdar olmak istiyorsunuz boylelikle runtime esnasinda hizlica bu dosyaya dair programiniz hizlica insiyatif alsin. bu ve benzeri ihtiyaclara file system event deniyor, inotify da bunlardan haberdar olmanizi saglayan bir api oluyor.

    dedigim gibi, hem tek bir dosyayi, hem de bir dizini izleyebiliyorsunuz fakat bir dizini izlemekten kasit, sadece o dizini izlemek, yani recursive olarak sub-directory'lerde olup bitenlerden haberiniz olmuyor.

    nasil kullanilir ?
    ****************
    1- oncelikle bir file descriptor ile inotify instance'i olusturursunuz. (bkz: file descriptor)
    (bkz: inotify_init)

    2- bir watch item eklersiniz. nedir bu? mesela yukaridaki event'lerden bir ya da bir kismini izlemek istiyoruzdur, su dosya her open ya da access oldugunda haberim olsun gibi.
    (bkz: inotify_add_watch)

    3- event'leri okur ve buna gore gereken islemleri yapariz. misal bir ui yapmisizdir, source folder'ina yeni bir dosya eklendiginde otomatik olarak onu gostermek istiyoruzdur, source folder'inda her yeni dosya yaratildiginda event uzerinden haberimiz olur ve ui icinde ismi olan bir kutucuk ekleriz.

    inotify_init function signature'u;

    int inotify_init();

    return edilen int degeri file descriptor'dir. (bkz: everything is a file) event'leri bu elde ettigimiz file descriptor ile okuruz. (bkz: read/@bozdoganli)

    event eklemek icin kullanacagimiz inotify_add_watch function signature'u;

    int inotify_add_watch(int fd, const char *path, unsigned int mask);

    fd: file descriptor (inotify instance'ina ait olan)
    path: izlemek istediginiz dosyanin path'i
    mask: evetn'leri tanimlayan bitmask

    return edilen int degeri watch descriptor'dir.

    bitmask'ler icin (buyuk harflerle);

    in_access ......... file access
    in_attrib ........... file attribute degisimi
    in_creat ............ watch directory'de dosya yaratilmasi
    in_delete .......... watch directory'de dosya silinmesi
    in_delete_self .. izlenen dosyanin silinmesi
    in_modify ......... file modify
    in_move_self .... file move
  • bu api'de soyle bir sorun var, aslinda sorun da denmez. bir whiel(true) ya da while(1) dongusu icinde event'leri okurken, event'ler icindeki traversal'i sabit artimli bir for dongusuyle yapamazsiniz cunku her event farkli yer kaplamaktadir ve event'in ne kadar yer kapladigi struct inotify_event yapisi icinde len field'inde belirtilir.

    bu durumda her event'i okudugunuzda, yeni event'i gezmek icin (bkz: traverse) yapinin buyuklugu + event->len demeniz gerekecektir;

    while(1)
    {
    int n = read(notify_file_descriptor, event_buffer, buffer_size);

    char *index;
    for( index = event_buffer; index < event_buffer = readbytes);

    temp_event = (struct notify_event *) index;
    index += sizeof(struct inotify_event) + event_len;

    // .. ne isiniz varsa artik
  • ks. inode notify

    linux işletim sisteminde dizin tabanlı dnotify mekanizmasının yerine geliştirilmiş, inode tabanlı dosya sistemi izleme* mekanizmasıdır.

    inotify_event yapısı içerisindeki name elemanı, bit mask ile tanımlanmış ilgili event'in gerçekleştiği dosyanın ismidir ve null ile sonlandırılmıştır*. yapının len elemanı ise bu dosya isminin uzunluğunu tutmaktadır. dolayısıyla bir grup dosya ya da dizin için inotify mekanizması oluşturulduğunda, oluşan her event için event buffer okunurken gösterici ya da indeksin sabit aralıkta ilerletilmiyor olması eşyanın tabiatı gereği normaldir. zira izlenen her dosya yahut dizin aynı isimde olmayacağı gibi, aynı uzunlukta da olmak zorunda değildir. event buffer içerisinde dolaşırken, sıradaki event'e ilişkin yapıya [sizeof(struct inotify_event) + len] byte sonra erişirsiniz. dolayısıyla linux kernel 2.6.13'den bu yana* var olan bu güzide mekanizmada herhangi bir sorun yoktur. hatta oop'de uygulanan observer pattern'in yapısal* ve prosedürel sistem karşılığı olarak düşünülebilir.

    lakin bu mekanizma, yalnızca dosya sistemi üzerinde işlem yapabilmekte ve çoğu pseudo-filesystem*** üzerinde sağlıklı işlem yapamamaktadır. pipe, socket yahut device file gibi özel dosyalar* üzerinde izleme* işlemi yapabilmek için ise epoll mekanizması yahut select/poll mekanizması kullanılır. epoll ile i/o monitoring hadisesinin güzelliği ise edge triggered veya level triggered olabilmesinde saklıdır.

    not: inotify_event yapısı içerisindeki name elemanı, null terminated string olmasının yanı sıra, mevcut hizalamaya* uygun olacak sayıda null karakteri de tutmaktadır. dolayısıyla len elemanının toplam uzunluğu: "dosya ismi + sonlandırıcı karakter* + hizalama için gerekli null karakter sayısı" kadardır.