18 Ekim 2019 Cuma

inotify dizin izleme

Giriş
Şu satırı dahil ederiz.
#include <sys/inotify.h>
inotify Linux'ta dizin izleme için kullanılır.

Yapısı
İşletim sistemi bizim için bir kuyruk yaratır ve dizin olaylarını bu kuyruğa yazar. Açıklaması şöyle
Aside from ordinary errors (such as going over /proc/sys/fs/inotify/max_user_watches) inotify has several fault modes (queue space exhaustion, watch ID reuse), but those aren't "failures" in strict sense of word.

Queue exhaustion happens when someone performs filesystem changes faster than you can react. It is easy to reproduce: pause your program while it has an inotify descriptor open (so the event queue isn't drained) and rapidly generate lots of notifications by modifying the observed files/directories. If you don't want to modify your program, you can put it's process into CPU-sleep by temporarily assigning it to cgroup with extremely small percentage of CPU time. Once you have /proc/sys/fs/inotify/max_queued_events of unhandled events, your program will receive IN_Q_OVERFLOW (and potentially miss some events, that didn't fit into queue).
inotify_init metodu
Dizini izlemek için bir fd oluşturmak gerekir. Şöyle yaparız.
int fd = inotify_init();

if (fd < 0) {
  perror("inotify_init");
}
inotify_add_watch metodu
Açıklaması şöyle.
A successful call to inotify_add_watch() returns a unique watch descriptor for this inotify instance, for the filesystem object (inode) that corresponds to pathname. If the filesystem object was not previously being watched by this inotify instance, then the watch descriptor is newly allocated. If the filesystem object was already being watched (perhaps via a different link to the same object), then the descriptor for the existing watch is returned.
IN_CLOSE_WRITE seçeneği
Dosyayı izlemek için IN_CLOSE_WRITE kullandım.

IN_DELETE_SELF seçeneği
Açıklaması şöyle.
IN_DELETE_SELF
        Watched file/directory was itself deleted.  (This event
        also occurs if an object is moved to another filesystem,
        since mv(1) in effect copies the file to the other
        filesystem and then deletes it from the original filesys
        tem.)  In addition, an IN_IGNORED event will subsequently
        be generated for the watch descriptor.
Örnek
İzleyeceğimiz dizini belirtiriz.
int wd = inotify_add_watch(fd, ".",
        IN_MODIFY | IN_CREATE | IN_DELETE);
read metodu
Dizini izlemeye başlarız.
Örnek
Şöyle yaparız.
m_wd1 = inotify_add_watch( m_fd, "/tmp", IN_CREATE );
for( ;; )
{
  len = read( m_fd, buf, sizeof( buf ) );
  if( len == -1 && errno != EAGAIN )
  {
    syslog( LOG_ERR, "Failure to read the inotify event" );
    break;
  }
  for( ptr = buf; ptr < buf + len; ptr += sizeof( struct inotify_event ) + event->len )
  {
    event = (const struct inotify_event *) ptr;
    if( event->mask & IN_CREATE )
    {
      std::string name( event->name );
      ...
    }
  }
}

Örnek
Şöyle yaparız.
#define EVENT_SIZE  (sizeof(struct inotify_event))
#define BUF_LEN     (1024 * (EVENT_SIZE + 16))

char buffer[BUF_LEN];
int length = read(fd, buffer, BUF_LEN);

if (length < 0) {
  perror("read");
}
Bu çağrıdan dönünce hangi dosyaların değiştiği şöyle bulunur.
while (i < length) {
  struct inotify_event *event = (struct inotify_event *) &buffer[i];
  if (event->len) {
    if (event->mask & IN_CREATE) {
      printf("The file %s was created.\n", event->name);
    } else if (event->mask & IN_DELETE) {
      printf("The file %s was deleted.\n", event->name);
    } else if (event->mask & IN_MODIFY) {
      printf("The file %s was modified.\n", event->name);
    }
  }
  i += EVENT_SIZE + event->len;
}
Bazı izinlerin açıklaması şöyle
A is read from (IN_ACCESS)
B is written to (IN_MODIFY)
A was open for reading (as identified by IN_CLOSE_NOWRITE)
B was open for writing (as identified by IN_CLOSE_WRITE)
Örnek
Dosya kopyalarken şu olaylar gelir.
cp file newfile

IN_CREATE newfile
IN_MODIFY newfile
IN_CLOSE newfile
Örnek
Dosyaya ekleme yaparken şu olaylar gelir.
echo "foo" >> newfile

IN_CREATE newfile
IN_MODIFY newfile
IN_CLOSE newfile
inotify_rm_watch metodu
İzleme işlevini kapatır.
inotify_rm_watch(fd, wd);
close(fd);
inotify-tools Paketi
inotifywait komutu yazısına taşıdım.


Hiç yorum yok:

Yorum Gönder