Вы находитесь на странице: 1из 4

Monitorizarea activitatii sistemului de fisiere.

Daca trebuie sa monitorizezi mai multe FTP dropbox-uri pentru datele de intrare, s-ar putea scana
fiecare director tinta cu o comanda find pentru a enumera ce este nou. Cu toate acestea, desi
operatiunea pare inofensiva pentru sistem, fiecare invocare ruleaza un nou shell impreuna cu comanda
find in sine, care necesita multe apeluri de sistem pentru a deschide directorul, pentru a-l scana s.a.m.d.
Solutia optima pentru a face acest lucru este folosirea metodei inotify. Inotify este o
caracteristica a kernel-ului Linux care monitorizeaza sistemul de fisiere si alerteaza o aplicatie in legatura
cu evenimentele relative cum ar fi: stergere, citire, scriere chiar si o operatie de unmount a unui volum
de date. Puteti de asemenea urmari originea si destinatia modificarilor.
Folosirea inotify presupune: crearea unui descriptor de fisiere, atasarea unuia sau a mai multor
watch-uri (un watch este o cale si un set de evenimente) si folosirea metodei read() pentru a primi
informatiile de la decriptoru de fisiere. Deoarece Inotify functioneaza printr-un descriptor de fisiere
traditional, puteti folosi apelul de sistem select() pentru a monitoriza pasiv watch-urile si o alta
multitudine de surse de intrare in acelasi timp. Ambele abordari ( file descriptor si multiplexarea cu
ajutorul select ) evita busy polling ( poll = asteptarea unor event-uri pentru un file descriptor ).
Inotify prevede trei apeluri de sistem pentru a construi toate tipurile de monitoare de sisteme de fisiere:

Inotify_init() creeaza o instanta a subsistemului Inotify in kernel si returneaza un file descriptor


de fisier sau -1 in caz de esec. Ca si alte apeluri sistem, daca esueaza verificam errno pentru
diagnostificare.
Inotify_add_watch() adauga un watch. Fiecare watch trebuie sa furnizeze o cale si o lista de
evenimente, unde fiecare eveniment este specificat printr-o constanta, cum ar fi: IN_MODIFY.
Pentru a monitoriza mai mult de un eveniment va trebui sa folosim operatorul pipe in C pentru
fiecare eveniment. Apelul functiei returneaza un identificator unic pentru watch-ul inregistrat,
altfel returneaza -1.
Inotify_rm_watch() pentru a sterge un watch.

Sunt necesare, de asemenea apelurile de sistem: read() si close(). Apelul read() asteapta alertele
generate de inotify_init(). Apelul close() sterge si elibereaza toate watch-urile active, chiar si memoria
asociata cu instant inotify.

Exemplu de program simplu pe care se va baza aplicatia noastra:


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#define EVENT_SIZE ( sizeof (struct inotify_event) )

#define BUF_LEN

( 1024 * ( EVENT_SIZE + 16 ) )

int main( int argc, char **argv )


{
int length, i = 0;
int fd;
int wd;
char buffer[BUF_LEN];
fd = inotify_init();
if ( fd < 0 ) {
perror( "inotify_init" );
}
wd = inotify_add_watch( fd, "/home/strike",
IN_MODIFY | IN_CREATE | IN_DELETE );
length = read( fd, buffer, BUF_LEN );
if ( length < 0 ) {
perror( "read" );
}
while ( i < length ) {
struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
if ( event->len ) {
if ( event->mask & IN_CREATE ) {
if ( event->mask & IN_ISDIR ) {
printf( "The directory %s was created.\n", event->name );
}
else {
printf( "The file %s was created.\n", event->name );
}
}
else if ( event->mask & IN_DELETE ) {
if ( event->mask & IN_ISDIR ) {
printf( "The directory %s was deleted.\n", event->name );
}
else {
printf( "The file %s was deleted.\n", event->name );
}
}
else if ( event->mask & IN_MODIFY ) {
if ( event->mask & IN_ISDIR ) {
printf( "The directory %s was modified.\n", event->name );
}
else {
printf( "The file %s was modified.\n", event->name );
}
}
}
i += EVENT_SIZE + event->len;
}
( void ) inotify_rm_watch( fd, wd );
( void ) close( fd );
exit( 0 );
}

Aplicatia creeaza o instant de inotify si adauga un watch pentru a monitoriza modificarile din
/home/clawdiu. Metoda read() blocheaza pana cand una sau mai multe alerte sosesc. Specificatiile alertei
(fiecare fisier / eveniment) sunt transmise ca un flux de octeti, prin urmare, loop-ul din aplicatie
transforma fluxul de octeti intr-o serie de structuri de evenimente

struct inotify_event
{
int wd;
uint32_t mask;
uint32_t cookie;
uint32_t len;
char name __flexarr;
}

/* The watch descriptor */


/* Watch mask */
/* A cookie to tie two events together */
/* The length of the filename found in the name field */
/* The name of the file, padding to the end with NULs */

Acest tool este foarte folositor deoarece totul in Linux este fisier, deci fara niciun dubiu se pot
face foarte multe lucruri cu inotify watches.

Listarea device-urilor conectate la porturi USB sau serial port-uri


Lsusb este un utilitar folosit pentru afisarea informatiilor despre porturile USB din sistem
si a device-urilor conectate la acestea.
Prin apelarea acestui utilitar putem afla detalii despre numarul portului la care device-ul
este conectat, cate device-uri sunt atasate la portul respectiv, precum si numele si id-ul deviceului, acesta din urma fiind format din id-ul producatorului si id-ul device-ului.
O implementare simpla a acestui utilitar, poate fi:
#include <stdio.h>
#include <usb.h>
main(){
struct usb_bus *bus;
struct usb_device *dev;
usb_init();
usb_find_busses();
usb_find_devices();
for (bus = usb_busses; bus; bus = bus->next)
for (dev = bus->devices; dev; dev = dev->next){

printf("Trying device %s/%s\n", bus->dirname, dev->filename);


printf("\tID_VENDOR = 0x%04x\n", dev->descriptor.idVendor);
printf("\tID_PRODUCT = 0x%04x\n", dev->descriptor.idProduct);
}
}

Вам также может понравиться